Spring 3.x JSON status 406“特征根据请求不可接受”accept“headers()”

在使用Spring 3.x试图获得JSON响应的时候,我得到了406 error “这个请求所标识的资源只能根据request生成不可接受的响应,接受”headers()“。

这是我的环境

 * Spring 3.2.0.RELEASE * included jackson-mapper-asl-1.7.9.jar, jackson-core-asl-1.7.9.jar * Tomcat 6.x * mvc:annotation-driven in Spring configuration XML file 

我的控制器:

 @RequestMapping("/contest") public class ContestController { @RequestMapping(value="{name}", headers="Accept=*/*", method = RequestMethod.GET) public @ResponseBody Contest getContestInJSON(@PathVariable String name) { Contest contest = new Contest(); contest.setName(name); contest.setStaffName(new String("contestitem1")); return contest; } } 

我的Springconfiguration文件

 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <context:component-scan base-package="com.contestframework.controllers" /> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="mediaTypes"> <map> <entry key="atom" value="application/atom+xml"/> <entry key="html" value="text/html"/> <entry key="json" value="application/json"/> </map> </property> <property name="viewResolvers"> <list> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> </list> </property> <property name="defaultViews"> <list> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> </list> </property> </bean> <mvc:annotation-driven /> </beans> 

在此之后,我只需使用以下方式访问控制器:

 http://domain/SpringWebProject/json/contest/abcd 

并且我得到的响应是状态406:“由这个请求标识的资源只能根据请求”接受“头()来产生具有不可接受的特征的响应。

我也尝试了使用Javascript AJAX来访问这个替代机制,以确保我的请求头有application/JSON但是这导致了相同的Status 406结果

 $.getJSON('contest/abcd', function(data) { console.log(data) } 

这里是我的请求头从浏览器捕获:

 Request URL:http://localhost:8080/SpringWebProject/json/contest/abcd Request Method:GET Status Code:406 Not Acceptable Accept:application/json, text/javascript, */*; q=0.01 Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8 Connection:keep-alive Cookie:JSESSIONID=59689C95B0B9C21494EB0AB9D9F7BCCD Host:localhost:8080 Referer:http://localhost:8080/SpringWebProject/json/welcome User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4 X-Requested-With:XMLHttpRequest Response Headersview source Content-Length:1070 Content-Type:text/html;charset=utf-8 Date:Fri, 12 Oct 2012 18:23:40 GMT Server:Apache-Coyote/1.1 

感谢在这方面的帮助。

你的configuration没有任何问题,让我build议一些小的修改:

a)你的命名空间出现错误 – 它们指的是3.0模式,只是将它们改为3.1或者不明确引用版本,例如这样。

 xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 

要么

 xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 

b)您不需要ContentNegotiatingViewResolver,您可以从configuration中除去component-scan<mvc:annotation-driven/>的所有内容

c)请求将不会直接从浏览器工作,因为它明确要求“application / json”的Accept头文件 – $.getJson调用应该可以工作,但是它会发送正确的头文件

d)从@RequestMapping中删除headers=Acc.. ,同时产生两个过滤标准,以匹配正确的映射方法调用。

有了这些,没有理由为什么JSON不应该得到服务,你可以请尝试这些,看看它是如何去的。

我也刚刚经历了同样的问题。 这似乎是最新的3.2.0.RELEASE,因为我以前有3.1.2.RELEASE和一切工作的问题。 改成3.2.0.RELEASE之后就中断了。 已经使用3.1.3.RELEASE进行了testing,工作正常。 所以现在我build议回滚到3.1.3.RELEASE

编辑:感谢这个网站上的另一个链接到以下位置的post: http : //static.springsource.org/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-configuration内容协商

我现在通过禁用基于请求path的扩展获取媒体types来工作。 这可以通过以下来完成:

 <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> <!-- Turn off working out content type based on URL file extension, should fall back to looking at the Accept headers --> <property name="favorPathExtension" value="false" /> </bean> 

并为所有xsd模式位置指定版本3.2。

这是使用以下jacksonjar子:

 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.1.2</version> </dependency> 

我有同样的问题,我通过添加以下依赖项解决它

 <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>${jackson.version}</version> </dependency> 

