How to change the content type in exception handler

mime-types, spring, spring-mvc

Solution

I think removing the `produces = MediaType.APPLICATION_JSON_VALUE` from `@RequestMapping` of the `getMetaInformation` will give you the desired result.

The response-type will be negotiated according to the content-type value in the Accept header.

edit

As this does not cover scenario 3,4 here is a solution working with `ResponseEntity.class` directly:

@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleIllegalArgumentException(Exception ex) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.TEXT_PLAIN);
    return new ResponseEntity<String>(ex.getMessage(), headers, HttpStatus.BAD_REQUEST);
}

Problem

Suppose I have a controller that serves `GET` request and returns bean to be serialized to JSON and also provides an exception handler for `IllegalArgumentException` that can be raised in service: ``` @RequestMapping(value = "/meta/{itemId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public MetaInformation getMetaInformation(@PathVariable int itemId) { return myService.getMetaInformation(itemId); } @ExceptionHandler(IllegalArgumentException.class) @ResponseStatus(value = HttpStatus.BAD_REQUEST) @ResponseBody public String handleIllegalArgumentException(IllegalArgumentException ex) { return ExceptionUtils.getStackTrace(ex); } ``` Message convertors are: ``` <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> <bean class="org.springframework.http.converter.StringHttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven> ``` Now when I request the given URL in browser I see the correct JSON reply. However if exception is raised, the stringified exception is converted into JSON as well, but I would love it to be processed by `StringHttpMessageConverter` (resulting `text/plain` mime type). How can I go it? To make the picture more complete (and complicated), suppose I also have the following handler: ``` @RequestMapping(value = "/version", method = RequestMethod.GET) @ResponseBody public String getApplicationVersion() { return "1.0.12"; } ``` This handler allows the return string to be serialized by both `MappingJackson2HttpMessageConverter` and `StringHttpMessageConverter` depending in passed `Accept-type` by the client. The return types and values should be as following: ``` +----+---------------------+-----------------------+------------------+-------------------------------------+ | NN | URL | Accept-type | Content-type | Message converter | | | | request header | response header | | +----+---------------------+-----------------------+------------------+-------------------------------------+ | 1. | /version | text/html; */* | text/plain | StringHttpMessageConverter | | 2. | /version | application/json; */* | application/json | MappingJackson2HttpMessageConverter | | 3. | /meta/1 | text/html; */* | application/json | MappingJackson2HttpMessageConverter | | 4. | /meta/1 | application/json; */* | application/json | MappingJackson2HttpMessageConverter | | 5. | /meta/0 (exception) | text/html; */* | text/plain | StringHttpMessageConverter | | 6. | /meta/0 (exception) | application/json; */* | text/plain | StringHttpMessageConverter | +----+---------------------+-----------------------+------------------+-------------------------------------+ ```

Original source