1. 程式人生 > 實用技巧 >精通SpringBoot-詳解WebMvcConfigurer介面

精通SpringBoot-詳解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);
    }
}

看看控制檯列印資訊

//SpringMvc請求處理的執行過程
Interceptor preHandler method is running !
Controller is running !
Interceptor postHandler method is running !
Interceptor afterCompletion method is running !

題外話:從WebMvcConfigurer這個介面中,可以看到JDK8的一些新特性——在介面中新增了default方法和static方法,這兩種方法可以有方法體。大家可以業餘時間去了解下。這兩種新特性為我們編寫程式碼帶來了更多改變,讓程式碼變得更加簡潔。