以前我正在做下面的依赖关系

 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${com.jackson.core-version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${com.jackson.core-version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${com.jackson.core-version}</version> </dependency> 

总之,我已经通过org.codehaus.jacksonreplace了com.fasterxml.jackson.core

我在Spring MVC 4中遇到了这个问题。添加jackson-annotations,jackson-core和jackson-databind并没有解决问题。 试试这个库:

 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> 

我想你需要添加一个生产=“应用程序/ JSON”到你的@RequestMapping(有没有看过springMVC,所以我不是100%正面)…

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html

16.3.2.6可生成的媒体types

您可以通过指定可生成媒体types的列表来缩小主映射的范围。 只有Accept请求头匹配其中一个值,请求才会被匹配。 此外,生成条件的使用确保用于生成响应的实际内容types遵守生产条件中指定的媒体types。 例如:

 @Controller @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json") @ResponseBody public Pet getPet(@PathVariable String petId, Model model) { // implementation omitted } 

我有同样的问题,Biju Kunjummen在这个答案中添加的评论完美地为我工作

https://stackoverflow.com/a/12873170/20654

在我的Java类中有公共getter

我有一个类似的问题,当我添加jackson-databind数据库库时,它得到了解决。

这些是我的依赖:

 <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.12</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.4.3</version> </dependency> 

谢谢你分享你的经验。我遇到了同样的问题,它适用于我使用configuration如下所示:

  1. Spring MVC版本:3.2.5.RELEASE
  2. Apache的Tomcat的6.0.24
  3. JDK1.6
  4. jackson核心ASL-1.9.10.jar
  5. jackson映射器-ASL-1.9.10.jar

Spring MVCconfiguration文件:

 <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> <!-- Turn off working out content type based on URL file extension, should fall back to looking at the Accept headers --> <property name="favorPathExtension" value="false" /> </bean> 

模型类:Country.java

  private Integer countryId; private String name; //public setters and getters 

控制器方法:

 @RequestMapping(value = "/get_country_json",method = RequestMethod.GET) @ResponseBody public Country getCountry() 

部署描述符(web.xml)

  <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> 

请求调用控制器方法的URL:/SpringCURDApp/get_country_json.htm

我希望这可以帮助别人。

不要犯同样的错误,花一整天的时间和Springconfiguration一起玩,而实际上你的对象在Web服务中返回时,不是正确的封送到XML中。 看来Spring看到了一个JAXB编组错误,并没有报告它。 使用这个沙盒代码来validationJAXB编组:

 MyClass myclass = new MyClass(); //populate myclass here JAXBContext context = JAXBContext.newInstance(MyClass.class); Marshaller m = context.createMarshaller(); StringWriter w = new StringWriter(); m.marshal(myclass, w); System.out.println(w); 

这产生并显示了一个例外。 修复了原因,我的web服务可用XML和JSON。

不久:

对于Spring MVC 4.1.6有足够的:

 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.0</version> </dependency> 

jackson-databind依赖核心注释工件。


详细信息:

什么是HTTP 406错误?

406不可接受请求的资源只能根据在请求中发送的Accept报头生成不可接受的内容。

这意味着服务器无法生成在Accept Header中声明的媒体types的内容。

但是,服务器如何知道哪个媒体types可以生成,哪些不是?

Spring Web有HttpMessageConverter的概念。 其中一些转换器已经在Spring中注册了, AbstractMessageConverterMethodArgumentResolver将它们保存在属性messageConverters中

在请求处理期间, AbstractMessageConverterMethodProcessor分析哪个spring可以转换并保存所有支持的媒体typesproducibleMediaTypesvariables中。 如果要求媒体types不可生产,然后说错误406 ==我不能生成请求的媒体types。 抱歉。

长话短说 – 注册所需的转换器。 在你的情况下,它是生产应用程序/ JSON的jackson库

请参阅http://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-config-content-negotiation正如你所看到的;

“对于请求URI中的文件扩展名,MVC Javaconfiguration和MVC名称空间,如果存在对应的依赖关系(如Jackson,JAXB2或Rome),则会自动注册扩展名,例如.json,.xml,.rss和.atom类path“。

你应该在URI的末尾添加“.json”(就像http://domain/SpringWebProject/json/contest/abcd.json )它适用于我。

我有类似的问题,但它很奇怪。 我将解释我是如何解决它的。

在我的web.xml中,我的dispacher servlet映射到* .htm

 <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> 

不pipe我做了什么,总是扔 –

这个请求所标识的资源只能根据请求“accept”头来产生具有不可接受的特性的响应

最后我改变了

 <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> 

它的工作。 当你指定的时候,我想是什么

 <mvc:annotation-driven/> 

扩展优先于接受标题和.htm正在创build问题。 显然,我不能使用xml或json,因为servlet本身没有被映射。

我还想补充一下,生成注释,你会popup一个试图映射它将接受传入请求的头文件。 我正在为json和xml制作通用的请求处理程序方法。 由于我使用Java 8,Jaxb自Java 7以来内置于Java中,不需要JAXB依赖。 对于json我只需要添加 –

 <dependency org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.8.5"/> 

我正在使用常春藤进行依赖pipe理。

也许你应该更新你的jackson库。 我使用Spring v4.3.8,我使用它如下:

 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.8.7</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.7</version> </dependency> 

如果你使用Spring 4,那么你只能更新你的库:

  <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.3.0</version> </dependency>