将
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不可接受.
我设法创建一个简单的控制器与一个URL我无法访问:
@RequestMapping(value = "/resources/foo.js",produces = "text/javascript") @ResponseBody public String foo() throws Exception { return ""; }
当我在Accept-header中使用一个具有* / *的普通浏览器时,我不明白为什么我应该得到一个HTTP 406.这甚至更奇怪的是这个代码正在使用Spring 3.1.2,但不适用于Spring 3.2.这是为什么?
解决方法
已经有了与
Spring does content-negotiations in 3.2有关的几个更改.其中一个更改是现在可以根据URL中的文件后缀完成内容协商.默认情况下启用此功能.在3.2之前的Spring版本中,HTTP accept-header用于内容协商.当浏览器访问您的URL内容时,协商很少出现问题,因为浏览器总是发送Accept:(…)* / *.
Spring有一个后缀地图=>媒体类型.对于“.js”,默认媒体类型为“application / x-javascript”.当Spring尝试查找请求到/resources/foo.js的处理程序映射时,它将不匹配您的foo() – 方法,因为它产生错误的介质类型.
我不知道Spring团队是否想过这个案子.至少有一点奇怪,它允许您创建一个不能被访问的@RequestMapping(由于.js-media类型和在生产字段中设置的不兼容).
有几种方法来解决这个问题.一个是将生成参数更改为“application / x-javascript”.另一个是将“.js”的媒体类型更改为“text / javascript”(see the docs of how to do that).第三种可能性是关闭基于后缀的内容谈判(再次,see the docs of how to do it).