休闲运动系列:羽毛球免安装绿色中文版
662M · 2025-11-11
在 Spring Boot 应用的开发中,我们常常会遇到这样的场景:需要定制化 Web 行为,却不想完全重写 Spring MVC 的默认配置。无论是处理跨域请求、添加统一拦截逻辑,还是配置静态资源映射,这些看似简单的需求背后,都离不开一个强大的配置接口——WebMvcConfigurer。
Spring Boot 2.7.x 作为当前广泛使用的稳定版本,在自动配置和扩展性方面做了大量优化。从本节开始,我们将分几节内容分别介绍WebMvcConfigurer的所有配置项,以便在后续使用中能够清楚的了解每一项的作用。
本节之后相关的内容均使用的是Spring boot 2.7.18
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注解的。
void configurePathMatch(PathMatchConfigurer configurer) {
}
作用:配置 URL 路径匹配规则。
使用场景:
正常来讲我们是不需要配置任何东西的,但是为了扩展或者兼容一些老的项目,需要去配置。我们看看官网的说明:
还记的当时数据公司的老项目中,根据前端的/xxx.json路径,寻找对应的控制层,找了好久都没有找到,只找到/xxx路径,并没有找到.json的路径。当时真的是一脸懵逼。恰好这个配置就是当前案例表现。
@GetMapping("/foo")
public ResponseEntity<String> foo() {
return ResponseEntity.ok("FooController:请求成功!");
}
正常/foo可以访问,但是/foo.json是不可访问的。
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
// 默认关闭,这里开启后缀匹配
configurer.setUseSuffixPatternMatch(true);
}
此方法已经被弃用了,未来可能被删除。
设置了之后发现还是不能生效。我们需要借助官方文档的内容:
文档说明:Spring Framework 5.3开始,Spring Boot使用PathPatternParser作为默认策略与后缀匹配不兼容,需要更改策略:
spring.mvc.pathmatch.matching-strategy=ant-path-matcher
重新测试:
发现/foo和foo.json都是可以匹配的。
不止.json,任何后缀后可以匹配。原因注释已经说明了:在将模式匹配到请求时是否使用后缀模式匹配 (".*")。如果启用,则映射到 “/users” 的方法也会匹配到 “/users.*”
为什么SpringBoot要禁用后缀匹配呢?官方也给了答案:
如setUseTrailingSlashMatch,采用斜杠匹配默认是开启的。
开启的话,路径结尾都是自动映射/,访问的时候通过/xx和/xx/都可以访问,否则就是严格匹配,案例就只能/xx可以访问。
其他参数,大家可以自行探索。
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
}
作用:配置内容协商策略,根据客户端请求的不同方式(如 URL 后缀、请求头等)决定返回数据的媒体类型。
使用场景:
这个是针对那些不能正确发送Accept请求头的HTTP客户端,通过指定特殊的参数来确定请求的媒体类型。默认是关闭的。
我们需要开启开关,可以通过配置文件配置也可以通过配置参数。
如果按照配置问文件参照官方文档:
如果按照配置参数:
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// 开启内容协商
configurer.favorParameter(true)
// 执行参数:format 为默认参数
.parameterName("format 为默认参数");
}
两个配置一个即可。
默认的参数是:format,也可以通过配置或者配置文件修改。
如上图,不开启的内容协商,这里的参数会是正常的参数被接收还是遗弃,但是肯定不会报错。
开启之后就会出现媒体类型无法接受的异常。如果换掉配置的参数,就和正常的参数没有区别了。
我们将媒体类型改为为json即可正常访问或者绑定指定的媒体类型,如下配置:
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.favorParameter(true)
.parameterName("format")
.mediaType("qq", MediaType.APPLICATION_JSON);
}
这里通过qq这个参数值,映射了application/json。
可以通过该配置实现API的版本控制。
配置
@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接口
@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 请求成功!");
}
结果
可以通过指定的参数,访问不同版本的接口。
该功能需要建立在方法1的的基础上。
配置完成之后,就可以通过.v1或者.v2的形式指定版本:
本节就先接受这两个方法:
configurePathMatch:路径匹配configureContentNegotiation:内容协商每一项配置里面都有很多可以扩展的点,每一个点展开都可以无限放大。分享的内容仅仅是简单额入门,更详细的配置需要深入到每一个点,有兴趣的可以去深挖!