JDK8的一些新特性——在接口中新增了default方法和static方法,这两种方法可以有方法体。
java8之前,WebMvcConfigurerAdapter还是WebMvcConfigurer得空实现抽象类,WebMvcConfigurerAdapter没有被标注为@Deprecated被遗弃的类。
java8新特性 运用之后:
所以今天要说的是 WebMvcConfigurer,SpringBoot 确实为我们做了很多事情, 但有时候我们想要自己定义一些Handler,Interceptor,ViewResolver,MessageConverter,该怎么做呢。在Spring Boot 1.5版本都是靠重写WebMvcConfigurerAdapter的方法来添加自定义拦截器,消息转换器等。SpringBoot 2.0 后,该类被标记为@Deprecated。因此我们只能靠实现WebMvcConfigurer接口来实现。接下来让我们来看看这个接口类吧!
package org.springframework.web.servlet.config.annotation;
import java.util.List;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
public interface WebMvcConfigurer {
default void configurePathMatch(PathMatchConfigurer configurer) {
}
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
}
default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
}
default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
}
default void addFormatters(FormatterRegistry registry) {
}
default void addInterceptors(InterceptorRegistry registry) {
}
default void addResourceHandlers(ResourceHandlerRegistry registry) {
}
default void addCorsMappings(CorsRegistry registry) {
}
default void addViewControllers(ViewControllerRegistry registry) {
}
default void configureViewResolvers(ViewResolverRegistry registry) {
}
default void addArgumentResolvers(List resolvers) {
}
default void addReturnValueHandlers(List handlers) {
}
default void configureMessageConverters(List> converters) {
}
default void extendMessageConverters(List> converters) {
}
default void configureHandlerExceptionResolvers(List resolvers) {
}
default void extendHandlerExceptionResolvers(List resolvers) {
}
@Nullable
default Validator getValidator() {
return null;
}
@Nullable
default MessageCodesResolver getMessageCodesResolver() {
return null;
}
}
可以看到,这里有很多的空实现,我们只需实现该接口,@Override相应的方法,就可以实现一些你想要的功能。如下:
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 添加类型转换器和格式化器
* @param registry
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatterForFieldType(LocalDate.class, new USLocalDateFormatter());
}
}
拦截器配置如下所示,InterceptorRegistry 内的addInterceptor需要一个实现HandlerInterceptor接口的拦截器实例,addPathPatterns方法用于设置拦截器的过滤路径规则。
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ReqInterceptor()).addPathPatterns("/**");
}
拦截器实现如下:
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* l拦截器实现
*/
public class ReqInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Interceptor preHandler method is running !");
return super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("Interceptor postHandler method is running !");
super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("Interceptor afterCompletion method is running !");
super.afterCompletion(request, response, handler, ex);
}
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Interceptor afterConcurrentHandlingStarted method is running !");
super.afterConcurrentHandlingStarted(request, response, handler);
}
}
配置代码如下所示:
/**
* 跨域支持
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600);
}
这一个配置在之前是经常被使用到的,最经常用到的就是"/"、"/index"路径请求时不通过@RequestMapping配置,而是直接通过配置文件映射指定请求路径到指定View页面,当然也是在请求目标页面时不需要做什么数据处理才可以这样使用,配置内容如下所示:
/**
* 视图控制器配置
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/").setViewName("/index");
}
/**
* 配置请求视图映射
*/
@Bean
public InternalResourceViewResolver resourceViewResolver()
{
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
//请求视图文件的前缀地址
internalResourceViewResolver.setPrefix("/WEB-INF/jsp/");
//请求视图文件的后缀
internalResourceViewResolver.setSuffix(".jsp");
return internalResourceViewResolver;
}
/**
* 视图配置
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
super.configureViewResolvers(registry);
registry.viewResolver(resourceViewResolver());
/*registry.jsp("/WEB-INF/jsp/",".jsp");*/
}
这个配置一般针对于Api接口服务程序,配置在请求返回时内容采用什么转换器进行转换,我们最常用到的就是fastJson的转换,配置如下所示:
/**
* 消息内容转换配置
* 配置fastJson返回json转换
* @param converters
*/
@Override
public void configureMessageConverters(List> converters) {
//调用父类的配置
super.configureMessageConverters(converters);
//创建fastJson消息转换器
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
//创建配置类
FastJsonConfig fastJsonConfig = new FastJsonConfig();
//修改配置返回内容的过滤
fastJsonConfig.setSerializerFeatures(
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty
);
fastConverter.setFastJsonConfig(fastJsonConfig);
//将fastjson添加到视图消息转换器列表内
converters.add(fastConverter);
}
内容转换都是针对面向接口进行编写的实现类,都必须implements HttpMessageConverter接口完成方法的实现。
参考文档: