Dmy*_*tov 6 java rest spring http
我正在为我的Web应用程序使用'admin-on-rest'用户界面,它有下一个限制:
注意:jsonServer REST客户端要求API在对GET_LIST调用的响应中包含X-Total-Count标头.该值必须是集合中的资源总数.这允许admin-on-rest知道总共有多少页资源,并构建分页控件.
我通过手动将X-Total-Count标头添加到我的列表返回REST端点来解决了这个问题,如下所示:
response.addHeader("X-Total-Count", String.valueOf(outputList.size()));
但我想知道:如果有一些优雅的方式在Spring自动完成它?我的意思是当某个端点返回JSON列表时,自动添加此标头的值是否正确?
就在这里!(如果您使用的是Spring 4.1或更高版本)。
它称为ResponseBodyAdvice,它使您能够拦截呼叫(就在编写响应并提供对原始http响应的访问之前)。
基本上,您需要执行以下控制器建议:
@ControllerAdvice
public class ResourceSizeAdvice implements ResponseBodyAdvice<Collection<?>> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
//Checks if this advice is applicable.
//In this case it applies to any endpoint which returns a collection.
return Collection.class.isAssignableFrom(returnType.getParameterType());
}
@Override
public Collection<?> beforeBodyWrite(Collection<?> body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
response.getHeaders().add("X-Total-Count", String.valueOf(body.size()));
return body;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不仅仅想要响应中的元素总数,而是想要相应 JPA 方法中的实体总数,PagingAndSortingRepository您可以执行类似的操作,这对于分页应用程序很有用:)
受到博赫丹的回答的启发(/sf/answers/3106329341/)
@ControllerAdvice
public class ResourceSizeAdvice implements ResponseBodyAdvice<Page<?>> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
//Checks if this advice is applicable.
//In this case it applies to any endpoint which returns a page.
return Page.class.isAssignableFrom(returnType.getParameterType());
}
@Override
public Page<?> beforeBodyWrite(Page<?> page, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
serverHttpResponse.getHeaders().add("X-Total-Count",String.valueOf(page.getTotalElements()));
return page;
}
}
Run Code Online (Sandbox Code Playgroud)
确保调用默认方法的可分页版本,这样它返回 aPage而不是 a List:
repository.findAll(new PageRequest(0,100));
Run Code Online (Sandbox Code Playgroud)
如果您不使用存储库,那么您必须执行两个查询:
Select * from ...和
Select count(*) from ...
返回 a Wrapper,其中包含结果列表的内容以及来自 count 的总数。然后你可以更改@ControllerAdvice类以期望你的Wrapper并从中获取总数并将其放入标题中