Java HTTP 状态 406。Spring MVC 4.0、jQuery、JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21235472/
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
HTTP Status 406. Spring MVC 4.0, jQuery, JSON
提问by Shatranaft
I want to send JSON from my controller. I have the following configuration.
我想从我的控制器发送 JSON。我有以下配置。
spring-servlet.xml :
弹簧 servlet.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven/>
<mvc:resources mapping="/resources/**" location="/resources/"/>
<context:component-scan base-package="com.castle.controllers"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
.js :
.js :
function testAjax() {
var data = {userName: "MyUsername", password:"Password"};
$.ajax({
url: 'ajax/test.htm',
dataType : 'json',
type : 'POST',
contentType: "application/json",
data: JSON.stringify(data),
success: function(response){
alert('Load was performed.');
}
});
}
UserTest.java:
用户测试.java:
public class UserTest {
private String userName;
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
TestAjaxController.java :
TestAjaxController.java :
@Controller
@RequestMapping("/ajax")
public class TestAjaxController {
@RequestMapping(method = RequestMethod.POST, value = "/test.htm")
public @ResponseBody
UserTest testAjaxRequest(@RequestBody UserTest user) {
return user;
}
}
pom.xml :
pom.xml :
<dependency>
<groupId>org.codehaus.Hymanson</groupId>
<artifactId>Hymanson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.Hymanson</groupId>
<artifactId>Hymanson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
When i do this request, i get in my Controller JSON represented as UserTest object. But on return :
当我执行此请求时,我进入了表示为 UserTest 对象的控制器 JSON。但返回时:
HTTP Status 406 - The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
HTTP 状态 406 - 此请求标识的资源只能生成具有根据请求“接受”标头不可接受的特征的响应。
What i'm doing wrong? I know, there is a lot of questions about such cases, but i can't fix it for 2 days...
我在做什么错?我知道,关于这种情况有很多问题,但我不能解决它2天......
UPDATEI Have found the solution!!
It's only need to return an Object. Not a User object or something.
But
return Object;
更新我找到了解决方案!!只需要返回一个对象。不是 User 对象什么的。但
return Object;
public @ResponseBody Object testAjaxRequest(@RequestBody UserTest user) {
List<UserTest> list = new ArrayList<>();
list.add(user);
list.add(user);
list.add(user);
return list;
采纳答案by Sotirios Delimanolis
The main issue here is that the path "/test.htm"
is going to use content negotiation first before checking the value of an Accept
header. With an extension like *.htm
, Spring will use a org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy
and resolve that the acceptable media type to return is text/html
which does not match what MappingHymansonHttpMessageConverter
produces, ie. application/json
and therefore a 406 is returned.
这里的主要问题是路径"/test.htm"
将在检查Accept
标头值之前首先使用内容协商。对于像 那样的扩展*.htm
,Spring 将使用 aorg.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy
并解决返回的可接受媒体类型text/html
与MappingHymansonHttpMessageConverter
产生的内容不匹配的问题,即。application/json
因此返回 406。
The simple solution is to change the path to something like /test
, in which content negotiation based on the path won't resolve any content type for the response. Instead, a different ContentNegotiationStrategy
based on headers will resolve the value of the Accept
header.
简单的解决方案是将路径更改为类似/test
,其中基于路径的内容协商不会解析响应的任何内容类型。相反,ContentNegotiationStrategy
基于标头的不同将解析标头的值Accept
。
The complicated solution is to change the order of the ContentNegotiationStrategy
objects registered with the RequestResponseBodyMethodProcessor
which handles your @ResponseBody
.
复杂的解决方案是更改ContentNegotiationStrategy
使用RequestResponseBodyMethodProcessor
处理您的@ResponseBody
.
回答by Marty
Make sure to use produces = "application/json" in your annotations.
确保在注释中使用 products = "application/json"。
回答by zjor
Adding these lines to context configuration solved the same issue for me:
将这些行添加到上下文配置中为我解决了同样的问题:
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingHymanson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
I used Spring 4.1.x
and Hymanson 2.4.2
我用过Spring 4.1.x
和Hymanson 2.4.2
回答by ramird23
I had the same problem in the end it was the version of org.codehaus.Hymanson 1.9.x, when I switched from 1.9.x Hymanson to 2.x (fasterxml) in my pom.xml
我最终遇到了同样的问题,它是 org.codehaus.Hymanson 1.9.x 的版本,当我在 pom.xml 中从 1.9.x Hymanson 切换到 2.x(fasterxml)时
<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>
also is necesary : <mvc:annotation-driven />
也有必要: <mvc:annotation-driven />
回答by jlaitio
I ran into this issue when upgrading Spring in a legacy project. The .html
suffix of the AJAX endpoints (which were trying to return JSON) were indeed forcibly made to try to produce HTML due to the suffix, and since the handlers were returning an object, the request ended in a 406 error since Spring couldn't figure out how to make HTML out of a plain Java object.
我在旧项目中升级 Spring 时遇到了这个问题。.html
AJAX 端点的后缀(试图返回 JSON)确实由于后缀而被强制尝试生成 HTML,并且由于处理程序正在返回一个对象,因此请求以 406 错误结束,因为 Spring 无法计算了解如何从一个普通的 Java 对象中生成 HTML。
Instead of altering the endpoint suffixes, or doing a complete configuration of a custom ContentNegotiationStrategy
, making this change was enough:
无需更改端点后缀或对 customContentNegotiationStrategy
进行完整配置,只需进行此更改即可:
<mvc:annotation-driven />
changed to:
变成:
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
</bean>
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>