Spring 3.x JSON状态406"根据请求不接受的特性"accept"headers()"

use*_*567 42 spring spring-mvc

在尝试JSON使用我的响应时Spring 3.x,我得到406 error"此请求标识的资源只能生成具有根据request"accept"标题()接受的特性不可接受的响应."

这是我的环境

* 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
Run Code Online (Sandbox Code Playgroud)

我的控制器:

@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;
    }

}
Run Code Online (Sandbox Code Playgroud)

我的Spring配置文件

<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>
Run Code Online (Sandbox Code Playgroud)

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

http://domain/SpringWebProject/json/contest/abcd
Run Code Online (Sandbox Code Playgroud)

我得到的响应是状态406:"此请求标识的资源只能根据请求"accept"headers()生成具有不可接受特征的响应."

我还尝试了一种替代机制,通过访问它Javascript AJAX来确保我的请求标头有,application/JSON但这导致了相同的状态406结果

$.getJSON('contest/abcd', function(data) {
console.log(data) }
Run Code Online (Sandbox Code Playgroud)

这是我从浏览器捕获的REQUEST HEADER:

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
Run Code Online (Sandbox Code Playgroud)

感谢这方面的任何帮助.

ann*_*ate 49

我刚刚遇到过同样的问题.看起来这是最新的3.2.0.RELEASE的一个问题,因为我之前有3.1.2.RELEASE而且一切正常.更改为3.2.0.RELEASE后,它会中断.已经使用3.1.3.RELEASE进行了测试,并且工作正常.所以现在我建议回滚到3.1.3.RELEASE

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

我现在已经通过禁用基于所请求路径的扩展来获取媒体类型来实现它.这可以通过以下方式完成:

<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>
Run Code Online (Sandbox Code Playgroud)

并为所有xsd架构位置指定版本3.2.

这是使用以下杰克逊罐子:

<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>
Run Code Online (Sandbox Code Playgroud)

  • 我的申请就是这种情况.万分感谢!我觉得我需要放弃10次.我一直在寻找这个问题.这就像魔术一样. (8认同)
  • 我的应用程序只需要jackson-databind. (2认同)

Bij*_*men 19

您的配置没有任何问题,但我建议您做一些小改动:

a)您的命名空间显示错误 - 它们指的是3.0模式,只需将它们更改为3.1一个或不明确地引用该版本,这种方式适用于例如.

xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans.xsd
Run Code Online (Sandbox Code Playgroud)

要么

xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
Run Code Online (Sandbox Code Playgroud)

b)你不需要ContentNegotiatingViewResolver,可以去除一切,但component-scan<mvc:annotation-driven/>从配置

c)请求不会直接在浏览器中工作,因为它明确要求"application/json"的Accept标头 - $.getJson调用应该工作,因为它发送正确的标头

d)headers=Acc..从@RequestMapping中删除,并且还生成两者都是过滤条件以匹配正确的映射方法调用.

有了这些,没有理由说json不应该服用,你能不能试试这些,看看它是怎么回事.

  • 您的项目问题实际上非常小 - 您在Contest类中保护了getter,只需将其更改为公共方法,它应该干净利落. (13认同)

小智 11

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

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>${jackson.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

以前我是用以下依赖来做的

<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>
Run Code Online (Sandbox Code Playgroud)

简而言之,我已经用org.codehaus.jackson替换了com.fasterxml.jackson.core


Wes*_*cio 8

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

<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>
Run Code Online (Sandbox Code Playgroud)


les*_*es2 7

我认为你需要在你的@RequestMapping中添加一个produce ="application/json"(暂时没看过spring mvc所以我不是100%正面)...

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

16.3.2.6可生产的媒体类型

您可以通过指定可生成的媒体类型列表来缩小主映射.仅当Accept请求标头与其中一个值匹配时,才会匹配请求.此外,使用生成条件可确保用于生成响应的实际内容类型遵循生成条件中指定的媒体类型.例如:

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


Osc*_*Ryz 7

我有同样的问题,Biju Kunjummen在这个答案中添加的评论对我来说非常有用

/sf/answers/901121931/

那是我的Java类中的公共getter


bur*_*lug 6

我有一个类似的问题,当我添加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>
Run Code Online (Sandbox Code Playgroud)