路径匹配
路径匹配概述
在 Spring 框架(这里聚焦于 Spring5.3 及后续版本涉及的请求路径匹配相关内容 )里,请求路径匹配是很关键的部分,是处理 Web 请求时确定 URL 路径与控制器方法映射关系的核心机制。
路径匹配是指框架如何将传入的 HTTP 请求 URL
映射到对应的控制器方法上。例如,当用户访问 /users/123
时,框架需要决定这个请求应该由哪个 @GetMapping
或
@RequestMapping
注解的方法来处理。
在 Spring Framework 5.3 及 Spring Boot 2.4 之后,引入了一种新的路径匹配机制,这一变化在 Spring Boot 3 中得到了保留和进一步的应用。这个新机制主要是通过 PathPattern 代替了传统的 AntPathMatcher。
AntPathMatcher 是基于 Ant 风格的路径匹配,而 PathPattern 则是一个更高效、更精确的路径匹配方式,它是通过 PathPatternParser 解析得到的。
路径匹配两大策略
Spring5.3 之后加入了更多的请求路径匹配的实现策略:
以前只支持 AntPathMatcher 策略,现在提供了 PathPatternParser 策略。并且可以让我们指定到底使用那种策略。
Spring Boot 默认使用新版的路径匹配器,也就是 PathPatternParser
,性能高,但是 **
不能写在中间
使用 spring.mvc.pathmath.macthing-strategy
改变匹配策略
具体策略说明
- AntPathMatcher:是 Spring
中传统的路径匹配策略,基于 Ant 风格的路径模式语法,在之前的 Spring
版本中广泛使用,很多开发者对其规则比较熟悉,用于处理各种 Web
请求路径与配置的映射关系,像在 Spring MVC
里配置请求映射(
@RequestMapping
等注解配合路径规则)时,常基于它工作 。 - PathPatternParser:Spring5.3 之后新增的策略,它在一些场景下可能有更好的性能表现或者更灵活的特性,和 Ant 风格路径用法有一定关联但也有自身特点,也用于解析请求路径,确定是否匹配预设的路径模式,辅助完成请求的路由等操作 。开发者可以根据项目实际需求,比如对路径匹配性能、规则灵活度等方面的要求,来指定使用哪种策略。
Ant 风格路径
AntPathMatcher
是 Spring 框架中一个基于 Ant
风格模式的路径匹配器,它支持使用 ?
、*
和
**
等通配符进行匹配。
Ant 风格的路径模式语法具有以下规则:
*
(星号)- 作用是匹配任意数量的字符,但不包含目录分隔符(
/
)。 - 比如
*.html
,就是说不管前面的文件名是什么(像a.html
、abc.html
等),只要是以.html
为后缀的文件路径,都能匹配上。常用于匹配同一层级下符合某种后缀特征的文件或路径片段。
- 作用是匹配任意数量的字符,但不包含目录分隔符(
?
(问号)- 代表匹配任意一个字符,同样不跨越目录分隔符。
- 例如有路径
a?b
,那么aab
、acb
等单字符差异的路径能匹配,而aabb
(多了一个字符 )就匹配不上。可以用于精确控制路径中某一位字符的不确定性场景。
**
(两个星号)- 强大之处在于能匹配任意数量的目录,包括多层嵌套的目录结构。
- 像
folder2/**/*.jsp
,不管folder2
下面有多少级子目录,只要最终文件是.jsp
后缀,就会被匹配到,比如folder2/a/b/c.jsp
、folder2/d.jsp
等情况都满足,在处理多层目录下的资源匹配时非常好用。
{}
(花括号)- 用于定义命名的模式占位符,路径变量,这在 RESTful 风格的路径中很常用。
- 比如
/{type}/id}.html
,这里的{type}
和{id}
就是占位符,实际请求路径可能是/user/123.html
,此时type
就对应user
,id
对应123
,在 Spring MVC 中,这些占位符的值可以被提取出来,作为方法参数使用(通过@PathVariable
注解 ),方便进行动态的路径参数处理。
[]
(方括号)- 用来表示字符集合,限定匹配的字符范围。
- 如
[a - z]
就表示只能匹配小写字母 a 到 z 中的一个字符,若路径规则是[a - z]bc
,那么abc
、bbc
等符合字符范围的能匹配,而1bc
(数字不在集合内 )、Abc
(大写字母不在集合内 )就匹配失败,可用于对路径中特定位置字符进行精确范围限制的场景,比如某些有特定字符规范的编号路径等 。
注意:Ant 风格的路径模式语法中的特殊字符需要转义
转义说明
在 Ant 风格路径模式语法里,特殊字符(像*
、?
等本身具有特殊匹配含义的字符
)如果是作为普通字符出现在路径中(比如路径里真的有一个*
作为文件名的一部分
),就需要进行转义,一般是通过在特殊字符前加反斜杠(\
)等方式,让框架把它们当作普通字符对待,而不是执行匹配规则,否则框架会按照匹配规则去解析,导致路径匹配结果不符合预期
。
1 | // 匹配字面量 /files/*.txt |
PathPatternParser 风格路径
PathPatternParser: 一个新的路径解析器,用于解析路径模式字符串,创建 PathPattern 对象。它引入了更严格的语法规则,并且设计了更高效的匹配算法。
PathPattern: 由 PathPatternParser 解析路径模式字符串得到的对象,代表了一种更加精确和高效的路径匹配方式。
特点:
- 性能: 相比 AntPathMatcher,PathPattern 提供了更高的性能。这是因为 PathPattern 在匹配过程中采用了更加高效的算法,在 jmh 基准测试下,有 6~8 倍吞吐量提升,降低 30%~40%空间分配率。
- 精确性: PathPattern 的语法规则更严格,能够提供更精确的匹配结果。
- 路径变量语法更严格,必须明确指定变量名:
/{name}
- 路径变量语法更严格,必须明确指定变量名:
- 使用场景: 在 Spring Framework 5.3 及之后的版本中,默认使用 PathPattern 进行路径匹配。如果你的应用是基于这些版本的 Spring Boot 构建的,那么在处理路径匹配时,你将会默认使用 PathPattern。
- 对
**
通配符的使用有限制(不能出现在路径中间)- 有效:
/resources/**
- 无效:
/resources/**/file
- 有效:
路径匹配示例
控制器方法映射
1 |
|
解释一下/products/{code:[a-z]+\\d+}
这段正则是如何匹配/api/products/abc123
的
{code:[a-z]+\\d+}
这种形式定义了一个名为code
的路径变量,并且对它的值设定了正则表达式约束。- 其中,其中
[a-z]+
表示这个部分必须由至少一个小写字母组成,\\d+
表示这部分必须由至少一个数字组成 - 所以说,整个正则表达式
[a-z]+\\d+
的意思是,code
的值要先有至少一个小写字母,接着有至少一个数字,而且字母和数字之间不能有其他字符,所以,/api/products/a1
也能匹配,而/api/products/123abc
就无法匹配
静态资源匹配
1 | # 匹配所有静态html文件 |
拦截器路径配置
1 |
|
内容协商
注意这里多源码解读
什么是内容协商
在 Spring Boot 3 中,内容协商(Content Negotiation)是一个非常重要的概念,特别是在构建 RESTful API 时。
内容协商机制允许客户端和服务器就如何交换资源的数据格式达成协议,允许同一资源URL根据客户端的偏好提供不同格式的表示。这一过程通常由服务器和客户端共同完成:客户端告知服务器它期望的内容类型,服务器根据自身能力选择最合适的表现形式返回。
简单来说,它允许客户端通过请求头指定它们希望接收响应的格式(如 JSON,XML 等),服务器基于这些信息来决定以什么格式返回数据。
内容协商主要依靠媒体类型(Media
Type),也称为MIME类型,如application/json
、application/xml
、text/html
等。
也就是,一套系统适配多端数据返回。

