Spring MVC 通过内容协商机制自动根据 Accept 请求头选择 JSON 或 XML 等响应格式,依赖 ContentNegotiationManager 和 HttpMessageConverter,需配置 Jackson 依赖、禁用 ignoreAcceptHeader 并避免 produces 硬编码。

Spring MVC 通过内容协商(Content Negotiation)机制,自动根据客户端请求头中的 Accept 字段选择返回 JSON、XML 或其他格式的数据。这个过程不需要手动判断或分支编码,而是由框架内部的 ContentNegotiationManager 和 HttpMessageConverter 协同完成。
核心原理是自动匹配媒体类型
当客户端发起请求时,比如用 Postman 设置 Accept: application/json,Spring MVC 会解析该头,确定目标媒体类型为 application/json;接着查找能处理该类型的 HttpMessageConverter(如 MappingJackson2HttpMessageConverter),再将 Controller 返回的 Java 对象序列化为 JSON 响应体。
关键前提是:
- 方法上标注了
@ResponseBody或类上用了@RestController - 项目中已引入对应的消息转换器依赖(如 Jackson 处理 JSON,Jackson XML 处理 XML)
- Spring Boot 默认启用基于请求头的内容协商策略(
HeaderContentNegotiationStrategy)
需要确保的三项配置
-
引入必要依赖
立即学习“Java免费学习笔记(深入)”;
- JSON 支持:
spring-boot-starter-web默认包含 Jackson - XML 支持:额外添加
jackson-dataformat-xml<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency>
- JSON 支持:
-
确认 Accept 头未被忽略
默认行为是尊重Accept头。若在配置中误设ignoreAcceptHeader: true,协商将失效。建议显式关闭忽略:spring: mvc: contentnegotiation: ignore-accept-header: false -
Controller 方法不锁定 produces 类型
避免在@GetMapping中写死produces = "application/json",否则会强制只返回 JSON,绕过协商。保持方法开放,让框架按需选择:@GetMapping("/users/{id}") public User getUser(@PathVariable Long id) { return userService.findById(id); }
实际请求示例与响应效果
| 客户端请求方式 |
Accept 头值 |
Spring MVC 响应格式 |
|---|---|---|
| 浏览器直接访问 | text/html,application/xhtml+xml,... |
默认 fallback 到 JSON(因无 HTML 视图) |
curl -H "Accept: application/json" /api/users/1 |
application/json |
返回 JSON(如 {"id":1,"name":"张三"}) |
curl -H "Accept: application/xml" /api/users/1 |
application/xml |
返回 XML(如 <user><id>1</id><name>张三</name></user>) |
curl -H "Accept: application/json, application/xml;q=0.9" /api/users/1 |
权重优先 JSON | 仍返回 JSON |
只要 User 类有标准 getter、且 XML 转换器可用,无需额外代码即可支持多格式。
不复杂但容易忽略


















