Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring 3.x JSON status 406 "characteristics not acceptable according to the request "accept" headers ()"

Upon trying to get my response in JSON using Spring 3.x, I get the 406 error "The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ()."

Here is my environment

* Spring 3.2.0.RELEASE * included jackson-mapper-asl-1.7.9.jar, jackson-core-asl-1.7.9.jar * Tomcat 6.x * mvc:annotation-driven in Spring configuration XML file 

My Controller:

@RequestMapping("/contest") public class ContestController {      @RequestMapping(value="{name}", headers="Accept=*/*", method = RequestMethod.GET)     public @ResponseBody Contest getContestInJSON(@PathVariable String name) {         Contest contest = new Contest();         contest.setName(name);         contest.setStaffName(new String("contestitem1"));          return contest;     }  } 

My Spring Configuration file

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="     http://www.springframework.org/schema/beans          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     http://www.springframework.org/schema/context      http://www.springframework.org/schema/context/spring-context-3.0.xsd     http://www.springframework.org/schema/mvc     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  <context:component-scan base-package="com.contestframework.controllers" />  <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">  <property name="mediaTypes">     <map>       <entry key="atom" value="application/atom+xml"/>       <entry key="html" value="text/html"/>       <entry key="json" value="application/json"/>     </map>  </property>   <property name="viewResolvers">  <list>   <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">     <property name="prefix" value="/WEB-INF/pages/"/>     <property name="suffix" value=".jsp"/>   </bean>  </list>  </property>   <property name="defaultViews">   <list>    <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />   </list>  </property>   </bean>  <mvc:annotation-driven />  </beans> 

After this I just access the Controller using below:

http://domain/SpringWebProject/json/contest/abcd 

and the response I get is Status 406: "The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ()."

I also tried an alternate mechanism by access this using Javascript AJAX to make sure my request header has application/JSON but this led to the same Status 406 result

$.getJSON('contest/abcd', function(data) { console.log(data) } 

Here is my REQUEST HEADER captured from browser:

Request URL:http://localhost:8080/SpringWebProject/json/contest/abcd Request Method:GET Status Code:406 Not Acceptable  Accept:application/json, text/javascript, */*; q=0.01 Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8 Connection:keep-alive Cookie:JSESSIONID=59689C95B0B9C21494EB0AB9D9F7BCCD Host:localhost:8080 Referer:http://localhost:8080/SpringWebProject/json/welcome User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4 X-Requested-With:XMLHttpRequest Response Headersview source Content-Length:1070 Content-Type:text/html;charset=utf-8 Date:Fri, 12 Oct 2012 18:23:40 GMT Server:Apache-Coyote/1.1 

Appreciate any help in this regard.

like image 311
user1740567 Avatar asked Oct 12 '12 18:10

user1740567


2 Answers

I have also just experienced this same issue. It would appear it is an issue with the latest 3.2.0.RELEASE, as I previously had 3.1.2.RELEASE and it all worked. After changing to 3.2.0.RELEASE it breaks. Have tested with 3.1.3.RELEASE and that works fine. So for now I would suggest rolling back to 3.1.3.RELEASE

EDIT: Thanks to another post on this site that linked to the following location: http://static.springsource.org/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-config-content-negotiation

I've now got it working by disabling the getting of media type based on the extension of the requested path. This can be done by the following:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">     <!-- Turn off working out content type based on URL file extension, should fall back to looking at the Accept headers -->     <property name="favorPathExtension" value="false" /> </bean> 

And specify version 3.2 for all the xsd schema locations.

And this is using the following jackson jars:

<dependency>     <groupId>com.fasterxml.jackson.core</groupId>     <artifactId>jackson-core</artifactId>     <version>2.1.2</version> </dependency> <dependency>     <groupId>com.fasterxml.jackson.core</groupId>     <artifactId>jackson-databind</artifactId>     <version>2.1.2</version> </dependency> 
like image 138
annihilate Avatar answered Sep 21 '22 16:09

annihilate


There is nothing wrong in your configuration, let me suggest a few small changes though:

a) Your namespaces appear wrong - they are referring to the 3.0 schemas, just change them to either 3.1 one's or don't refer to the version explicitly, this way for eg.

xsi:schemaLocation="     http://www.springframework.org/schema/beans          http://www.springframework.org/schema/beans/spring-beans.xsd 

OR

xsi:schemaLocation="     http://www.springframework.org/schema/beans          http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 

b) You don't require the ContentNegotiatingViewResolver, you can remove everything but the component-scan and <mvc:annotation-driven/> from your configuration

c) The request will not directly work from the browser as it explicitly requires an Accept header of "application/json" - $.getJson call should work though as it sends the correct headers

d) Remove the headers=Acc.. from the @RequestMapping, and produces also, both are filtering criteria to match up the correct mapped method call.

With these, there is no reason why the json should not get served out, can you please try with these and see how it goes.

like image 40
Biju Kunjummen Avatar answered Sep 18 '22 16:09

Biju Kunjummen