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来代替 新坑)。