Mariusz Pala
Mariusz Pala

Reputation: 1071

Spring MVC XML request returns 406 error

I've visited all the forum posts but I still can't solve my issue. I have an app that should return both XML and JSON result. But only JSON works, XML request return 406 error. I'm using Spring 3.2. There is no error in the log besides the 406 http status. I've tried the following configurations:

Configuration 1:

<beans...>

    <context:component-scan base-package="com.sample" />


    <!-- First version -->
    <bean id="xmlConverter"
        class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
        <constructor-arg>
            <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
                <property name="classesToBeBound">
                    <list>
                        <value>com.sample.Class</value>
                    </list>
                </property>
            </bean>

        </constructor-arg>
        <property name="supportedMediaTypes">
            <list>
                <bean class="org.springframework.http.MediaType">
                    <constructor-arg index="0" value="application" />
                    <constructor-arg index="1" value="xml" />
                    <constructor-arg index="2" value="UTF-8" />
                </bean>
            </list>
        </property>
    </bean>

    <bean id="jaxbAnnotationInspector" class="org.codehaus.jackson.xc.JaxbAnnotationIntrospector" />
    <bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper">
        <property name="annotationIntrospector" ref="jaxbAnnotationInspector" />
    </bean>
    <bean id="jsonConverter"
        class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="objectMapper" ref="jacksonObjectMapper" />
        <property name="supportedMediaTypes">
            <list>
                <bean class="org.springframework.http.MediaType">
                    <constructor-arg index="0" value="application" />
                    <constructor-arg index="1" value="json" />
                    <constructor-arg index="2" value="UTF-8" />
                </bean>
            </list>
        </property>
    </bean>

    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="xmlConverter" />
                <ref bean="jsonConverter" />
            </list>
        </property>
    </bean>

    <bean
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="useDefaultSuffixPattern" value="false" />
    </bean>
</beans>

Configuration 2:

<beans ...>

    <context:component-scan base-package="com.sample" />

    <mvc:annotation-driven />

    <!-- Second version -->
    <bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1" />
        <property name="defaultContentType" value="application/xml" />
        <property name="mediaTypes">
            <map>
                <entry key="xml" value="application/xml" />
                <entry key="json" value="application/json" />
            </map>
        </property>
        <property name="defaultViews">
            <list>
                <bean
                    class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                    <property name="prefixJson" value="false" />
                </bean>
                <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                    <constructor-arg>
                        <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
                            <property name="classesToBeBound">
                                <list>
                                    <value>com.sample.Class</value>
                                </list>
                            </property>
                        </bean>
                    </constructor-arg>
                </bean>
            </list>
        </property>
        <property name="favorPathExtension" value="true" />
        <property name="ignoreAcceptHeader" value="false" />
    </bean>

    <bean
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="useDefaultSuffixPattern" value="false" />
    </bean>
</beans>

My Maven dependencies:

<!-- Spring 3 dependencies -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${org.springframework.version}</version>
    <exclusions>
        <exclusion>
            <artifactId>commons-logging</artifactId>
            <groupId>commons-logging</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${org.springframework.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${org.springframework.version}</version>
    <scope>compile</scope>
</dependency>

<!-- Jackson JSON Mapper -->
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.10</version>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-xc</artifactId>
    <version>1.9.10</version>
</dependency>

<!-- XML Mapper -->
<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-oxm-tiger</artifactId>
    <version>1.5.10</version>
</dependency>

My method:

@RequestMapping(value = "/repositories", method = RequestMethod.GET)
@ResponseBody
public List<Repository> getRepositories(HttpServletRequest req, HttpServletResponse resp) throws CaraException {
    List<Repository> repositories = repositoryFactory.getAvailableRepositories();
    return repositories;
}

My class annotated with JAXB:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Repository

[EDIT]

I narrowed down the issue. Looks like it's related with the java.util.List I return. If I try to return any other object annotated with JAXB - it works. So the question is how to make the List work ?

Thanks in advance for any help with this.

Mariusz

Upvotes: 0

Views: 1314

Answers (1)

Mariusz Pala
Mariusz Pala

Reputation: 1071

I found the solution. Instead of the List I had to create a list wrapper and return that wrapper. Apparently JAXB cannot handle lists.

@XmlRootElement(name = "repositories")
public class RepositoryListWrapper {
    private List<Repository> list;

    protected RepositoryListWrapper() {
    } // Keep JAXB happy

    public RepositoryListWrapper(List<Repository> list) {
        this.list = list;
    }

    @XmlElement(name = "repository")
    public List<Repository> getRepositories() {
        return list;
    }
}

Upvotes: 1

Related Questions