Reputation: 85476
I'm trying to return a JSON response with Spring 3.0.6, but I get a 406 response "Not Acceptable", with the description: "The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ()."
I know that a very similar question has been asked before, but I can't make it work for my project, despite many tests and I don't understand what I'm doing wrong.
In my Maven pom.xml I've the following:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.8.5</version>
<scope>compile</scope>
</dependency>
In web.xml I reference webmvc-config.xml, and the log confirms that is loaded.
<servlet>
<servlet-name>mainServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
In webmvc-config.xml I've the following:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:annotation-driven />
My Controller is:
@Controller
public class ClassifiedController {
@RequestMapping(value = "/classified/{idClassified}", headers = "Accept=*/*",
method = RequestMethod.GET)
@ResponseBody
public final Classified getClassified(@PathVariable final int idClassified) {
...
I tried with or without the headers parameter with the same results. If I call the URL directly with Firefox the Request Headers contain the following (checked with firebug):
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
If I use the following JQuery:
$.ajax({
url: '/classified/38001',
type: 'GET',
dataType: 'json'
});
The following headers are sent:
Accept: application/json, text/javascript, */*; q=0.01
In both cases the result is a 406 error. I don't know what else should I check to make it work.
UPDATE: I decided to debug through Spring and I found out that Jackson was called correctly and in org.codehaus.jackson.map.ser.StdSerializerProvider the method _findExplicitUntypedSerializer contains the following code:
try {
return _createAndCacheUntypedSerializer(runtimeType, property);
} catch (Exception e) {
return null;
}
This is unfortunate because hides the source of the problem. With the debugger I found out that that exception contained a very descriptive error message:
Conflicting getter definitions for property "reminded":
ClassifiedImpl#isReminded(0 params) vs
ClassifiedImpl#getReminded(0 params)
Now that I see the error message is a silly mistake and easy to fix, but without that it wasn't that obvious. In fact, fixing the problem, leaded to a working serialization.
Upvotes: 12
Views: 22613
Reputation: 376
I've stumbled upon the same error (406: content not acceptable) with Spring MVC and @RestController annotation.
The Spring handler:
@RequestMapping(value = "/stuff-acknowledgment/{id}", produces ="application/json;charset=UTF-8", headers="Accept=*")
public Message acknowledgeStuff(@PathVariable("id") String id, @ModelAttribute("ack") AckBean acquittement) {
Observation:
http://www.host.com/stuff-acknowledgment/{id}
$id
has a very particular format: xxxcomplicatedhashxxx.png
(or whatever extension you can think of). Therefore:
Spring MVC interpret the extension and want to produce a result of that same mime type (even if I define it as a path variable), here an "image/png"
MIME type even if I tell him to produce JSON. So a 406 exception is thrown.
Fix:
Remove the ".png"
extension in the URI, or remove the PathVariable and put it in the body, or add a suffix behind the pathVariable (not tested but should work as well), the point is to avoid a file extension at the end of the URI.
P.S.: I know it doesn't answer the specific problem (with the solution in the update) in the question but I found that SO thread when searching for that problem and post my fix here for the record, hoping it can help someone in the future.
Upvotes: 7
Reputation: 2864
I ran into this problem because the objects that I wanted to return as JSON didn't have any getter methods for their properties. Jackson probably needs these. After adding them it worked.
Upvotes: 4
Reputation: 4330
Add the following in DispatcherServlet-servlet.xml.
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jacksonMessageConverter"/>
</list>
</property>
</bean>
Upvotes: 7
Reputation: 21
although this thread is a little old...
u need to add the following (maven dependency):
org.codehaus.jacksonjackson-mapper-asl1.9.13
Upvotes: 2
Reputation: 15104
In terms of the MappingJacksonJson processing, you'll need to make sure that the Jackson ObjectMapper supports your object type for serialisation.
Upvotes: 6