Java Spring MVC + JSON = 406 不可接受

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16335591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:23:06  来源:igfitidea点击:

Spring MVC + JSON = 406 Not Acceptable

javajsonspring

提问by Mateusz

I'm trying to generate a simple JSON response working. Right now I get 406 Not Acceptable error. Tomcat says "The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers." even though my Acceptheaders are

我正在尝试生成一个简单的 JSON 响应。现在我收到 406 Not Acceptable 错误。Tomcat 说“此请求标识的资源只能生成具有根据请求“接受”标头不可接受的特征的响应。即使我的Accept标题是

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

In tomcat/lib I have all Tomcat jars, Spring jars and Hymanson-all-1.9.0.jar. I'm using Spring 3.2.2 with Tomcat 7.

在 tomcat/lib 中,我有所有 Tomcat jar、Spring jar 和 Hymanson-all-1.9.0.jar。我在 Tomcat 7 中使用 Spring 3.2.2。

I'm aware that this issue has been discussed many times, but none of solutions is working for me.

我知道这个问题已经讨论过很多次了,但没有一个解决方案对我有用。

web.xml

网页.xml

<web-app id="WebApp_ID" version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <display-name>Spring Web MVC Application</display-name>

  <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>

</web-app>

dispatcher-servlet.xml

调度程序-servlet.xml

<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-2.5.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">

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
 <context:component-scan base-package="com.smiechmateusz.controller" />
 <context:annotation-config />

    <mvc:annotation-driven />

</beans>

HelloWorldController.java

HelloWorldController.java

package com.smiechmateusz.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import com.smiechmateusz.dao.Foo;

@Controller
@RequestMapping("/")
public class HelloWorldController extends AbstractController{

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
        HttpServletResponse response) throws Exception {

        ModelAndView model = new ModelAndView("HelloWorldPage");
        return model;
    }

    @RequestMapping(value="foobar.htm", method = RequestMethod.GET)
    public @ResponseBody Foo getShopInJSON() {
        Foo f = new Foo();
        f.setX(1);
        f.setY(2);
        f.setDescription("desc");
        return f;
    }
}

Foo.java

文件

package com.smiechmateusz.dao;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="foobaz")
public class Foo implements Serializable
{
    private int x, y;
    String description;
    int id;

    @Column(name = "x")
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    @Column(name = "y")
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    @Column(name = "description")
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    @Id @GeneratedValue
    @Column(name = "id")
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
}

I've already tried adding

我已经尝试添加

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingHymansonHttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
          <list>
            <ref bean="jsonConverter"/>
          </list>
    </property>
</bean>

to my dispatcher-servlet.xmlor changing jakcson-allto Hymanson-asland Hymanson-core-aslbut output was the same.

到我的dispatcher-servlet.xml或将jakcson-all更改为Hymanson-aslHymanson-core-asl但输出是相同的。

采纳答案by Sean Patrick Floyd

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8

接受:text / html的,应用/ XHTML + xml的,应用/ XML; Q = 0.9,/Q = 0.8

That should be the problem. JSON is served as application/json. If you set the Accept header accordingly, you should get the proper response. (There are browser plugins that let you set headers, I like "Poster" for Firefox best)

那应该是问题所在。JSON 作为application/json. 如果您相应地设置 Accept 标头,您应该会得到正确的响应。(有些浏览器插件可以让你设置标题,我最喜欢 Firefox 的“海报”)

回答by alain.janinm

You have to register the annotation binding for Hymanson in your spring-mvc-config.xml, for example :

您必须在 spring-mvc-config.xml 中为 Hymanson 注册注解绑定,例如:

<!-- activates annotation driven binding -->
<mvc:annotation-driven ignoreDefaultModelOnRedirect="true" validator="validator">
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.json.MappingHymansonHttpMessageConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven>

Then in your controller you can use :

然后在您的控制器中,您可以使用:

@RequestMapping(value = "/your_url", method = RequestMethod.GET, produces = "application/json")
@ResponseBody

回答by KSev

If you're using Maven and the latest Hymanson codethen you can remove all the Hymanson-specific configuration from your spring configuration XML files (you'll still need an annotation-driven tag <mvc:annotation-driven/>) and simply add some Hymanson dependencies to your pom.xml file. See below for an example of the dependencies. This worked for me and I'm using:

