Spring MVC ResponseBodyAdvice 用于在指定 return 类型中添加 header
Spring MVC ResponseBodyAdvice for add header in specify return type
我的控制器中有一个方法 return object 列表。
该方法支持分页结果,在HttpHeader中添加HttpHeaders.LINK以支持Pagination Discoverability。
我被迫添加此行以支持 .
我认为也许 ControllerAdvice 或 ResponseAdvice 支持在那做这件事。
我如何检查 return 方法?如果 return 类型是 QueryResult 则向其添加 HttpHeader?
@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);
}
这个class通过分页生成Headersclass
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;
}
}
我想写这样的方法并自动添加link headers
@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;
}
}
您可以使用 ResponseBodyAdvice
(typically also annotated with @ControllerAdvice
). Your implementation's beforeBodyWrite
method will be called with the response body and the ServerHttpResponse
的实现。后者使您可以访问响应 headers 并允许您根据需要更新它们。
我的控制器中有一个方法 return object 列表。 该方法支持分页结果,在HttpHeader中添加HttpHeaders.LINK以支持Pagination Discoverability。 我被迫添加此行以支持 . 我认为也许 ControllerAdvice 或 ResponseAdvice 支持在那做这件事。 我如何检查 return 方法?如果 return 类型是 QueryResult 则向其添加 HttpHeader?
@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);
}
这个class通过分页生成Headersclass
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;
}
}
我想写这样的方法并自动添加link headers
@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;
}
}
您可以使用 ResponseBodyAdvice
(typically also annotated with @ControllerAdvice
). Your implementation's beforeBodyWrite
method will be called with the response body and the ServerHttpResponse
的实现。后者使您可以访问响应 headers 并允许您根据需要更新它们。