Spring自动添加'X-Total-Count'标题

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列表时,自动添加此标头的值是否正确?

Boh*_*nko 6

就在这里!(如果您使用的是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)


Mic*_*dis 5

如果您不仅仅想要响应中的元素总数,而是想要相应 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并从中获取总数并将其放入标题中