Spring mvc 精确 控制返回字段 SimpleFilterProvider,@JasonView,以及VO 视图模型的选择

使用 SimpleFilterProvider,PropertyFilter 好处在于 解耦,灵活.但是弊端也非常明显 

先来看看@JsonView 的处理方式

在 WebMvcConfigurationSupport 中有一个配置方法,如果程序中有 com.fasterxml.jackson.databind.ObjectMapper && com.fasterxml.jackson.core.JsonGenerator 包的引用就会把实现了  RequestBodyAdvice 的 JsonViewRequestBodyAdvice 以及

实现了 ResponseBodyAdvice 的 JsonViewResponseBodyAdvice 添加进来
    @Bean
    public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
        RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
        adapter.setContentNegotiationManager(mvcContentNegotiationManager());
        adapter.setMessageConverters(getMessageConverters());
        adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer());
        adapter.setCustomArgumentResolvers(getArgumentResolvers());
        adapter.setCustomReturnValueHandlers(getReturnValueHandlers());

        if (jackson2Present) {
            adapter.setRequestBodyAdvice(Collections.singletonList(new JsonViewRequestBodyAdvice()));
            adapter.setResponseBodyAdvice(Collections.singletonList(new JsonViewResponseBodyAdvice()));
        }

        AsyncSupportConfigurer configurer = new AsyncSupportConfigurer();
        configureAsyncSupport(configurer);
        if (configurer.getTaskExecutor() != null) {
            adapter.setTaskExecutor(configurer.getTaskExecutor());
        }
        if (configurer.getTimeout() != null) {
            adapter.setAsyncRequestTimeout(configurer.getTimeout());
        }
        adapter.setCallableInterceptors(configurer.getCallableInterceptors());
        adapter.setDeferredResultInterceptors(configurer.getDeferredResultInterceptors());

        return adapter;
    }

最终处理的是,  RequestResponseBodyAdviceChain 这个责任链

使用 SimpleFilterProvider,PropertyFilter 自定义控制json返回值,会直接拿到request,强制修改请求头为Json,并输出,结束了此次的请求.就把责任链给中断了,所以在@RestController 中,会失效

使用@jsonView 比较符合Spring的设计模式,但是耦合性非常强,并且你会发现,如果你要返回Jpa 的page @JsonView 就没用了

还要对Page做以下包装

/**
 * @author laizhenwei
 * @date 2018/06/09
 */
@JsonView(View.class)
public class PageVo<T> extends PageImpl<T> implements Page<T> {

    private static final long serialVersionUID = -3530103094806749298L;

    public PageVo(final List<T> content, final Pageable pageable, final long total) {
        super(content, pageable, total);
    }

    public PageVo(final List<T> content) {
        super(content);
    }

    public PageVo(final Page<T> page, final Pageable pageable) {
        super(page.getContent(), pageable, page.getTotalElements());
    }

所以还是乖乖写VO 转换吧,反正都要浪费元空间

猜你喜欢

转载自www.cnblogs.com/sweetchildomine/p/9158861.html