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;

/**

  • @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> 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 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;

/**

  • @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方法,这两种方法可以有方法体。大家可以业余时间去了解下。这两种新特性为我们编写代码带来了更多改变,让代码变得更加简洁。

你可能感兴趣的:(springboot——详解WebMvcConfigurer接口)