我正在尝试使用 Spring MVC 3.2 编写一个使用/生成 JSON 和 HTML 的控制器。我有两个产生不同内容类型的处理程序方法:
@Controller
public class FooController {
@RequestMapping(value="/foo", produces="text/html")
public String fooHTML() {
// ...
}
@RequestMapping(value="/foo", produces="application/json")
public String fooJSON() {
// ...
}
}
如果Accept
来自客户端的标头包含text/html
or application/json
,这将非常有效
...但后来出现了 Internet Explorer。如此处所述,IE 的Accept
标头各不相同,但它从不包含text/html
并且始终*/*
位于末尾。当 Spring 收到来自 IE 的请求时,它看不到与我的控制器生成的内容类型直接相等的内容类型,但是,锁定*/*
通配符,它(正确地)决定两种映射都适用。
面对多个匹配的处理程序映射,Spring(在 RequestMappingHandlerMapping bean 中)按照字典顺序对映射进行排序,选择第一个,然后继续。从我的角度来看,问题在于这个过程优先application/json
于text/html
. 除非客户端特别请求,否则我宁愿返回text/html
application/json
——这样,我可以将 HTML 提供给 IE 等愚蠢的客户端,将 JSON 提供给我的 API 用户等精通内容类型的客户端。
有谁知道不需要扩展 RequestMappingHandlerMapping 来对处理程序进行不同排序的方法?你有什么简单的解决方法吗?
注意:我尝试在 ContentNegotiationManager 中设置默认内容类型,如Spring blog中所述。它不能解决我的问题,因为该设置仅在未指定 Accept 标头时生效。