如果您使用的是 Maven 和最新的Hymanson 代码,那么您可以从 Spring 配置 XML 文件中删除所有特定于 Hymanson 的配置(您仍然需要一个注释驱动的标签 <mvc:annotation-driven/>)并简单地添加pom.xml 文件的一些 Hymanson 依赖项。有关依赖项的示例,请参见下文。这对我有用,我正在使用:

  • Apache Maven 3.0.4 (r1232337; 2012-01-17 01:44:56-0700)
  • org.springframework version 3.1.2.RELEASE
  • spring-security version 3.1.0.RELEASE.

    ...<dependencies>
    ...
        <dependency>
            <groupId>com.fasterxml.Hymanson.core</groupId>
            <artifactId>Hymanson-core</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.Hymanson.core</groupId>
            <artifactId>Hymanson-databind</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.Hymanson.core</groupId>
            <artifactId>Hymanson-annotations</artifactId>
            <version>2.2.3</version>
        </dependency>
        ...
    </dependencies>...
    
  • Apache Maven 3.0.4 (r1232337; 2012-01-17 01:44:56-0700)
  • org.springframework 版本 3.1.2.RELEASE
  • spring-security 版本 3.1.0.RELEASE。

    ...<dependencies>
    ...
        <dependency>
            <groupId>com.fasterxml.Hymanson.core</groupId>
            <artifactId>Hymanson-core</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.Hymanson.core</groupId>
            <artifactId>Hymanson-databind</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.Hymanson.core</groupId>
            <artifactId>Hymanson-annotations</artifactId>
            <version>2.2.3</version>
        </dependency>
        ...
    </dependencies>...
    

回答by Doo Dah

One more way you can get this error is to create a class with no public members. 406 unacceptable is a pretty useless error message in this scenario.

获得此错误的另一种方法是创建一个没有公共成员的类。在这种情况下,406 unacceptable 是一个非常无用的错误消息。

回答by Demwis

I suppose, that the problem was in usage of *.htmextension in RequestMapping (foobar.htm). Try to change it to footer.jsonor something else.

我想,问题是在 RequestMapping ( foob​​ar.htm)中使用*.htm扩展名。尝试将其更改为footer.json或其他内容。

The link to the correct answer: https://stackoverflow.com/a/21236862/537246

正确答案的链接:https: //stackoverflow.com/a/21236862/537246

P.S.

聚苯乙烯

It is in manner of Spring to do something by default, concerning, that developers know whole API of Spring from A to Z. And then just "406 not acceptable" without any details, and Tomcat's logs are empty!

默认情况下,Spring 会做一些事情,开发人员从 A 到 Z 了解 Spring 的整个 API。然后只是“406 不可接受”,没有任何细节,Tomcat 的日志是空的!

回答by Balaji Katika

It looks like your are trying to produce/recieve json output. I see two problems with your approach. 1) You didn't specify the application/json in your Accept header 2) You need to specify produces="application/json" in your @RequestMapping

看起来您正在尝试生成/接收 json 输出。我发现你的方法有两个问题。1) 您没有在 Accept 标头中指定 application/json 2) 您需要在 @RequestMapping 中指定 products="application/json"

回答by The Java Guy

There is another case where this status will be returned: if the Hymanson mapper cannot figure out how to serialize your bean. For example, if you have two accessor methods for the same boolean property, isFoo()and getFoo().

还有另一种情况会返回此状态:如果 Hymanson 映射器无法弄清楚如何序列化您的 bean。例如,如果您对同一个布尔属性有两个访问器方法,isFoo()并且getFoo().

removed getFoo()and put isFoo(). it worked for me.

删除getFoo()并放置isFoo()。它对我有用。

回答by Shubham

Try adding

尝试添加

@RequestMapping(method = RequestMethod.GET,headers = {"Accept=text/xml, application/json"})

on getShopInJSON().

getShopInJSON()

It worked for me.

它对我有用。

回答by Nguyen Viet

With Spring 4 you only add @EnableWebMvc, for example:

使用 Spring 4,您只需添加@EnableWebMvc,例如:

@Controller
@EnableWebMvc
@RequestMapping(value = "/articles/action", headers="Accept=*/*",  produces="application/json")
public class ArticlesController {

}

回答by jwv

I couldn't see it as an answer here so I thought I would mention that I recieved this error using spring 4.2 when I accidentally removed the getter/setter for the class I was expecting to be returned as Json.

我无法将其视为此处的答案,所以我想我会提到当我不小心删除了我期望作为 Json 返回的类的 getter/setter 时,我使用 spring 4.2 收到了这个错误。