HTTP status 406. Spring MVC 4.0, jQuery, JSON

I want to send JSON from my controller. I have the following configuration.

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> 

When I make this request, I get in my JSON controller presented as a UserTest object. But on return:

HTTP Status 406 - The resource identified by this request is capable of generating responses with characteristics that are not valid according to the headers of the accept request.

What am I doing wrong? I know there are many questions about such cases, but I can’t fix this in 2 days ...

UPDATE I found a solution! He needs to return the object. Not a user object or anything else. But 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; 
+4
java json jquery spring spring-mvc
Jan 20 '14 at 13:34
source share
5 answers

The main problem here is that the path "/test.htm" will use content negotiation first before checking the value of the Accept header. With an extension of type *.htm Spring will use org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy and decide that an acceptable media type is returned text/html , which does not match what MappingJacksonHttpMessageConverter creates, i.e. application/json and therefore 406 is returned.

A simple solution is to change the path to something like /test , in which path-based content negotiation will not allow any type of content to respond. Instead, another ContentNegotiationStrategy -based ContentNegotiationStrategy allow the value of the Accept header.

The tricky solution is to reorder the ContentNegotiationStrategy objects registered with RequestResponseBodyMethodProcessor , which your @ResponseBody .

+20
Jan 20 '14 at 14:45
source

I had the same problem, after all, it was a version of org.codehaus.jackson 1.9.x when I switched from 1.9.x jackson to 2.x (quickxml) in my pom.xml

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

also needed: <mvc:annotation-driven />

+1
Apr 24 '15 at 20:40
source

I ran into this problem when updating Spring in an outdated project. The suffix .html of the AJAX endpoints (which tried to return JSON) was really forcibly trying to create HTML because of the suffix, and since the handlers returned the object, the request failed with 406 because Spring was unable to figure out how to make HTML from a simple Java object.

Instead of changing the endpoint suffix or completing the full configuration of the custom ContentNegotiationStrategy , to make this change is enough:

 <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"/> 
+1
May 2 '16 at 15:07
source

Adding these lines to the context configuration solved the same problem for me:

  <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </mvc:message-converters> </mvc:annotation-driven> 

I used Spring 4.1.x and Jackson 2.4.2

0
Sep 22 '14 at 20:42
source

Be sure to use the results = "application / json" command in your annotations.

-2
Jan 20 '14 at 15:39
source



All Articles