Reputation: 2220
I have migrated my application from Spring 3 to Spring 4.1.7.
Now, when i a doing an ajax query, the server responds with an HTTP 406
error.
POST /extranet/EmailIdentificationGetFicheClient.html HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept: application/json, */*; q=0.01
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
The response :
HTTP/1.1 406 Inacceptable Server: Apache-Coyote/1.1 Content-Type: text/html;charset=utf-8 Content-Language: fr Content-Length: 1110 Date: Wed, 26 Aug 2015 08:28:08 GMT
I have the latest jackson librairies in the classpath :
<dependency org="com.fasterxml.jackson.datatype" name="jackson-datatype-json-org" rev="2.6.1" />
<dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.9.13" />
My dispatcher-servlet.xml
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class = "org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/plain; charset=UTF-8" />
</bean>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter">
<property name="supportedMediaTypes" value="application/xml"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="favorPathExtension" value="false" />
<property name="useJaf" value="false" />
<property name="useNotAcceptableStatusCode" value="false" />
<property name="viewResolvers">
<list>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="order" value="1" />
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
</list>
</property>
As the application lives along with struts, the spring servlet was mapped to *.html URLs.
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
We have several ajax queries such as this one :
$.ajax({
type : "post",
accepts : {
json : 'application/json'
},
url : "/extranet/emailIdentification.html",
cache : false,
dataType : 'json', ...
The controller code (i can see in debug that it gets correctly there).
@RequestMapping(value="/extranet/EmailIdentification")
@ResponseBody
public Contact getContactFromEmail(HttpServletRequest request) throws SpringException {
Additionnaly, we are using spring-security and what we are trying to do is get spring to recognize the accept header as it did on the previous version.
Thank you for your time.
Upvotes: 0
Views: 627
Reputation: 2220
I have finally found where my problem was.
The problem was not caused by the jackson librairies for my part as they were correctly loaded.
I noticed in debug that i received an exception HttpMediaTypeNotAcceptableException
.
This exception was caused by the ContentNegotiationStrategy
loaded was using the path extension instead of the HTTP headers, although i configured the view resolver to ignore path extension :
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="favorPathExtension" value="false" />
<property name="useJaf" value="false" />
<property name="useNotAcceptableStatusCode" value="false" />
<property name="viewResolvers">
I also added a Content Manager Factory :
<bean id="cnManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="useJaf" value="false" />
<property name="ignoreAcceptHeader" value="false" />
</bean>
But this factory was never taken into account, instead, spring loaded its own version called mvcContentNegotiationManager
.
The final hack was therefore to force using the correct class and this is done by setting it through the mvc:annotation-driven tag :
<mvc:annotation-driven content-negotiation-manager="cnManager" />
Et Voilà. Now i can still use the .html extension in spring 4 even for json queries.
Upvotes: 1
Reputation: 1789
The cause of the problem is inability of Spring to load Jackson. It is not loaded by dependencies by default. After I've added the dependency
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.2</version>
</dependency>
the JSON was returned after typing the address in the browser, without any tricks with Accept headers (as it is supposed to do).
Upvotes: 0