Spring MVC 内容协商策略
# Spring MVC 内容协商策略
前言
内容协商策略(Content Negotiation)允许客户端和服务器就响应的媒体类型(Media Type)达成一致。它对于 RESTful Web 服务非常重要,因为相同的 API 接口可能需要支持多种格式的响应数据,如 JSON、XML、HTML 等。通过配置 ContentNegotiationConfigurer
,你可以自定义内容协商的行为,以适应不同的业务需求。
# 1. 配置内容协商策略
在 Spring MVC 中,通过实现 WebMvcConfigurer
接口并重写 configureContentNegotiation
方法,可以自定义内容协商策略。
@Configuration // 标记为配置类
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// 启用 URL 后缀内容协商,例如 /data.json 返回 JSON
configurer.favorPathExtension(true)
// 忽略请求头中的 Accept 参数,优先使用 URL 或请求参数决定响应格式
.ignoreAcceptHeader(true)
// 启用基于请求参数的内容协商,例如 /data?format=json 返回 JSON
.favorParameter(true)
.parameterName("format") // 定义请求参数的名称,如 format=json
// 仅使用已注册的扩展名进行内容协商
.useRegisteredExtensionsOnly(true)
// 设置默认的媒体类型,如果未指定格式则返回 JSON
.defaultContentType(MediaType.APPLICATION_JSON)
// 注册扩展名与媒体类型的映射关系
.mediaType("json", MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2. 关键配置参数详解
favorPathExtension(true)
:启用基于 URL 后缀的内容协商。例如,访问/data.json
会返回 JSON 数据,而访问/data.xml
会返回 XML 数据。- 默认值:
true
- 注意:该配置可能会引发安全问题,建议只在明确需求时启用。
- 默认值:
ignoreAcceptHeader(true)
:忽略请求头中的Accept
参数,优先使用 URL 后缀或请求参数决定响应格式。- 默认值:
false
- 使用场景:当希望客户端通过 URL 或请求参数而非请求头来控制响应格式时使用。
- 默认值:
favorParameter(true)
:启用基于请求参数的内容协商。例如,访问/data?format=json
会返回 JSON 数据。- 默认值:
false
- 参数名称设置:通过
parameterName("format")
设置请求参数的名称。
- 默认值:
useRegisteredExtensionsOnly(true)
:只允许使用已注册的扩展名进行内容协商,防止未注册的扩展名造成歧义或安全隐患。- 默认值:
false
- 默认值:
defaultContentType(MediaType.APPLICATION_JSON)
:设置默认的媒体类型,当请求未指定格式时使用。- 使用场景:确保未明确指定格式的请求有合理的默认响应格式。
mediaType("json", MediaType.APPLICATION_JSON)
和mediaType("xml", MediaType.APPLICATION_XML)
:定义扩展名与媒体类型的映射关系,告诉 Spring MVC 如何根据请求的扩展名决定响应格式。
# 3. 内容协商策略的应用示例
创建一个简单的控制器来演示内容协商策略的效果:
@RestController // 标记为 REST 控制器,自动返回 JSON 或 XML
public class ContentNegotiationController {
@GetMapping("/sample")
public ResponseEntity<Map<String, String>> getSampleData() {
// 创建返回数据
Map<String, String> response = new HashMap<>();
response.put("message", "This is a sample response");
response.put("status", "success");
// 根据内容协商策略返回不同格式的数据
return ResponseEntity.ok(response);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4. 测试内容协商策略
启动 Spring Boot 应用后,通过以下不同方式请求 /sample
路径:
通过 URL 后缀请求 JSON:访问
http://localhost:8080/sample.json
,应该返回 JSON 格式的响应。通过 URL 后缀请求 XML:访问
http://localhost:8080/sample.xml
,应该返回 XML 格式的响应。通过请求参数请求 JSON:访问
http://localhost:8080/sample?format=json
,应该返回 JSON 格式的响应。通过请求参数请求 XML:访问
http://localhost:8080/sample?format=xml
,应该返回 XML 格式的响应。默认返回格式(未指定格式时):访问
http://localhost:8080/sample
,应该返回默认的 JSON 格式响应。
# 5. 注意事项
- 依赖配置:如果你需要支持 XML 格式的响应,确保项目中包含适当的 XML 解析库,例如 Jackson XML 扩展或 JAXB。
- 安全考虑:启用
favorPathExtension(true)
时,要小心处理 URL 扩展名带来的潜在安全问题,建议结合业务需求合理配置。
总结
- 内容协商策略允许灵活地控制 API 响应的格式,支持基于 URL 后缀、请求参数和请求头的内容协商。
- 使用
WebMvcConfigurer
实现自定义内容协商策略时,需要特别注意各配置参数的默认值及其作用,确保策略与业务需求一致。 - 在实际开发中,推荐启用请求参数或请求头的内容协商,避免因 URL 后缀匹配带来的安全问题。