Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC 4: "application/json" Content Type is not being set correctly

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.

like image 502
user1757703 Avatar asked May 30 '15 16:05

user1757703


People also ask

How do you set the content type of the response to json?

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.

How pass json object in post request in spring boot?

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.

What is MediaType Application_json?

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.


Video Answer


2 Answers

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.

like image 115
Sotirios Delimanolis Avatar answered Sep 29 '22 11:09

Sotirios Delimanolis


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; } 
like image 37
ninj Avatar answered Sep 29 '22 10:09

ninj