从Spring 3.2+开始,在eval
Accept标头之前,内容协商还需要考虑其他因素:
从https://spring.io/blog/2013/05/11/content-negotiation-using-spring-
mvc:
在Spring MVC中启用内容协商
Spring支持几种用于选择所需格式的约定:URL后缀和/或URL参数。这些与使用Accept标头一起工作。结果,可以以三种方式中的任何一种来请求内容类型。默认情况下,将按以下顺序检查它们:
*在URL中添加路径扩展名(后缀)。因此,如果传入的URL是类似http://myserver/myapp/accounts/list.html的内容,则需要HTML。对于电子表格,URL应该为
http://myserver/myapp/accounts/list.xls。后缀到媒体类型的映射是通过JavaBeans激活框架或JAF自动定义的(因此,activation.jar必须在类路径上)。
* 像这样的URL参数:http:// myserver / myapp / accounts / list?format =
xls。参数的名称默认为格式,但是可以更改。默认情况下,禁用参数使用,但启用后将对其进行第二次检查。
- 最后,检查“接受HTTP标头”属性。这实际上是HTTP定义为工作的方式,但是,如前所述,使用它可能会出现问题。
这实际上意味着,如果您映射
@Controller带有
.htm(l)后缀的方法,则即使您发送其他格式作为标头,它也将返回
html并且不会返回
json任何其他格式
Accept。
我
.htm一直将控制器映射为,并且
@ResponseBody当我升级到Spring 3.2和更高版本时,必须更改用于映射带注释的方法的方式。
编辑: 按照我的预期,在看到您的web.xml之后,您正在将每个.html后缀请求映射到调度程序servlet:
`<servlet-mapping> <servlet-name>springDispatcher</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping>`
我认为现在
@RequestMapping控制器中的就像这样:
@RequestMapping(value="/test", method=RequestMethod.GET, produces="application/json")public @ResponseBody List<ModelVechicle> fetchListModelById(@RequestParam Integer number) {由于
/test不匹配
.html后缀,请求没有到达springDispatcher,这就是为什么您得到404的原因。
现在,解决此问题的选项:
1)在web.xml中添加一个与此控制器匹配的新映射:
<servlet-mapping> <servlet-name>springDispatcher</servlet-name> <url-pattern>*.html</url-pattern> <url-pattern>*/test</url-pattern></servlet-mapping>
这样,您将被迫包括任何新的非html返回方法。对我来说似乎不可用。
2)将所有传入请求映射到dispatcherServlet
<servlet-mapping> <servlet-name>springDispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
我不太喜欢这个选项,我更喜欢过滤我真正想要到达的分派器servlet的内容。
3)为这种请求找到新的匹配模式。我总是发布某种通用后缀,而JAF不会捕获它,例如* .service:
<servlet-mapping> <servlet-name>springDispatcher</servlet-name> <url-pattern>*.html</url-pattern> <url-pattern>*.service</url-pattern> </servlet-mapping>
因此,在返回XML或JSON(或仅取决于
Accept标题的任何其他格式)的Controller方法中,我这样映射:
@RequestMapping(value="/test.service", method=RequestMethod.GET, produces="application/json")public @ResponseBody List<ModelVechicle> fetchListModelById(@RequestParam Integer number) {4)您还可以使用’
http://com.xxx.yyy/myApp/service/resource
‘模式发布所有此类@ResponseBody控制器方法,并
/service/在web.xml中用作servlet映射
<servlet-mapping> <servlet-name>springDispatcher</servlet-name> <url-pattern>*.html</url-pattern> <url-pattern>/service/</url-pattern> </servlet-mapping>



