【开发者必备】Spring Boot 2.7.x:WebMvcConfigurer配置手册来了(一)!

关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 引言

在 Spring Boot 应用的开发中,我们常常会遇到这样的场景:需要定制化 Web 行为,却不想完全重写 Spring MVC 的默认配置。无论是处理跨域请求、添加统一拦截逻辑,还是配置静态资源映射,这些看似简单的需求背后,都离不开一个强大的配置接口------WebMvcConfigurer

Spring Boot 2.7.x 作为当前广泛使用的稳定版本,在自动配置和扩展性方面做了大量优化。从本节开始,我们将分几节内容分别介绍WebMvcConfigurer的所有配置项,以便在后续使用中能够清楚的了解每一项的作用。

本节之后相关的内容均使用的是Spring boot 2.7.18

02 概览

org.springframework.web.servlet.config.annotation.WebMvcConfigurer接口中总共包含18个扩展方法:

  • configurePathMatch:配置路径匹配
  • configureContentNegotiation:配置内容协商
  • configureAsyncSupport:配置异步请求的支持
  • configureDefaultServletHandling:配置Servlet的默认跳转
  • addFormatters:增加格式化程序和转化器
  • addInterceptors:添加拦截器
  • addResourceHandlers:添加资源处理器
  • addCorsMappings:处理跨域
  • addViewControllers:增加视图控制
  • configureViewResolvers:配置视图解析器
  • addArgumentResolvers:增加参数解析器
  • addReturnValueHandlers:增加返回值的控制器
  • configureMessageConverters:配置消息转化器
  • extendMessageConverters:继承消息转化器
  • configureHandlerExceptionResolvers:增加异常解析器
  • extendHandlerExceptionResolvers:继承异常解析器
  • getValidator:定制Validator校验器
  • getMessageCodesResolver:定制消息和Code的解析器

Spring Boot为Spring MVC提供了自动配置,适用于大多数应用程序。它替代了对@EnableWebMvc的需求,且两者不能一起使用。除了Spring MVC的默认设置外,该自动配置还提供以下功能:

WebMvcConfigurer替代了@EnableWebMvc的前提下,并对其做了增强。如果使用了@EnableWebMvc,就会失去增强的功能,需要手动接管Spring MVC

所以一般情况下我们是不需要使用@EnableWebMvc注解的。

03 方法1

configurePathMatch

java 复制代码
void configurePathMatch(PathMatchConfigurer configurer) {
}

作用:配置 URL 路径匹配规则。

使用场景

  • 路径后缀匹配
  • URL 尾斜杠处理
  • 自定义路径匹配策略

正常来讲我们是不需要配置任何东西的,但是为了扩展或者兼容一些老的项目,需要去配置。我们看看官网的说明:

3.1 案例演示

还记的当时数据公司的老项目中,根据前端的/xxx.json路径,寻找对应的控制层,找了好久都没有找到,只找到/xxx路径,并没有找到.json的路径。当时真的是一脸懵逼。恰好这个配置就是当前案例表现。

java 复制代码
@GetMapping("/foo")
public ResponseEntity<String> foo() {
    return ResponseEntity.ok("FooController:请求成功!");
}

正常/foo可以访问,但是/foo.json是不可访问的。

3.2 增加路径匹配的参数

java 复制代码
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
    
    // 默认关闭,这里开启后缀匹配
    configurer.setUseSuffixPatternMatch(true);
}

此方法已经被弃用了,未来可能被删除。

设置了之后发现还是不能生效。我们需要借助官方文档的内容:

文档说明:Spring Framework 5.3开始,Spring Boot使用PathPatternParser作为默认策略与后缀匹配不兼容,需要更改策略:

properties 复制代码
spring.mvc.pathmatch.matching-strategy=ant-path-matcher

重新测试:

发现/foofoo.json都是可以匹配的。

不止.json,任何后缀后可以匹配。原因注释已经说明了:在将模式匹配到请求时是否使用后缀模式匹配 (".*")。如果启用,则映射到 "/users" 的方法也会匹配到 "/users.*"

为什么SpringBoot要禁用后缀匹配呢?官方也给了答案:

