SpringBoot>23 - 2.0版本WebMvc配置

前言:

Springboot的starter封装了很多东西,包含了MessageConverter、ViewResolver等web的配置,若需要自定义。在之前1.5版本中自定义javaBean继承WebMvcConfigurerAdapter类,但是在2.0版本中此类标记过时,需要实现WebMvcConfigurer接口实现自定义配置。

一、1.5.X版本回顾:

配置类继承WebMvcConfigurerAdapter,重写方法。

/**
 * WebMvcConfigurerAdapter(抽象类):
 * 实现了WebMvcConfigurer接口
 * 自定义web配置,只需重写方法即可
 */
@Configuration
public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter {
    ...
}

// 实现 WebMvcConfigurer 接口
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
    // 方法没有任何逻辑
    public WebMvcConfigurerAdapter() {
    }
    ...
}

// WebMvcConfigurer 接口
public interface WebMvcConfigurer {
    void configurePathMatch(PathMatchConfigurer var1);
    ...
}

设计技巧: 自定义web配置和WebMvcConfigurer接口之间加上抽象类,继承抽象类之后就不必要去实现那些我们不需要的方法,自定义配置只需要针对某一个方法重写即可。

2.0.X版本WebMVC自定义配置:

SpringBoot2.0及Spring5.0中WebMvcConfigurerAdapter已被废弃 。推荐直接实现WebMvcConfigurer接口或继承WebMvcConfigurationSupport类。

方式1、继承WebMvcConfigurationSupport类:

public class CustomWebMvcConfig extends WebMvcConfigurationSupport{
    ...
}

此种方式会导致web自动配置失效。
原因:查看源码
在这里插入图片描述

// 没有WebMvcConfigurationSupport类型的bean时改自动配置类才会生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})

解决:重写相应的方法。例如:

@Configuration
public class WebAppConfig extends WebMvcConfigurationSupport {

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(LoginInterceptor()).addPathPatterns("/sys/**")
                .excludePathPatterns("/sys/login.html", "/sys/login/**");
        super.addInterceptors(registry);
    }

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        super.addResourceHandlers(registry);
    }
}

不推荐此种方式。

方式2、实现 WebMvcConfigurer 接口:
推荐此种配置方式。

1、如下:以拦截器和消息转换器的配置为例

/**
 * @Auther: xf
 * @Date: 2019/1/8 19:25
 * @Description: springboot 2.0  自定义webmvc的配置
 * 方式:
 * 1、继承 WebMvcConfigurationSupport 会导致 webmvc 自动配置失效
 * 2、实现 WebMvcConfigurer 接口  推荐
 */
@Configuration
//public class CustomWebMvcConfig extends WebMvcConfigurationSupport{
public class CustomWebMvcConfig implements WebMvcConfigurer {

    /**
     * 拦截器配置
     * addPathPatterns 用于添加拦截规则
     * excludePathPatterns 用户排除拦截
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
         // 多个拦截器会组成一个拦截器链
         registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**").excludePathPatterns("/login");
         registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**");
    }

    /**
     * 消息转换器 -- alibaba 开源的 fastjson
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

        /**
         * springboot 2.0 配置FastJson失效,添加如下配置
         *
         * 自定义的 FastJsonHttpMessageConverter 在 MappingJackson2HttpMessageConverter 后面,导致失效
         * 解决:加载FastJsonHttpMessageConverter 前删除 MappingJackson2HttpMessageConverter
         *
         * 参考链接:https://segmentfault.com/a/1190000015975405
         */
        Iterator<HttpMessageConverter<?>> iterator = converters.iterator();
        while(iterator.hasNext()){
            HttpMessageConverter<?> converter = iterator.next();
            if(converter instanceof MappingJackson2HttpMessageConverter){
                iterator.remove();
            }
        }

        // 1、需要定义一个convert转换消息的对象;
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        // 2、添加fastJson的配置信息,比如:是否要格式化返回的json数据;
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.PrettyFormat,
                // list null -> []
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteDateUseDateFormat,
                // String null -> ""
                SerializerFeature.WriteNullStringAsEmpty,
                // Number null -> 0
                SerializerFeature.WriteNullNumberAsZero,
                // Boolean null -> false
                SerializerFeature.WriteNullBooleanAsFalse,
                //禁止循环引用
                SerializerFeature.DisableCircularReferenceDetect
        );

        // 3、处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        // 4、在convert中添加配置信息.
        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        // 5、将convert添加到converters当中.
        converters.add(fastJsonHttpMessageConverter);

        /**
         * WriteNullListAsEmpty  :List字段如果为null,输出为[],而非null
         * WriteNullStringAsEmpty : 字符类型字段如果为null,输出为"",而非null
         * DisableCircularReferenceDetect :消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
         * WriteNullBooleanAsFalse:Boolean字段如果为null,输出为false,而非null
         * WriteMapNullValue:是否输出值为null的字段,默认为false
         */
    }
}

注意: springboot2.0中fastjson消息转换器配置失效的问题。

2、测试:拦截器、消息转换器均有效。

个人学习分享
更多 springboot、springcloud、docker 文章关注微信公众号吧:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/cp026la/article/details/86518655