My problem is that I want to return a Java collection as JSON using Spring MVC and the standard annotations that come with it. Unfortunately though I end up with HTTP error code 406 every time.
"The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers."
I thought that Jackson and Spring can automagically convert my return type but it returns a HTTP error 406 if we use a collection or anything other return type than String
. Can you please help show what I am doing wrong?
Research
As I mentioned we can get a String to return. We think the problem will be either in Maven (dependencies with Jackson) or in our understanding of Spring MVC REST annotations. Another route is we have not configured our Spring context's correctly.
Controller
This is my annotated Spring controller. The first simple method (
getAJsonString
) works but the second one (getImprovedJsonMap
) with a map returns a HTTP error code 406 which we presume is due to the complex type:
@Controller
@RequestMapping("/kfc/brands")
public class DefaultMetricsService {
@RequestMapping(value="/firstMethod", method = RequestMethod.GET)
public @ResponseBody String getAJsonString() {
return "HELLO";
}
@RequestMapping(value = "/Metrics/type3", method = RequestMethod.GET)
public @ResponseBody Map<String, String> getImprovedJsonMap() {
Map jsonMap = new HashMap<String, String>();
jsonMap.put("counter", "3000");
return jsonMap;
}
Spring Servlet Definition
This is my Spring configuration (
metrics-servlet.xml
:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:component-scan base-package="com.t2" />
<mvc:annotation-driven />
</beans>
...
Dependencies
This is my pom with versions of Jackson:
<!-- Dependency Versions -->
<org.slf4j.version>1.6.1</org.slf4j.version>
<spring.version>3.2.2.RELEASE</spring.version>
<commons.loggin.version>1.1.1</commons.loggin.version>
<junit.version>4.8.2</junit.version>
<jackson.version>1.9.10</jackson.version>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons.loggin.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Jackson JSON Mapper -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
...
Servlet
This is my servlet definition:
<servlet>
<servlet-name>metrics</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:metrics-application-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>metrics</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:metrics-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>