In Spring MVC, how can I set the mime type header when using @ResponseBody

JavaJsonSpringSpring MvcController

Java Problem Overview


I have a Spring MVC Controller that returns a JSON String and I would like to set the mimetype to application/json. How can I do that?

@RequestMapping(method=RequestMethod.GET, value="foo/bar")
@ResponseBody
public String fooBar(){
    return myService.getJson();
}

The business objects are already available as JSON strings, so using MappingJacksonJsonView is not the solution for me. @ResponseBody is perfect, but how can I set the mimetype?

Java Solutions


Solution 1 - Java

Use ResponseEntity instead of ResponseBody. This way you have access to the response headers and you can set the appropiate content type. According to the Spring docs:

> The HttpEntity is similar to > @RequestBody and @ResponseBody. > Besides getting access to the request > and response body, HttpEntity (and the > response-specific subclass > ResponseEntity) also allows access to > the request and response headers

The code will look like:

@RequestMapping(method=RequestMethod.GET, value="/fooBar")
public ResponseEntity<String> fooBar2() {
	String json = "jsonResponse";
	HttpHeaders responseHeaders = new HttpHeaders();
	responseHeaders.setContentType(MediaType.APPLICATION_JSON);
	return new ResponseEntity<String>(json, responseHeaders, HttpStatus.CREATED);
}

Solution 2 - Java

I would consider to refactor the service to return your domain object rather than JSON strings and let Spring handle the serialization (via the MappingJacksonHttpMessageConverter as you write). As of Spring 3.1, the implementation looks quite neat:

@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE, 
    method = RequestMethod.GET
    value = "/foo/bar")
@ResponseBody
public Bar fooBar(){
    return myService.getBar();
}

Comments:

First, the <mvc:annotation-driven /> or the @EnableWebMvc must be added to your application config.

Next, the produces attribute of the @RequestMapping annotation is used to specify the content type of the response. Consequently, it should be set to MediaType.APPLICATION_JSON_VALUE (or "application/json").

Lastly, Jackson must be added so that any serialization and de-serialization between Java and JSON will be handled automatically by Spring (the Jackson dependency is detected by Spring and the MappingJacksonHttpMessageConverter will be under the hood).

Solution 3 - Java

You may not be able to do it with @ResponseBody, but something like this should work:

package xxx;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class FooBar {
  @RequestMapping(value="foo/bar", method = RequestMethod.GET)
  public void fooBar(HttpServletResponse response) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    out.write(myService.getJson().getBytes());
    response.setContentType("application/json");
    response.setContentLength(out.size());
    response.getOutputStream().write(out.toByteArray());
    response.getOutputStream().flush();
  }
}

Solution 4 - Java

I don't think this is possible. There appears to be an open Jira for it:

SPR-6702: Explicitly set response Content-Type in @ResponseBody

Solution 5 - Java

Register org.springframework.http.converter.json.MappingJacksonHttpMessageConverter as the message converter and return the object directly from the method.

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  <property name="webBindingInitializer">
    <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"/>
  </property>
  <property name="messageConverters">
    <list>
      <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    </list>
  </property>
</bean>

and the controller:

@RequestMapping(method=RequestMethod.GET, value="foo/bar")
public @ResponseBody Object fooBar(){
    return myService.getActualObject();
}

This requires the dependency org.springframework:spring-webmvc.

Solution 6 - Java

I don't think you can, apart from response.setContentType(..)

Solution 7 - Java

My version of reality. Loading a HTML file and streaming to the browser.

@Controller
@RequestMapping("/")
public class UIController {

	@RequestMapping(value="index", method=RequestMethod.GET, produces = "text/html")
	public @ResponseBody String GetBootupFile() throws IOException  {
		Resource resource = new ClassPathResource("MainPage.html");
		String fileContents = FileUtils.readFileToString(resource.getFile());
	    return fileContents;
	}
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSean Patrick FloydView Question on Stackoverflow
Solution 1 - JavaJavier FerreroView Answer on Stackoverflow
Solution 2 - JavamatsevView Answer on Stackoverflow
Solution 3 - JavaGriffeyDogView Answer on Stackoverflow
Solution 4 - JavadogbaneView Answer on Stackoverflow
Solution 5 - JavaOrangeDogView Answer on Stackoverflow
Solution 6 - JavaBozhoView Answer on Stackoverflow
Solution 7 - JavaR KeeneView Answer on Stackoverflow