2016-08-10 8 views
2

У меня есть метод в моем контроллере, который возвращает список объектов. Этот метод поддерживает результат подкачки и добавляет HttpHeaders.LINK в HttpHeader для поддержки раскрываемости разбиения на страницы. Я вынужден добавить эти строки для поддержки. Я думаю, что, возможно, ControllerAdvice или ResponseAdvice поддерживают это. Как я могу проверить возврат метода? и если тип возврата - QueryResult, то добавьте HttpHeader к этому?Spring MVC ResponseBodyAdvice для добавления заголовка в задании типа возврата

@RequestMapping(value = "/list", method = RequestMethod.GET) 
    public ResponseEntity<QueryResult<Personel>> search(
      SearchOption searchOption) { 
     QueryResult<Personel> list=ipersonelService.search(); 
     HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(list, "/api/personel"); 
     return new ResponseEntity<>(list, headers, HttpStatus.OK); 
    } 

этот класс генерирует заголовки от класса пейджинга

public static HttpHeaders generatePaginationHttpHeaders(QueryResult page, String baseUrl) 
    throws URISyntaxException { 

    HttpHeaders headers = new HttpHeaders(); 
    headers.add("X-Total-Count", "" + page.getTotalElements()); 
    String link = ""; 
    if ((page.getPageNumber() + 1) < page.getTotalPages()) { 
     link = "<" + generateUri(baseUrl, page.getPageNumber() + 1, page.getPageSize()) + ">; rel=\"next\","; 
    } 
    // prev link 
    if ((page.getPageNumber()) > 0) { 
     link += "<" + generateUri(baseUrl, page.getPageNumber() - 1, page.getPageSize()) + ">; rel=\"prev\","; 
    } 
    // last and first link 
    int lastPage = 0; 
    if (page.getTotalPages() > 0) { 
     lastPage = page.getTotalPages() - 1; 
    } 
    link += "<" + generateUri(baseUrl, lastPage, page.getPageSize()) + ">; rel=\"last\","; 
    link += "<" + generateUri(baseUrl, 0, page.getPageSize()) + ">; rel=\"first\""; 
    headers.add(HttpHeaders.LINK, link); 
    return headers; 
} 


private static String generateUri(String baseUrl, int page, int size) throws URISyntaxException { 
     return UriComponentsBuilder.fromUriString(baseUrl).queryParam("page", page).queryParam("size", size).toUriString(); 
    } 



public class QueryResult<T> { 

    private int  pageNumber; 
    private int  totalElements; 
    private int  totalPages; 
    private int  pageSize; 

    @JsonProperty("rows") 
    private List<T> items; 

    public QueryResult() { 

    } 

    public int getPageNumber() { 
     return pageNumber; 
    } 

    public void setPageNumber(int pageNumber) { 
     this.pageNumber = pageNumber; 
    } 

    public int getTotalElements() { 
     return totalElements; 
    } 

    public void setTotalElements(int totalElements) { 
     this.totalElements = totalElements; 
    } 

    public int getPageSize() { 
     return pageSize; 
    } 

    public void setPageSize(int pageSize) { 
     this.pageSize = pageSize; 
    } 

    public List<T> getItems() { 
     return items; 
    } 

    public void setItems(List<T> items) { 
     this.items = items; 
    } 

    public int getTotalPages() { 
     if (this.getPageSize() > 0) 
      return this.getTotalElements()/this.getPageSize(); 

     return 0; 
    } 

    public void setTotalPages(int totalPages) { 
     this.totalPages = totalPages; 
    } 

} 

я хочу написать метод, как это и автоматических заголовков Добавить ссылку

@RequestMapping(value = "/list", method = RequestMethod.GET) 
     public QueryResult<Personel> search(
       SearchOption searchOption) { 
      return ripersonelService.search(); 
     } 

после поиска я нашел это решение

@ControllerAdvice 
public class BaseController implements ResponseBodyAdvice<Object> { 


    private final Logger logger = Logger.getLogger(BaseController.class); 

    @Override 
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { 
     return true; 
    } 

    @Override 
    public Object beforeBodyWrite(
      Object body, 
      MethodParameter returnType, 
      MediaType selectedContentType, 
      Class<? extends HttpMessageConverter<?>> selectedConverterType, 
      ServerHttpRequest request, 
      ServerHttpResponse response) { 
     if(body instanceof QueryResult){ 
      QueryResult result =(QueryResult) body; 
      HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(result, request.getURI().getPath()); 
      response.getHeaders().add(HttpHeaders.LINK, headers.getFirst(HttpHeaders.LINK)); 
      response.getHeaders().add("X-Total-Count", headers.getFirst("X-Total-Count")); 
     } 

     return body; 
    } 
} 

ответ

4

Y ou может использовать реализацию ResponseBodyAdvice (обычно также аннотируется @ControllerAdvice). Способ вашей реализации beforeBodyWrite будет вызываться с телом ответа и ServerHttpResponse. Последний дает вам доступ к заголовкам ответов и позволяет вам обновлять их по мере необходимости.