WebMvcConfigurerAdapter配置类是spring提供的一种配置方式,采用javabean的方式替代传统的基于xml的配置来对spring框架进行自定义的配置。因此,在springboot提倡的基于注解的配置 && 采用约定大于配置的风格下,当需要进行自定义配置的时候,便可以继承WebMvcConfigurerAdapter这个抽象类,通过javabean来实现需要的配置。

WebMvcConfigurerAdapter是一个抽象类,只提供一些空的接口让用户去重写。其提供的接口如下:

public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
    /*配置路径匹配参数*/
    public void configurePathMatch(PathMatchConfigurer configurer) {}
    /*配置Web Service或REST API设计中内容协商,即根据客户端的支持内容格式情况来封装响应消息体,如xml,json*/
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}
    /*配置路径匹配参数*/
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {}
    /* 使得springmvc在接口层支持异步*/
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}
    /* 注册参数转换和格式化器*/
    public void addFormatters(FormatterRegistry registry) {}
    /* 注册配置的拦截器*/
    public void addInterceptors(InterceptorRegistry registry) {}
    /* 自定义静态资源映射*/
    public void addResourceHandlers(ResourceHandlerRegistry registry) {}
    /* cors跨域访问*/
    public void addCorsMappings(CorsRegistry registry) {}
    /* 配置页面直接访问,不走接口*/
    public void addViewControllers(ViewControllerRegistry registry) {}
    /* 注册自定义的视图解析器*/
    public void configureViewResolvers(ViewResolverRegistry registry) {}
    /* 注册自定义控制器(controller)方法参数类型*/
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {}
    /* 注册自定义控制器(controller)方法返回类型*/
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {}
    /* 重载会覆盖掉spring mvc默认注册的多个HttpMessageConverter*/
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}
    /* 仅添加一个自定义的HttpMessageConverter,不覆盖默认注册的HttpMessageConverter*/
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}
    /* 注册异常处理*/
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {}
    /* 多个异常处理,可以重写次方法指定处理顺序等*/
    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {}
}

使用WebMvcConfigurerAdapter提供的接口实现自定义配置项示例:

1、注册拦截器

首先编写拦截器类

public class LoginInterceptor extends HandlerInterceptorAdapter {

    private static final Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //拦截器相关处理代码
        logger.info("*********我是拦截器************");
        return true;
    }
}

自定义配置类继承WebMvcConfigurerAdapter接口实现接口的addInterceptors方法来配制我们自定义的拦截器

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    /*
    * 拦截器配置*/
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**");//注册拦截器,并配置拦截路径
}

2.配置CORS跨域

只需要在上面的webConfig里重写WebMvcConfigurerAdapter的addCorsMappings方法就可以获得基于spring的跨域支持。

/**
     * 跨域CORS配置
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        super.addCorsMappings(registry);
        registry.addMapping("/**")
                .allowedHeaders("*")
                .allowedMethods("POST","GET")
                .allowedOrigins("http://...")
                .allowCredentials(true);
    }

3.配置ViewController

当首页或者登陆页的页面对外暴露,不需要加载任何的配置的时候,这些页面将不通过接口层,而是直接访问,这时,就需要配置ViewController指定请求路径直接到页面。

/**
     * 视图控制器配置
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        super.addViewControllers(registry);
        registry.addViewController("/").setViewName("forward:/index.html");
    }

4.配置Formatter

当请求的参数中带有日期的参数的时候,可以在此配置formatter使得接收到日期参数格式统一

@Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new Formatter<Date>() {
            @Override
            public Date parse(String date, Locale locale) {
                return new Date(Long.parseLong(date));
            }

            @Override
            public String print(Date date, Locale locale) {
                return Long.valueOf(date.getTime()).toString();
            }
        });
    }

以上应用只适用于spring boot 2.0,Spring 5.0之前的版本,spring boot 2.0,Spring 5.0 以后WebMvcConfigurerAdapter会取消掉,高版本也提供了两种解决方案:

方案1:直接实现WebMvcConfigurer

@Configuration
public class WebMvcConfg implements WebMvcConfigurer {

        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/index").setViewName("index");
        }

}

方案2: 直接继承WebMvcConfigurationSupport

@Configuration
public class WebMvcConfg extends WebMvcConfigurationSupport {

        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/index").setViewName("index");
        }

}

其实,源码下WebMvcConfigurerAdapter是实现WebMvcConfigurer接口,所以直接实现WebMvcConfigurer接口也可以;WebMvcConfigurationSupport与WebMvcConfigurerAdapter、接口WebMvcConfigurer处于同一个目录下,WebMvcConfigurationSupport包含WebMvcConfigurer里面的方法,高版本中推荐使用WebMvcConfigurationSupport类,其实,源码下WebMvcConfigurerAdapter是实现WebMvcConfigurer接口,所以直接实现WebMvcConfigurer接口也可以;WebMvcConfigurationSupport与WebMvcConfigurerAdapter、接口WebMvcConfigurer处于同一个目录下,WebMvcConfigurationSupport包含WebMvcConfigurer里面的方法,高版本中推荐使用WebMvcConfigurationSupport类,其禁止了SpringBoot对mvc的自动配置,完全由用户自己实现配置(不注意的话会遇到坑:springboot2.0、spring5.0 拦截器配置WebMvcConfigurerAdapter过时使用WebMvcConfigurationSupport来代替 新坑)。