0

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.

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

1 Comment

Sorry this is not the problem, the jars are correctly loaded through my application server. Thank you for pointing that out anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.