Spring Boot 中的内容协商架构
SpringBoot基于Spring MVC的内容协商机制,通过以下组件实现:
- ContentNegotiationManager: 负责协调整个内容协商过程
- ContentNegotiationStrategy: 定义如何确定客户端请求的媒体类型
- HttpMessageConverter: 负责在Java对象和HTTP请求/响应体之间进行转换
SpringBoot默认支持多种内容协商策略,可以根据需求进行配置和组合。
多端内容适配
基于请求头实现内容协商
基于请求头的内容协商是最符合HTTP规范的一种方式,它通过检查HTTP请求中的Accept
头来确定客户端期望的响应格式。例如,当客户端发送Accept: application/json
头时,服务器会优先返回JSON格式的数据。
这种策略由HeaderContentNegotiationStrategy
实现,是SpringBoot的默认内容协商策略。
- 优先检查请求的
Accept
头 - 其次检查URL路径扩展名(如
.json
) - 默认支持JSON格式(通过Jackson),因为默认的 web 场景导入了 jackson 的相关包
这种行为有很多好处
- 符合HTTP规范,是RESTful API的推荐实践,一般在面向程序化客户端的API接口,当多种客户端需要相同数据的不同表现形式时使用
- 无需修改URL,保持URL的简洁性
- 适用于所有HTTP客户端
- 对缓存友好
在SpringBoot中,默认已启用基于请求头的内容协商,无需额外配置。如果需要显式配置,可以在application.properties
或application.yml
中添加:
1 | # 启用/禁用基于后缀的内容协商 |
或者
1 |
|
基于请求参数的内容协商
基于请求参数的内容协商通过URL查询参数来确定客户端期望的响应格式。例如,/api/products?format=json
请求JSON格式,而/api/products?format=xml
请求XML格式。
- 发送请求
GET/projects/spring-boot?format=json
- 匹配到
@GetMapping("/projects/spring-boot")
- 根据参数协商,优先返回 JSON 类型的数据,需要开启参数匹配设置
这种策略由ParameterContentNegotiationStrategy
实现,需要显式启用。
配置方式如下
1 | spring: |
1 |
|
注意相关实体类添加对应的注解
基于URL路径扩展名实现内容协商
基于URL路径扩展名的内容协商通过URL末尾的文件扩展名来确定客户端期望的响应格式。例如,/api/products.json
请求JSON格式,而/api/products.xml
请求XML格式。
这种策略由PathExtensionContentNegotiationStrategy
实现,需要特别注意的是,从Spring
5.3开始,出于安全考虑,默认已禁用此策略。
由于路径扩展策略可能导致路径遍历攻击,Spring 5.3后默认禁用。如果必须使用,建议做好URL的安全配置
配置方式如下
1 | spring: |
1 |
|
组合策略实现高级内容协商
如何进行策略组合的配置
在实际应用中,通常会组合多种策略实现提供最大的灵活性。可以通过
ContentNegotiationConfigurer
来配置组合策略。
例如如下配置组合了基于请求参数、Accept
请求头和 URL
路径扩展名的内容协商策略,提供了更灵活的内容协商方式。
没错,这个配置类来实现更复杂的配置,是通过实现
WebMvcConfigurer
接口方法实现的
1 | import org.springframework.context.annotation.Configuration; |
自定义内容协商策略
简介
自定义内容协商格式主要涉及到两个方面:一是自定义支持的媒体类型(Media Types),二是自定义对这些媒体类型的处理。
在 Spring Boot 3 中,自定义内容协商格式通常需要以下几个步骤:
- 注册自定义媒体类型:你可以通过配置类来注册自定义的媒体类型,让 Spring MVC 知道你打算支持哪些额外的格式。
- 实现 HttpMessageConverter 接口:对于每种你想支持的媒体类型,你需要提供一个相应的HttpMessageConverter实现,用于序列化和反序列化数据。
- 配置 Spring MVC 以使用你的自定义 HttpMessageConverter:最后,你需要在 Spring MVC 配置中注册你的 HttpMessageConverter 实现,以确保Spring MVC 会使用它们进行请求和响应的处理。
ContentNegotiationConfigurer接口
ContentNegotiationConfigurer
是 Spring
框架中的一个接口,用于自定义内容协商策略,主要通过以下几种方式来实现:
URL参数: 通过 URL 参数来指定响应格式,例如,
?format=json
。Accept头:通过
Accept
请求头来指定希望接收的响应类型,这是HTTP规范推荐的方式。扩展名: 通过 URL 的扩展名来指定响应的格式。例如,
.json
表示希望响应为 JSON 格式,.xml
表示希望响应为 XML 格式。
实现自定义内容协商-以实现 yaml 内容协商为例子
首先是注册自定义媒体类型,假设你想添加对
application/yaml
这种媒体类型的支持,首先需要在配置类中注册这种媒体类型,注意别忘了引入可能需要的依赖,然后接下来,需要创建一个
WebMvcConfigurer
实例,重写其中的configureContentNegotiation
内容,把消息转换器和注册器注册进去,用于处理
YAML 格式的数据。
引入需要的依赖
添加 Jackson 的 YAML 处理模块:
1 | <dependency> |
创建 YAML 消息转换器
实现HttpMessageConverter
接口,用于处理 YAML
格式的数据:
1 | import com.fasterxml.jackson.databind.ObjectMapper; |
配置内容协商策略
注册自定义媒体类型并配置消息转换器:
1 | import org.springframework.context.annotation.Bean; |
创建示例实体类
1 | import com.fasterxml.jackson.annotation.JsonInclude; |
创建 REST 控制器
1 | import org.springframework.web.bind.annotation.*; |
测试
下面通过几种方式测试 YAML 格式的内容协商:
1 | # 请求JSON格式 |
发送 YAML 格式的请求体
1 | curl -X POST -H "Content-Type: application/x-yaml" -d ' |
内容协商原理 -
HttpMessageConverter
基于上述我们的自定义内容协商的内容,我们可以知道,实现自定义内容协商的配置关键在于,编写WebMvcConfigurer
提供的configureMessageConverters
底层,修改底层的MessageConverters
这里就讲一下是如何实现的和其中的实现原理
内容协商的完整流程
当客户端发起请求时,内容协商的执行流程如下:
- 请求到达 DispatcherServlet:Spring MVC 的前端控制器接收请求
- HandlerMapping 确定处理器:找到处理该请求的 Controller 方法
- 内容协商启动:
- 检查请求的
Accept
头(如Accept: application/json
) - 检查 URL 参数(如
?format=json
) - 检查 URL 扩展名(如
.json
)
- 检查请求的
- 选择合适的 Converter:
- 根据协商结果(如 JSON、XML),从
HttpMessageConverter
列表中选择支持该媒体类型的转换器 - 排序规则:优先使用用户自定义的 Converter(通过
extendMessageConverters
添加),再使用默认的
- 根据协商结果(如 JSON、XML),从
- 执行转换:
- 请求处理:读取请求体并转换为 Controller 方法的参数
- 响应处理:将 Controller 返回值序列化为响应格式
核心接口:HttpMessageConverter
在 Spring MVC 中,内容协商是将 HTTP 请求和响应与特定格式(如
JSON、XML、YAML 等)进行匹配的过程。这一过程的核心在于
HttpMessageConverter
接口,它负责处理 HTTP
请求和响应的序列化与反序列化。
HttpMessageConverter
是一个策略接口,负责:
- 读取 HTTP 请求体并将其转换为 Java 对象(反序列化)
- 写入 Java 对象到 HTTP 响应体(序列化)
其核心方法包括:
canRead(Class clazz, MediaType mediaType)
:判断是否能将请求转换为指定类型canWrite(Class clazz, MediaType mediaType)
:判断是否能将对象序列化为指定媒体类型read(Class clazz, HttpInputMessage inputMessage)
:从请求中读取并转换为对象write(T t, MediaType contentType, HttpOutputMessage outputMessage)
:将对象写入响应
内容协商的具体实现
内容协商是确定响应格式的过程,主要由
ContentNegotiationManager
负责:
- 确定客户端期望的媒体类型
- 检查
Accept
请求头 - 检查 URL 参数(如
?format=json
) - 检查 URL 扩展名(如
.json
)
- 检查
- 选择合适的 HttpMessageConverter
- 遍历所有注册的
HttpMessageConverter
- 调用
canWrite()
方法判断转换器是否支持该类型和媒体类型 - 选择第一个匹配的转换器
- 遍历所有注册的
1 | public List<MediaType> resolveMediaTypes(NativeWebRequest request) throws HttpMediaTypeNotAcceptableException { |
@ResponseBody
由 HttpMessgaeConverter
处理
@ResponseBody
注解的作用是:将 Controller
方法的返回值直接写入 HTTP
响应体,而不是转发到视图页面,当方法或类标注了
@ResponseBody
(@RestController
等价于类上标注
@Controller
+ @ResponseBody
)时,Spring MVC
会启用特殊的返回值处理逻辑。
@ResponseBody
注解是内容协商机制的关键触发点:
当 Controller 方法被
@ResponseBody
注解时(或类被@RestController
注解),Spring MVC 会:步骤层次
- 通过内容协商确定响应的媒体类型
- 找到支持该媒体类型的
HttpMessageConverter
- 使用该 Converter 将返回值序列化为响应体
源码层次
请求进来先来到
DispatcherServlet
类中的doDispatch()
方法处理1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// DispatcherServlet.java
// 这里是简化的源码流程
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 1. 找到处理请求的 Handler
// 其实一上来这里是空的,一点点补充的
HandlerExecutionChain mappedHandler = getHandler(request);
// 2. 找到执行 Handler 的 Adapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 执行 Handler
ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 4. 处理返回值
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}找到了一个
HandlerAdapter
适配器,利用适配器执行目标方法RequestMappingHandlerAdapter
来执行,最终会调用invokeHandlerMethod()
来执行目标方法目标方法执行之前,准备好两个东西
HandlerMethodArgumentResolver
:参数解析器,确定目标方法每个参数值HandlerMethodReturnValueHandler
:返回值处理器,确定目标方法的返回值改怎么处理
RequestMappingHandlerAdapter
里面的invokeAndHandle()
真正执行目标方法目标方法执行完成,会返回返回值对象
找到一个合适的返回值处理器
HandlerMethodReturnValueHandler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29// HandlerMethodReturnValueHandlerComposite.java
public void handleReturnValue( Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
// 查找能处理该返回值的处理器
HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
if (handler == null) {
throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
}
// 使用处理器处理返回值
handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
}
private HandlerMethodReturnValueHandler selectHandler( { Object returnValue, MethodParameter returnType)
// 是否是异步返回值
boolean isAsyncValue = isAsyncReturnValue(returnValue, returnType);
for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) {
continue;
}
// 判断处理器是否支持该返回值类型
if (handler.supportsReturnType(returnType)) {
return handler;
}
}
return null;
}最终找到
RequestResponseBodyMethodProcessor
能处理标注了@ResponseBody
注解的方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public void handleReturnValue( Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest)throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
mavContainer.setRequestHandled(true);
ServletServerHttpRequest inputMessage = this.createInputMessage(webRequest);
ServletServerHttpResponse outputMessage = this.createOutputMessage(webRequest);
if (returnValue instanceof ProblemDetail detail) {
outputMessage.setStatusCode(HttpStatusCode.valueOf(detail.getStatus()));
if (detail.getInstance() == null) {
URI path = URI.create(inputMessage.getServletRequest().getRequestURI());
detail.setInstance(path);
}
this.invokeErrorResponseInterceptors(detail, (ErrorResponse)null);
}
this.writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
}RequestResponseBodyMethodProcessor
调用writeWithMessageConverters
,利用MessageConverter
把返回值进行序列化然后写出去
上述的源码内容都在说一个事:
@ResponseBody
由HttpMessgaeConverter
处理的而
HttpMessageConverter
会进行内容协商- 遍历所有的
MessageConverter
,看谁支持这种内容类型的数据 - 默认的
MessageConverter
有以下: - 最终因为要
json,所以
MappingJackson2HttpMessageConverter
支持写出 JSON - Jackson 用
ObjectMapper
把对象写出去
- 遍历所有的
@ResponseBody
与HttpMessageConverter
的协作流程可以概括为:- 请求处理:DispatcherServlet 接收请求并找到处理方法
- 方法执行:HandlerAdapter 执行目标方法
- 返回值处理:通过 HandlerMethodReturnValueHandler 找到 RequestResponseBodyMethodProcessor
- 内容协商:确定响应的媒体类型
- 转换器选择:遍历 HttpMessageConverter 列表,找到第一个支持该类型和媒体类型的转换器
- 序列化输出:使用选定的转换器将返回值序列化为响应体
所以请求处理的整体流程就很清晰了,当客户端发送 HTTP 请求到 Spring MVC 应用时,整个处理流程可以概括为:
- 请求进入 DispatcherServlet:Spring MVC 的前端控制器接收所有请求
- HandlerMapping 确定处理器:找到处理该请求的 Controller 方法
- HandlerAdapter 执行方法:通过适配器执行目标方法
- 返回值处理:将方法返回值转换为 HTTP 响应
- 响应输出:将处理结果返回给客户端
例如
1 |
|
Spring MVC 会根据协商结果选择:
MappingJackson2HttpMessageConverter
处理 JSONJaxb2RootElementHttpMessageConverter
处理 XML- 自定义的
YamlHttpMessageConverter
处理 YAML
WebMvcAutoConfiguration
提供几种默认的HttpMessageConverters
Spring MVC 默认注册了多种
HttpMessageConverter
,按顺序排列如下:
- ByteArrayHttpMessageConverter:处理二进制数据,支持
application/octet-stream
- StringHttpMessageConverter:处理字符串,支持
text/plain
- ResourceHttpMessageConverter:处理资源文件,支持
application/octet-stream
- ResourceRegionHttpMessageConverter:处理部分资源,支持媒体类型范围请求
- SourceHttpMessageConverter:处理 javax.xml.transform.Source,支持 XML
- AllEncompassingFormHttpMessageConverter:处理表单数据,支持
application/x-www-form-urlencoded
- Jaxb2RootElementHttpMessageConverter:处理 JAXB 注解的对象,支持 XML
- MappingJackson2HttpMessageConverter:处理
JSON,支持
application/json
- MappingJackson2XmlHttpMessageConverter:处理
XML,支持
application/xml
- AtomFeedHttpMessageConverter:处理 Atom 格式,支持
application/atom+xml
- RssChannelHttpMessageConverter:处理 RSS 格式,支持
application/rss+xml
注意这里需要添加可能需要的注解才可能在适配器遍历的时候被选中为有效的
而其中,我们可以知道:
- 系统提供的默认的 MessageConverter的功能很有限,仅适用于 json 或者普通的数据返回
- 需要增加额外的内容协商功能,必须添加新的
HttpMessageConverters
自定义 HttpMessageConverter 的优先级
当添加自定义 HttpMessageConverter
时,注册顺序非常重要:
替换默认转换器:
1
2
3
4
5
6
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.clear(); // 移除所有默认转换器
converters.add(new YamlHttpMessageConverter()); // 添加自定义转换器
// 添加其他必要的转换器
}注意:这种方式会完全替换默认转换器,需谨慎使用
扩展默认转换器(推荐方式):
1
2
3
4
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(0, new YamlHttpMessageConverter()); // 添加到列表开头,优先使用
}原理:Spring MVC 按顺序遍历转换器列表,选择第一个支持的转换器
常见的内置 HttpMessageConverter
Spring MVC 默认提供了多种转换器:
转换器 | 支持的媒体类型 | 用途 |
---|---|---|
MappingJackson2HttpMessageConverter | application/json, application/*+json | JSON 处理 |
MappingJackson2XmlHttpMessageConverter | application/xml, text/xml | XML 处理 |
StringHttpMessageConverter | text/plain | 字符串处理 |
FormHttpMessageConverter | application/x-www-form-urlencoded | 表单数据处理 |
ByteArrayHttpMessageConverter | application/octet-stream | 二进制数据处理 |
总结
内容协商是 Spring MVC 处理不同格式数据的核心机制,其关键点在于:
- HttpMessageConverter 是实现格式转换的核心接口
- 内容协商策略决定了如何选择合适的转换器
- 注册顺序影响转换器的优先级
- @ResponseBody 注解触发自动内容协商
通过自定义 HttpMessageConverter
和内容协商策略,可以轻松支持 JSON、XML、YAML 甚至自定义格式,实现灵活的
API 设计。