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

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
重新测试:
发现/foo
和foo.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
:内容协商
每一项配置里面都有很多可以扩展的点,每一个点展开都可以无限放大。分享的内容仅仅是简单额入门,更详细的配置需要深入到每一个点,有兴趣的可以去深挖!