I want to send JSON from my controller. I have the following configuration.
spring-servlet.xml :
I had the same problem in the end it was the version of org.codehaus.jackson 1.9.x, when I switched from 1.9.x jackson to 2.x (fasterxml) 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 is necesary : <mvc:annotation-driven />
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.
Instead of altering the endpoint suffixes, or doing a complete configuration of a custom ContentNegotiationStrategy
, making this change was 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"/>
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.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
I used Spring 4.1.x
and Jackson 2.4.2
Make sure to use produces = "application/json" in your annotations.
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 MappingJacksonHttpMessageConverter
produces, ie. application/json
and therefore a 406 is returned.
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.
The complicated solution is to change the order of the ContentNegotiationStrategy
objects registered with the RequestResponseBodyMethodProcessor
which handles your @ResponseBody
.