我想从我的控制器发送JSON。我有以下配置。
spring-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:
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:
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:
@Controller
@RequestMapping("/ajax")
public class TestAjaxController {
@RequestMapping(method = RequestMethod.POST, value = "/test.htm")
public @ResponseBody
UserTest testAjaxRequest(@RequestBody UserTest user) {
return user;
}
}
pom.xml:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
当我执行此请求时,我会使用表示为UserTest对象的Controller JSON。但回来时:
HTTP状态406 - 此请求标识的资源只能根据请求“accept”标头生成具有不可接受特征的响应。
我做错了什么?我知道,有很多关于此类案件的问题,但我无法解决它2天......
更新
我找到了解决方案!!
它只需要返回一个Object。不是用户对象或其他东西。
但
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;
答案 0 :(得分:20)
这里的主要问题是路径"/test.htm"
将在检查Accept
标头的值之前首先使用内容协商。使用类似*.htm
的扩展名,Spring将使用org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy
并确定要返回的可接受媒体类型是text/html
,这与MappingJacksonHttpMessageConverter
生成的不匹配,即。 application/json
因此返回406。
简单的解决方案是将路径更改为/test
,其中基于路径的内容协商不会解析响应的任何内容类型。相反,基于标头的不同ContentNegotiationStrategy
将解析Accept
标头的值。
复杂的解决方案是更改使用ContentNegotiationStrategy
注册的RequestResponseBodyMethodProcessor
对象的顺序,该@ResponseBody
处理您的{{1}}。
答案 1 :(得分:1)
我最后遇到的问题是org.codehaus.jackson 1.9.x的版本, 当我在我的pom.xml中从1.9.x jackson切换到2.x(fasterxml)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
也是必要的:<mvc:annotation-driven />
答案 2 :(得分:1)
在遗留项目中升级Spring时遇到了这个问题。由于后缀,AJAX端点的.html
后缀(试图返回JSON)确实被强制用于尝试生成HTML,并且由于处理程序返回了一个对象,因此请求以406错误结束Spring无法弄清楚如何用普通的Java对象制作HTML。
不是更改端点后缀,也不是对自定义ContentNegotiationStrategy
进行完整配置,而是进行此更改就足够了:
<mvc:annotation-driven />
更改为:
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
</bean>
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
答案 3 :(得分:0)
将这些行添加到上下文配置为我解决了同样的问题:
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
我使用了Spring 4.1.x
和Jackson 2.4.2
答案 4 :(得分:-2)
确保在注释中使用produce =“application / json”。