I have a controller mapped with the following annotation:
@RequestMapping(value = "/json", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public String bar() {
return "{\"test\": \"jsonResponseExample\"}";
}
I return a valid JSON string however, the content-type when I view the response on Chrome Dev Tools in browser is not application/json
but just plain text/html
. Why is the content type not being set?
My web.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<web-app metadata-complete="true" version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>Spring MVC Web Application</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- static assets -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
My dispatcher-servlet.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:annotation-config />
<context:component-scan base-package="com.mydomain.controllers" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
Using WildFly 8.1 as my app server.
This question is related to
java
json
spring
spring-mvc
content-type
Use jackson library and @ResponseBody
annotation on return type for the Controller.
This works if you wish to return POJOs represented as JSon. If you woud like to return String and not POJOs as JSon please refer to Sotirious answer.
I had the dependencies as specified @Greg post. I still faced the issue and could be able to resolve it by adding following additional jackson dependency:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.7.4</version>
</dependency>
When I upgraded to Spring 4 I needed to update the jackson dependencies as follows:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.5.1</version>
</dependency>
Not exactly for this OP, but for those who encountered 404 and cannot set response content-type
to "application/json"
(any content-type
). One possibility is a server actually responds 406 but explorer (e.g., chrome) prints it as 404.
If you do not customize message converter, spring would use AbstractMessageConverterMethodProcessor.java
. It would run:
List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(request);
List<MediaType> producibleMediaTypes = getProducibleMediaTypes(request, valueType, declaredType);
and if they do not have any overlapping (the same item), it would throw HttpMediaTypeNotAcceptableException
and this finally causes 406. No matter if it is an ajax, or GET/POST, or form action, if the request uri ends with a .html
or any suffix, the requestedMediaTypes
would be "text/[that suffix]", and this conflicts with producibleMediaTypes
, which is usually:
"application/json"
"application/xml"
"text/xml"
"application/*+xml"
"application/json"
"application/*+json"
"application/json"
"application/*+json"
"application/xml"
"text/xml"
"application/*+xml"
"application/xml"
"text/xml"
"application/*+xml"
As other people have commented, because the return type of your method is String
Spring won't feel need to do anything with the result.
If you change your signature so that the return type is something that needs marshalling, that should help:
@RequestMapping(value = "/json", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public Map<String, Object> bar() {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("test", "jsonRestExample");
return map;
}
Source: Stackoverflow.com