Reputation: 1071
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
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