Spring boot 梳理 - WebMvcConfigurer接口 使用案例

转:https://yq.aliyun.com/articles/617307

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

原文地址:https://www.cnblogs.com/jiangtao1218/p/10241721.html

时间: 2024-10-02 01:26:16

Spring boot 梳理 - WebMvcConfigurer接口 使用案例的相关文章

spring boot与jdbcTemplate的整合案例2

简单入门了spring boot后,接下来写写跟数据库打交道的案例.博文采用spring的jdbcTemplate工具类与数据库打交道. 下面是搭建的springbootJDBC的项目的总体架构图: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www

Spring Boot提供RESTful接口时的错误处理实践

本文首发于个人网站:http://www.javaadu.online/,如需转载,请注明出处 使用Spring Boot开发微服务的过程中,我们会使用别人提供的接口,也会设计接口给别人使用,这时候微服务应用之间的协作就需要有一定的规范. 基于rpc协议,我们一般有两种思路:(1)提供服务的应用统一将异常包起来,然后用错误码交互:(2)提供服务的应用将运行时异常抛出,抛出自定义的业务异常,服务的调用者通过异常catch来处理异常情况. 基于HTTP协议,那么最流行的就是RESTful协议,服务提

spring boot开发REST接口

1.配置pom.xml文件的<parent>和<depencencies>,指定spring boot web依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.1.RELEASE</version> <r

Spring boot 梳理 - 代码结构(Main类的位置)

Spring boot 对代码结构无特殊要求,但有个套最佳实践的推荐 不要使用没有包名的类.没有包名时,@ComponentScan, @EntityScan, or @SpringBootApplication 可能会有问题. Main类在包路径中的位置:强烈建议main类放在包的根路径上.We generally recommend that you locate your main application class in a root package above other classe

Spring boot 梳理 - Spring Boot 属性配置和使用(转)

转:https://blog.csdn.net/isea533/article/details/50281151 Spring Boot 支持多种外部配置方式,这些方式优先级如下: 命令行参数 来自java:comp/env的JNDI属性 Java系统属性(System.getProperties()) 操作系统环境变量 RandomValuePropertySource配置的random.*属性值 jar包外部的application-{profile}.properties或applicat

spring boot使用定时器框架Quartz案例

一.你需要在项目中加入quartz-all-2.1.7.jar的jar包(我这里使用spring boot环境) 二.然后需要新建一个类去注册定时任务和销毁定时任务,这个类需要实现ServletContextListener的接口中的contextInitialized和contextDestroyed方法 三.接着就是去定义你自己的定时任务了,也就是再去新建一个类去实现Job的接口中的execute()方法,这个方法就是你在定时任务执行的时候要执行的内容 1, SimpleTrigger 指定

Spring boot 梳理 [email&#160;protected]、@EnableAutoConfiguration与(@EnableWebMVC、WebMvcConfigurationSupport,WebMvcConfigurer和WebMvcConfigurationAdapter)

@EnableWebMvc=继承DelegatingWebMvcConfiguration=继承WebMvcConfigurationSupport 直接看源码,@EnableWebMvc实际上引入一个DelegatingWebMvcConfiguration @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Import({DelegatingWebMvcConfiguration.clas

Spring boot 梳理 - SpringApplication

简单启动方式 public static void main(String[] args) { SpringApplication.run(MySpringConfiguration.class, args); } 调试方式启动 java -jar myproject-0.0.1-SNAPSHOT.jar --debug 高级启动方式 @SpringBootApplication public class App { public static void main( String[] args

Spring boot 梳理 - 在bean中使用命令行参数-自动装配ApplicationArguments

If you need to access the application arguments that were passed to SpringApplication.run(-?), you can inject a org.springframework.boot.ApplicationArguments bean. The ApplicationArguments interface provides access to both the raw String[] arguments