Skip to content

HTTP 消息转换 (HTTP Message Conversion)

spring-web 模块包含 HttpMessageConverter 接口,用于通过 InputStreamOutputStream 读取和写入 HTTP 请求与响应的主体。

HttpMessageConverter 在客户端(如 RestClient)和服务器端(如 Spring MVC 的 REST 控制器)都被广泛使用。

常用实现类

框架提供了主流媒体类型(MIME Types)的具体实现:

实现类媒体类型 (Media Type)说明
StringHttpMessageConvertertext/*读取和写入字符串。默认编码通常为 UTF-8
JacksonJsonHttpMessageConverterapplication/json使用 Jackson 的 JsonMapper 进行 JSON 的读写。
FormHttpMessageConverterapplication/x-www-form-urlencoded读写表单数据,映射到 MultiValueMap<String, String>
ByteArrayHttpMessageConverter*/*读写字节数组。写入时默认为 application/octet-stream
JacksonXmlHttpMessageConverterapplication/xml使用 Jackson 的 XML 扩展进行 XML 读写。
ProtobufHttpMessageConverterapplication/x-protobuf读写 Google Protobuf 二进制格式数据。

内容协商

在服务器端,Spring MVC 会根据以下因素决定使用哪个转换器:

  1. 请求的 Accept 标头:客户端想要什么格式?
  2. 请求的 Content-Type 标头:客户端发来的是什么格式?
  3. Controller 方法的返回类型

补充教学

1. 魔法的源头:@ResponseBody 与 @RequestBody

当你给方法加上 @ResponseBody 时,Spring 不再通过 ViewResolver 找页面,而是把返回值丢给 HttpMessageConverter 链。

  • 策略模式:Spring 会遍历所有已注册的转换器,调用它们的 canWrite 方法。第一个说“我能处理这个类型”的转换器将负责把结果写回浏览器。

2. 为什么我的 JSON 字段名变了?

通常是因为 Jackson 的默认行为。

  • 技巧 1:使用 @JsonProperty("user_name") 显式指定字段名。
  • 技巧 2:在全局配置中修改命名策略(如驼峰转下划线):
    properties
    spring.jackson.property-naming-strategy=SNAKE_CASE

3. 如何解决 StringHttpMessageConverter 的中文乱码?

早期版本中,该转换器默认使用 ISO-8859-1,导致中文乱码。 现代方案:在 Spring Boot 3+ 中,默认已统一为 UTF-8。如果你还在使用旧版本,可以通过配置自定义 Bean 或修改属性来解决:

properties
server.servlet.encoding.force=true
server.servlet.encoding.charset=UTF-8

4. 常见的 415 Unsupported Media Type 错误

当你看到这个报错时,通常意味着:

  • 你发送的是 JSON,但忘记在 Header 里加 Content-Type: application/json
  • 或者你的后端没引入 jackson-databind 依赖,导致 Spring 找不到能处理 JSON 的转换器。

Based on Spring Framework.