我想从控制器发送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-此请求标识的资源仅能够生成具有根据请求“接受”标头不可接受的特征的响应。
我做错了什么?我知道,关于此类情况有很多问题,但我无法在两天内解决…
更新 我已经找到了解决方案!只需要返回一个对象。不是用户对象或其他东西。但 return 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;
这里的主要问题是,"/test.htm"在检查Accept标头的值之前,路径将首先使用内容协商。使用扩展名*.htm,Spring将使用org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy和来确定要返回的可接受的媒体类型text/html与MappingJacksonHttpMessageConverter产生的媒体类型不匹配,即。application/json因此返回406。
"/test.htm"
Accept
*.htm
org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy
text/html
MappingJacksonHttpMessageConverter
application/json
一种简单的解决方案是将路径更改为,类似于/test,其中基于该路径的内容协商不会解析响应的任何内容类型。相反,ContentNegotiationStrategy基于标头的其他内容将解析标头的值Accept。
/test
ContentNegotiationStrategy
复杂的解决方案是更改处理的ContentNegotiationStrategy对象在上注册的对象的顺序。RequestResponseBodyMethodProcessor``@ResponseBody
RequestResponseBodyMethodProcessor``@ResponseBody