升级到Spring 3.2后的HttpMediaTypeNotAcceptableException
问题内容:
将我的Spring MVC应用程序升级到Spring 3.2之后,访问某些URL时出现以下异常:
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:203) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:272) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:212) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:55) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:297) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1091) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1076) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:896) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915) [spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
(...)
此异常导致HTTP 406 NOT ACCEPTABLE。
我设法用无法访问的URL创建了一个简化的控制器:
@RequestMapping(value = "/resources/foo.js", produces = "text/javascript")
@ResponseBody
public String foo() throws Exception {
return "";
}
由于我使用的是其中有一个正常的浏览器*/*
在Accept
-header,我不明白为什么我应该得到一个HTTP
406是什么让这个更奇怪的是,这个代码工作与Spring 3.1.2,但与春3.2。这是为什么?
问题答案:
有关Spring在3.2中进行内容协商的方式,已经进行了一些更改。这些更改之一是,现在可以基于URL中的文件后缀进行内容协商。默认情况下启用此功能。在3.2之前的Spring版本中,HTTP
accept-header用于内容协商。当浏览器访问您的URL时,内容浏览器很少会出现问题,因为浏览器总是发送Accept:(...)*/*
。
Spring具有一个后缀=> Media type的映射。对于“ .js”,默认媒体类型为“ application /
x-javascript”。当Spring尝试查找对/resources/foo.js的请求的处理程序映射时,它与您的foo()
-method
不匹配,因为它会生成错误的媒体类型。
我不确定Spring团队是否考虑过此案。至少让您创建一个@RequestMapping
无法访问的对象是有点奇怪(因为.js-
media类型与Produces字段中设置的内容不兼容)。
有几种解决此问题的方法。一种是将生产参数更改为“ application / x-javascript”。另一个方法是将“ .js”的媒体类型更改为“
text / javascript”(请参阅有关方法的文档)。第三种可能性是关闭基于后缀的内容协商(同样,请参见有关如何做的文档)。