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.
For receiving a JSON request, it is important to mention or tell the browser about the type of request it is going to receive. So we set its MIME type by mentioning it in the Content-Type. We can do the same in two ways: MIME type: application/json.
Send JSON Data in POST Spring provides a straightforward way to send JSON data via POST requests. The built-in @RequestBody annotation can automatically deserialize the JSON data encapsulated in the request body into a particular model object. In general, we don't have to parse the request body ourselves.
APPLICATION_JSON is a "public constant media type for application/json ", whereas MediaType. APPLICATION_JSON_VALUE is a "String equivalent of MediaType. APPLICATION_JSON ". Attributes on Java annotations can only be one of a limited set of types. This prevents MediaType from being used as an annotation attribute.
First thing to understand is that the RequestMapping#produces()
element in
@RequestMapping(value = "/json", method = RequestMethod.GET, produces = "application/json")
serves only to restrict the mapping for your request handlers. It does nothing else.
Then, given that your method has a return type of String
and is annotated with @ResponseBody
, the return value will be handled by StringHttpMessageConverter
which sets the Content-type
header to text/plain
. If you want to return a JSON string yourself and set the header to application/json
, use a return type of ResponseEntity
(get rid of @ResponseBody
) and add appropriate headers to it.
@RequestMapping(value = "/json", method = RequestMethod.GET, produces = "application/json") public ResponseEntity<String> bar() { final HttpHeaders httpHeaders= new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); return new ResponseEntity<String>("{\"test\": \"jsonResponseExample\"}", httpHeaders, HttpStatus.OK); }
Note that you should probably have
<mvc:annotation-driven />
in your servlet context configuration to set up your MVC configuration with the most suitable defaults.
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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With