精通Spring Boot——详解WebMvcConfigurer接口

SpringBoot 确实为我们做了很多事情, 但有时候我们想要自己定义一些Handler,Interceptor,ViewResolver,MessageConverter,该怎么做呢。在Spring Boot 1.5版本都是靠重写WebMvcConfigurerAdapter的方法来添加自定义拦截器,消息转换器等。SpringBoot 2.0 后,该类被标记为@Deprecated。因此我们只能靠实现WebMvcConfigurer接口来实现。接下来让我们来看看这个接口类吧!(列举下常用的方法供参考)

package com.developlee.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.developlee.configurer.USLocalDateFormatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.JsonbHttpMessageConverter;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
 * @TODO //
 * @Author Lensen
 * @Date 2018/7/21
 * @Description 实现WebMvcConfigurer接口,
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
 /**
 * 添加类型转换器和格式化器
 * @param registry
 */
 @Override
 public void addFormatters(FormatterRegistry registry) {
 registry.addFormatterForFieldType(LocalDate.class, new USLocalDateFormatter());
 }
 /**
 * 跨域支持
 * @param registry
 */
 @Override
 public void addCorsMappings(CorsRegistry registry) {
 registry.addMapping("/**")
 .allowedOrigins("*")
 .allowCredentials(true)
 .allowedMethods("GET", "POST", "DELETE", "PUT")
 .maxAge(3600 * 24);
 }
 /**
 * 添加静态资源--过滤swagger-api (开源的在线API文档)
 * @param registry
 */
 @Override
 public void addResourceHandlers(ResourceHandlerRegistry registry) {
 //过滤swagger
 registry.addResourceHandler("swagger-ui.html")
 .addResourceLocations("classpath:/META-INF/resources/");
 registry.addResourceHandler("/webjars/**")
 .addResourceLocations("classpath:/META-INF/resources/webjars/");
 registry.addResourceHandler("/swagger-resources/**")
 .addResourceLocations("classpath:/META-INF/resources/swagger-resources/");
 registry.addResourceHandler("/swagger/**")
 .addResourceLocations("classpath:/META-INF/resources/swagger*");
 registry.addResourceHandler("/v2/api-docs/**")
 .addResourceLocations("classpath:/META-INF/resources/v2/api-docs/");
 }
 }
 /**
 * 配置消息转换器--这里我用的是alibaba 开源的 fastjson
 * @param converters
 */
 @Override
 public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
 //1.需要定义一个convert转换消息的对象;
 FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
 //2.添加fastJson的配置信息,比如:是否要格式化返回的json数据;
 FastJsonConfig fastJsonConfig = new FastJsonConfig();
 fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,
 SerializerFeature.WriteMapNullValue,
 SerializerFeature.WriteNullStringAsEmpty,
 SerializerFeature.DisableCircularReferenceDetect,
 SerializerFeature.WriteNullListAsEmpty,
 SerializerFeature.WriteDateUseDateFormat);
 //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);
 }
 @Override
 public void addInterceptors(InterceptorRegistry registry) {
 registry.addInterceptor(new ReqInterceptor()).addPathPatterns("/**");
 }
}

添加一个Interceptor,作为测试

package com.developlee.configurer;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * @TODO //
 * @Author Lensen
 * @Date 2018/7/21
 * @Description 请求Interceptor
 */
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);
 }
}

写个controller测试下

@Controller
@RequestMapping("/locale")
public class LocaleController {
 @GetMapping("/date")
 @ResponseBody
 public String locale(Locale locale){
 System.out.println("Controller is running !");
 return "Hello" + USLocalDateFormatter.getPattern(locale);
 }
}

请求地址: http://localhost:8080/locale/date ,看看控制台打印信息

//SpringMvc请求处理的执行过程

Interceptor preHandler method is running !

Controller is running !

Interceptor postHandler method is running !

Interceptor afterCompletion method is running !

题外话:从WebMvcConfigurer这个接口中,可以看到JDK8的一些新特性——在接口中新增了default方法和static方法,这两种方法可以有方法体。大家可以业余时间去了解下。这两种新特性为我们编写代码带来了更多改变,让代码变得更加简洁。

精通Spring Boot——详解WebMvcConfigurer接口

相关推荐