3.3 其他参数

setUseTrailingSlashMatch,采用斜杠匹配默认是开启的。

开启的话,路径结尾都是自动映射/,访问的时候通过/xx/xx/都可以访问,否则就是严格匹配,案例就只能/xx可以访问。

其他参数,大家可以自行探索。

04 方法2

configureContentNegotiation

java 复制代码
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
	}

作用:配置内容协商策略,根据客户端请求的不同方式(如 URL 后缀、请求头等)决定返回数据的媒体类型。

使用场景

  • API 版本控制(通过不同媒体类型)
  • 支持多种数据格式(JSON、XML、YAML等)
  • 向后兼容旧客户端
  • 根据请求特性返回不同格式的响应

4.1 开启配置

这个是针对那些不能正确发送Accept请求头的HTTP客户端,通过指定特殊的参数来确定请求的媒体类型。默认是关闭的。

我们需要开启开关,可以通过配置文件配置也可以通过配置参数。

如果按照配置问文件参照官方文档:

如果按照配置参数:

java 复制代码
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    // 开启内容协商
    configurer.favorParameter(true)
        // 执行参数:format 为默认参数
        .parameterName("format 为默认参数");
}

两个配置一个即可。

默认的参数是:format,也可以通过配置或者配置文件修改。

4.2 验证测试

如上图,不开启的内容协商,这里的参数会是正常的参数被接收还是遗弃,但是肯定不会报错。

开启之后就会出现媒体类型无法接受的异常。如果换掉配置的参数,就和正常的参数没有区别了。

我们将媒体类型改为为json即可正常访问或者绑定指定的媒体类型,如下配置:

java 复制代码
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer
        .favorParameter(true)
        .parameterName("format")
        .mediaType("qq", MediaType.APPLICATION_JSON);
}

这里通过qq这个参数值,映射了application/json

4.3 API版本控制

可以通过该配置实现API的版本控制。

配置

java 复制代码
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer
        .favorParameter(true)
        .parameterName("format")
        .mediaType("v1", MediaType.valueOf("application/vnd.api.v1+json"))
        .mediaType("v2", MediaType.valueOf("application/vnd.api.v2+json"));
}

API接口

java 复制代码
@GetMapping(value = "/pathMatch", produces = "application/vnd.api.v1+json")
public ResponseEntity<String> pathMatchV1(String json) {
    System.out.println("json v1:" + json);
    return ResponseEntity
        .ok("FooController:pathMatch v1 请求成功!");
}

@GetMapping(value = "/pathMatch", produces = "application/vnd.api.v2+json")
public ResponseEntity<String> pathMatchV2(String json) {
    System.out.println("json v2:" + json);
    return ResponseEntity
        .ok("FooController:pathMatch v2 请求成功!");
}

结果

可以通过指定的参数,访问不同版本的接口。

4.4 通过后缀名确定媒体类型

该功能需要建立在方法1的的基础上。

配置完成之后,就可以通过.v1或者.v2的形式指定版本:

05 小结

本节就先接受这两个方法:

  • configurePathMatch:路径匹配
  • configureContentNegotiation:内容协商

每一项配置里面都有很多可以扩展的点,每一个点展开都可以无限放大。分享的内容仅仅是简单额入门,更详细的配置需要深入到每一个点,有兴趣的可以去深挖!

相关推荐
aricvvang3 小时前
🚀 NestJS 使用 cache-manager-redis-store 缓存无效?真相在这里!
javascript·后端·nestjs
oak隔壁找我3 小时前
Java Collection 包使用指南
java·后端
Hero | 柒3 小时前
设计模式之单例模式
java·单例模式·设计模式
哈哈哈哈~3 小时前
Java中的单例模式
java·单例模式
纪莫3 小时前
技术面:Spring(循环依赖,spring与springboot的区别)
java·spring·java面试⑧股
oak隔壁找我3 小时前
Spring Boot MongoDB 使用技巧
java·后端
嫄码4 小时前
BigDecimal对象比较时的注意事项
java
倚栏听风雨4 小时前
RAG检索增强生成(Retrieval Augmented Generation)
后端