首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Spring的ResponseBodyAdvice:执行顺序?

Spring的ResponseBodyAdvice:执行顺序?
EN

Stack Overflow用户
提问于 2015-02-14 10:54:38
回答 1查看 3.4K关注 0票数 10

我想实现一个自定义的ResponseBodyAdvice,它只是查找Page<?>,然后将总元素的数量添加到响应头。

代码语言:javascript
复制
@ControllerAdvice
public class PageResponseAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return Page.class.isAssignableFrom(returnType.getParameterType());
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        ((Page<?>) body).getTotalElements();
        ...
    }

}

问题是:

  • 为什么类型为MappingJacksonValue
  • Is的body (在beforeBodyWrite方法中)有更好的实现方法?/我是不是用错了interceptor?

我不想关心包装器类,尽管我只想在beforeBodyWrite方法中使用未修改的普通Page对象。

编辑:

我现在只需要extend AbstractMappingJacksonResponseBodyAdvice。这工作得很好,但感觉不太对。也许还是有人有更好的主意。

下面是Page -> Content-Range Header的代码

代码语言:javascript
复制
@ControllerAdvice
public class PageResponseAdvice extends AbstractMappingJacksonResponseBodyAdvice {
    @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return super.supports(returnType, converterType) && Page.class.isAssignableFrom(returnType.getParameterType());
    }

    @Override protected void beforeBodyWriteInternal(MappingJacksonValue bodyContainer, MediaType contentType, MethodParameter returnType, ServerHttpRequest request, ServerHttpResponse response) {
        Page<?> page = ((Page<?>) bodyContainer.getValue());
        Long from = null;
        Long to = null;
        if(page.getTotalElements() > 0 && page.getNumberOfElements() > 0) {
            from = Integer.valueOf(page.getNumber()).longValue()*page.getSize();
            to = from + page.getNumberOfElements() - 1;
        }
        response.getHeaders().add(
                HttpHeaders.CONTENT_RANGE,
                ContentRangeEncoder.encode(
                        "items",
                        from,
                        to,
                        page.getTotalElements()
                )
        );
        response.getHeaders().add(
                HttpHeaders.ACCEPT_RANGES,
                "items"
        );
    }
}

(如果有人感兴趣的话。这是ContentRangeEncoder):

代码语言:javascript
复制
public class ContentRangeEncoder {
    private static final Pattern TYPE_PATTERN = Pattern.compile("[a-zA-Z0-9]+");
    private static final Predicate<String> TYPE_PATTERN_PREDICATE = TYPE_PATTERN.asPredicate();

    public static <T extends Number & Comparable<T>> String encode(String unit, T from, T to, T length) {
        StringBuilder sb = new StringBuilder();
        if(unit != null) {
            Assert.isTrue(TYPE_PATTERN_PREDICATE.test(unit));
            sb.append(unit).append(" ");
        }

        if(from == null && to == null) {
            sb.append("*");
        } else {
            Assert.notNull(from);
            Assert.notNull(to);
            Assert.isTrue(from.compareTo(to) <= 0);
            sb.append(from).append("-").append(to);
        }
        sb.append("/");
        if(length == null) {
            sb.append("*");
        } else {
            Assert.isTrue(to == null || length.compareTo(to) > 0);
            sb.append(length);
        }
        return sb.toString();
    }
}
EN

回答 1

Stack Overflow用户

发布于 2018-06-09 04:27:05

至于主体为什么是MappingJacksonValue类型,这取决于您的配置和特定处理程序方法的返回值。

顺便说一句,WebMvcConfigurationSupportJsonViewResponseBodyAdvice添加到RequestMappingHandlerAdapter中,如果在调用之前调用此ResponseBodyAdvice bean,这就解释了主体为什么是MappingJacksonValue。主体从一个ResponseBodyAdvice bean传递到下一个bean,每个bean以它认为合适的任何“形式”返回主体。

下面是JsonViewResponseBodyAdvice的超类'AbstractMappingJacksonResponseBodyAdvice‘的摘录,看看正文发生了什么:

代码语言:javascript
复制
public final Object beforeBodyWrite(@Nullable Object body,
    MethodParameter returnType, ..., ..., ..., ...) {

    //...

    MappingJacksonValue container = getOrCreateContainer(body);

    //...

    return container;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28511914

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档