WebMvcConfigurerAdapter配置类是spring提供的一种配置方式,采用JavaBean的方式替代传统的基于xml的配置来对spring框架进行自定义的配置。因此,在spring boot提倡的基于注解的配置,采用“约定大于配置”的风格下,当需要进行自定义的配置时,便可以继承WebMvcConfigurerAdapter这个抽象类,通过JavaBean来实现需要的配置。
WebMvcConfigurerAdapter是一个抽象类,它只提供了一些空的接口让用户去重写,比如如果想添加拦截器的时候,需要去重写一下addInterceptors()这个方法,去配置自定义的拦截器。我们可以看一下WebMvcConfigurerAdapter提供了哪些接口来供我们使用。
1 public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { 2 /*配置路径匹配参数*/ 3 public void configurePathMatch(PathMatchConfigurer configurer) {} 4 /*配置Web Service或REST API设计中内容协商,即根据客户端的支持内容格式情况来封装响应消息体,如xml,json*/ 5 public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {} 6 /*配置路径匹配参数*/ 7 public void configureAsyncSupport(AsyncSupportConfigurer configurer) {} 8 /* 使得springmvc在接口层支持异步*/ 9 public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {} 10 /* 注册参数转换和格式化器*/ 11 public void addFormatters(FormatterRegistry registry) {} 12 /* 注册配置的拦截器*/ 13 public void addInterceptors(InterceptorRegistry registry) {} 14 /* 自定义静态资源映射*/ 15 public void addResourceHandlers(ResourceHandlerRegistry registry) {} 16 /* cors跨域访问*/ 17 public void addCorsMappings(CorsRegistry registry) {} 18 /* 配置页面直接访问,不走接口*/ 19 public void addViewControllers(ViewControllerRegistry registry) {} 20 /* 注册自定义的视图解析器*/ 21 public void configureViewResolvers(ViewResolverRegistry registry) {} 22 /* 注册自定义控制器(controller)方法参数类型*/ 23 public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {} 24 /* 注册自定义控制器(controller)方法返回类型*/ 25 public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {} 26 /* 重载会覆盖掉spring mvc默认注册的多个HttpMessageConverter*/ 27 public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {} 28 /* 仅添加一个自定义的HttpMessageConverter,不覆盖默认注册的HttpMessageConverter*/ 29 public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {} 30 /* 注册异常处理*/ 31 public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {} 32 /* 多个异常处理,可以重写次方法指定处理顺序等*/ 33 public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {} 34 }
WebMvcConfigurerAdapter提供了很多的接口供用户去实现自定义的配置项。下面挑几个比较重要的介绍一下如何使用这些接口来自定义配置。
1.注册拦截器
首先,编写拦截器的代码:
1 public class LoginInterceptor extends HandlerInterceptorAdapter { 2 3 private static final Logger logger = LoggerFactory.getLogger(LoginInterceptor.class); 4 5 @Override 6 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 7 logger.info("-----------------------------"); 8 logger.info(request.getRequestedSessionId()); 9 logger.info("-----------------------------"); 10 return true; 11 } 12 }
这里只打印相关信息,然后,需要写一个config类去配置这个拦截器:
1 @Configuration 2 public class WebConfig extends WebMvcConfigurerAdapter { 3 /* 4 * 拦截器配置*/ 5 @Override 6 public void addInterceptors(InterceptorRegistry registry) { 7 registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**"); 8 }
配置类继承了WebMvcConfigurerAdapter这个类,并且重写了addInterceptors这个方法,在方法中,注册了上面编写的拦截器,并且为此拦截器配置了拦截路径,这样一来就算是配置好了这个拦截器。
2.配置CORS跨域
只需要在上面的webConfig里重写WebMvcConfigurerAdapter的addCorsMappings方法就可以获得基于spring的跨域支持。
1 /** 2 * 跨域CORS配置 3 * @param registry 4 */ 5 @Override 6 public void addCorsMappings(CorsRegistry registry) { 7 super.addCorsMappings(registry); 8 registry.addMapping("/**") 9 .allowedHeaders("*") 10 .allowedMethods("POST","GET") 11 .allowedOrigins("http://...") 12 .allowCredentials(true); 13 }
3.配置ViewController
当首页或者登陆页的页面对外暴露,不需要加载任何的配置的时候,这些页面将不通过接口层,而是直接访问,这时,就需要配置ViewController指定请求路径直接到页面。
1 /** 2 * 视图控制器配置 3 * @param registry 4 */ 5 @Override 6 public void addViewControllers(ViewControllerRegistry registry) { 7 super.addViewControllers(registry); 8 registry.addViewController("/").setViewName("forward:/index.html"); 9 }
4.配置ViewResolver
通常在使用jsp的项目中,会基于spring mvc配置的文件去配置视图解析器,通过重写WebMvcConfigurerAdapter里的configureViewResolvers也可以将自己定义的InternalResourceViewResolver配置整合进spring中。
1 /** 2 * 配置请求视图映射 3 * 4 * @return 5 */ 6 @Bean 7 public InternalResourceViewResolver resourceViewResolver() { 8 InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); 9 //请求视图文件的前缀地址 10 internalResourceViewResolver.setPrefix("/WEB-INF/jsp/"); 11 //请求视图文件的后缀 12 internalResourceViewResolver.setSuffix(".jsp"); 13 return internalResourceViewResolver; 14 } 15 16 @Override 17 public void configureViewResolvers(ViewResolverRegistry registry) { 18 super.configureViewResolvers(registry); 19 registry.viewResolver(resourceViewResolver()); 20 }
可以看一下ViewResolverRegistry中的代码:
1 public UrlBasedViewResolverRegistration jsp() { 2 return this.jsp("/WEB-INF/", ".jsp"); 3 } 4 5 public UrlBasedViewResolverRegistration jsp(String prefix, String suffix) { 6 InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 7 resolver.setPrefix(prefix); 8 resolver.setSuffix(suffix); 9 this.viewResolvers.add(resolver); 10 return new UrlBasedViewResolverRegistration(resolver); 11 }
可以看到,即使不去配置,spring也会新建一个默认的视图解析器。十分方便。
5.配置Formatter
当请求的参数中带有日期的参数的时候,可以在此配置formatter使得接收到日期参数格式统一。
1 @Override 2 public void addFormatters(FormatterRegistry registry) { 3 registry.addFormatter(new Formatter<Date>() { 4 @Override 5 public Date parse(String date, Locale locale) { 6 return new Date(Long.parseLong(date)); 7 } 8 9 @Override 10 public String print(Date date, Locale locale) { 11 return Long.valueOf(date.getTime()).toString(); 12 } 13 }); 14 }
总结一下,本文主要讲了如何通过JavaBean替代xml为springmvc做出自定义的配置,比较符合spring boot的去xml配置的风格。