Spring XML 406 error

百般思念 提交于 2019-12-05 09:46:28

I just came across this when trying to troubleshoot the same issue. After looking at pfac's answer, I discovered I could solve my issue simply by adding the jackson-dataformat-xml library to my project.

If using maven:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.3.2</version>
</dependency>

Just spent some hours chasing this, so I'm leaving here what worked for me (I'm using Spring 4.0.6) and what I believe will work for you (Spring 3.0.x).

Spring 4.0.x

Since MappingJackson2HttpMessageConverter picks up the Jackson data binding library automatically and enables controller methods annotated with @ResponseBody to automatically return JSON, one usually assumes that such a tool also exists for XML, but this is not the case.

In order to enable XML I had to manually create a RequestMappingHandlerAdapter with two message converters, a MarshallingHttpMessageConverter followed by a MappingJackson2HttpMessageConverter.

This also allows to use any of the marshallers provided by Spring, just by setting it as a property of MarshallingHttpMessageConverter.

Resulting spring-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- ... -->

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
                    <property name="marshaller">
                        <bean class="org.springframework.oxm.xstream.XStreamMarshaller"></bean>
                    </property>
                </bean>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
            </list>
        </property>
    </bean>

    <!-- ... -->

</beans>

Spring 3.0.x

NOTE: I'm assuming this version from the schema locations in your x-servlet.xml.

According to http://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc and http://spring.io/blog/2013/06/03/content-negotiation-using-views/, there are two ways to achieve what you want in Spring 3. The first one is using a ContentNegotiationManager, which is only available since versions 3.2.x and therefore is unavailable for your version. The second one is using a ContentNegotiatingViewResolver, which delegates the resolution of the views to other resolvers based on the content type requested (whether this is defined by the Accept header, by extension, or by default is configurable).

Basically you need to configure a ContentNegotiatingViewResolver with two resolvers, one for XML and another for your JSP views.

spring-servlet.xml:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="viewResolvers">
        <list>
            <bean class="org.springframework.web.servlet.view.XmlViewResolver">
                <property name="location" value="spreadsheet-views.xml"/>
            </bean>

            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="WEB-INF/views"/>
                <property name="suffix" value=".jsp"/>
            </bean>
        </list>
    </property>
</bean>

You can add a view resolver for JSON for example, but you will have to implement it since Spring does not provide one. The second blog post shows how to implement a simple one.

406 means the request content is considered Not Acceptable by the server. Try to remove the Accept header or adding headers="Accept=*/*" to the @RequestMapping annotations.

I was struggling with a similar problem. It appeared that for some reason my web app was not providing xml data type by default, even despite I was setting "produces=application/xml" parameter in annotations.

I only solved it by adding extra bean configuration for my applicationContext.xml:

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
   <property name="defaultContentType" value="application/xml" />
</bean>
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

or via Java Config class:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.APPLICATION_XML);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!