Bootstrap

Spring Boot WebMvcConfigurer:定制你的 Web 应用

  在构建基于Spring Boot的Web应用程序时,WebMvcConfigurer接口扮演着至关重要的角色。它允许开发者以一种简洁且非侵入的方式自定义Spring MVC的功能,而无需直接扩展框架的核心组件。本文将深入探讨WebMvcConfigurer的作用、如何实现其方法以及在实际项目中的一些最佳实践。
Spring Framework 官方文档

一、什么是 WebMvcConfigurer?

  WebMvcConfigurer是Spring Framework提供的一个接口,旨在为开发者提供一系列钩子(hooks),以便于对Spring MVC的行为进行定制化调整。通过实现该接口并重写其中的方法,您可以轻松地配置静态资源处理、视图解析、路径匹配规则、跨域资源共享(CORS)等特性,而不必创建完整的WebMvcConfigurationSupport类。

关键方法概览

  1. addCorsMappings:用于添加或修改CORS映射,从而控制哪些来源可以访问您的API。
  2. addInterceptors:注册自定义拦截器,这些拦截器可以在请求到达控制器之前执行预处理逻辑,或者在响应返回给客户端之后执行后处理逻辑。
  3. configureDefaultServletHandling:启用默认Servlet的处理功能,这对于服务静态资源特别有用。
  4. configureViewResolvers:配置视图解析器,以确定如何根据逻辑视图名称找到实际的视图实现。
  5. extendMessageConverters:扩展HTTP消息转换器列表,使得能够支持更多类型的媒体格式。
  6. addResourceHandlers:添加资源处理器,用于映射静态文件(如HTML、CSS、JavaScript)到特定的URL路径。
  7. addFormatters:注册自定义格式化器和转换器,用以简化数据绑定过程。
  8. addArgumentResolvers:添加参数解析器,允许您在方法签名中使用自定义类型作为参数。
  9. addReturnValueHandlers:注册返回值处理器,以影响从控制器方法返回的对象如何被解释为HTTP响应体。

二、WebMvcConfigurer 的作用:定制 Spring MVC 的核心配置

  WebMvcConfigurer 是 Spring MVC 提供的一个接口,它允许我们对 Spring MVC 的配置进行自定义。通过实现这个接口,我们可以:

  1. 添加拦截器: 拦截请求,进行权限校验、日志记录等操作。
  2. 自定义消息转换器: 自定义请求和响应的消息转换方式,例如支持 JSON、XML等多种格式。
  3. 配置视图解析器: 自定义视图解析规则,例如使用 Thymeleaf、FreeMarker 等模板引擎。
  4. 配置静态资源:自定义静态资源的访问路径和缓存策略。
  5. 配置格式化器和转换器: 自定义数据类型和字符串之间的转换规则。
  6. 配置跨域:解决跨域请求问题,允许不同域的客户端访问资源。

三、WebMvcConfigurer 的常用配置

3.1 添加拦截器:addInterceptors()

作用: 注册自定义拦截器,对请求进行拦截和处理。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor)
                .addPathPatterns("/api/**")
                .excludePathPatterns("/login", "/register");
    }
}

注意:MyInterceptor 为自定义的拦截器类,要实现HandlerInterceptor接口,在实际项目中通常用来防止用户没有经过授权而通过别人发送的链接访问项目页面。

3.2 自定义消息转换器:configureMessageConverters()

作用: 自定义请求和响应的消息转换器,例如支持 JSON、XML 等格式。

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(SerializerFeature.WriteMapNullValue, SerializerFeature.PrettyFormat);
        converter.setFastJsonConfig(config);
        converters.add(0, converter);
    }
}

3.3 配置视图解析器:configureViewResolvers()

作用: 自定义视图解析规则,例如使用 Thymeleaf、FreeMarker 等模板引擎。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring6.SpringTemplateEngine;
import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring6.view.ThymeleafViewResolver;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setPrefix("classpath:/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("HTML");
        templateResolver.setCharacterEncoding("UTF-8");
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver());
        return templateEngine;
    }

    @Bean
    public ThymeleafViewResolver viewResolver() {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        viewResolver.setCharacterEncoding("UTF-8");
        return viewResolver;
    }
}

3.4 配置静态资源:addResourceHandlers()

作用: 自定义静态资源的访问路径和缓存策略。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/")
                .setCachePeriod(3600);
    }
}

3.5 配置跨域: addCorsMappings()

作用: 解决跨域请求问题,允许不同域的客户端访问资源。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://localhost:8080")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

四、WebMvcConfigurer 的最佳实践

  1. 谨慎使用 WebMvcConfigurationSupport: 尽量避免继承 WebMvcConfigurationSupport,它会禁用 Spring Boot 的自动配置,导致配置变得繁琐。
  2. 保持配置简洁: WebMvcConfigurer 应该只进行Spring MVC 相关的配置,避免掺杂业务逻辑。
  3. 使用 addPathPatterns()excludePathPatterns(): 在添加拦截器时,使用 addPathPatterns() 和 excludePathPatterns() 指定拦截的路径和排除的路径。
  4. 自定义消息转换器: 根据实际需要,自定义消息转换器,例如支持JSON、XML 等格式。
  5. 配置静态资源: 配置静态资源的访问路径和缓存策略,提高性能。
  6. 开启跨域: 根据实际需求,配置跨域请求。
;