使用Ajax / JSON请求从Spring 3迁移到Spring 4.1 HTTP状态406

时间:2015-08-26 08:35:51

标签: json spring spring-mvc spring-4

我已将我的应用程序从Spring 3迁移到Spring 4.1.7。 现在,当我进行ajax查询时,服务器响应HTTP 406错误。

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

回应:

  

HTTP / 1.1 406不可接受的服务器:Apache-Coyote / 1.1内容类型:   text / html; charset = utf-8 Content-Language:fr Content-Length:1110   日期:2015年8月26日星期三08:28:08 GMT

我在类路径中有最新的jackson librairies:

<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" />

我的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>

当应用程序与struts一起使用时,spring servlet被映射到* .html URL。

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

我们有几个ajax查询,例如:

$.ajax({
    type : "post",
    accepts : {
      json : 'application/json'
    },
    url : "/extranet/emailIdentification.html",
    cache : false,
    dataType : 'json', ...

控制器代码(我可以在调试中看到它在那里正确显示)。

@RequestMapping(value="/extranet/EmailIdentification")
@ResponseBody
public Contact getContactFromEmail(HttpServletRequest request) throws SpringException {

另外,我们正在使用spring-security,而我们要做的就是让spring知道accept块,就像在之前版本中那样。

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

我终于找到了问题所在。

这个问题不是由杰克逊的图书馆造成的,因为他们被正确加载了。

我在调试中注意到我收到了异常HttpMediaTypeNotAcceptableException

此异常是由加载的ContentNegotiationStrategy使用路径扩展而不是HTTP标头引起的,尽管我将视图解析器配置为忽略路径扩展:

<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">

我还添加了一个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>

但是这个工厂从未被考虑过,而是加载了自己的版本mvcContentNegotiationManager

最后的黑客是强制使用正确的类,这是通过mvc:annotation-driven标签设置来完成的:

<mvc:annotation-driven content-negotiation-manager="cnManager" />

EtVoilà。现在我仍然可以在Spring 4中使用.html扩展名,即使对于json查询也是如此。