Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @ExceptionHandler does not work with @ResponseBody

I try to configure a spring exception handler for a rest controller that is able to render a map to both xml and json based on the incoming accept header. It throws a 500 servlet exception right now.

This works, it picks up the home.jsp:

@ExceptionHandler(IllegalArgumentException.class) public String handleException(final Exception e, final HttpServletRequest request, Writer writer) {     return "home"; } 

This does not work:

@ExceptionHandler(IllegalArgumentException.class) public @ResponseBody Map<String, Object> handleException(final Exception e, final HttpServletRequest request, Writer writer) {     final Map<String, Object> map = new HashMap<String, Object>();     map.put("errorCode", 1234);     map.put("errorMessage", "Some error message");     return map; } 

In the same controller mapping the response to xml or json via the respective converter works:

@RequestMapping(method = RequestMethod.GET, value = "/book/{id}", headers = "Accept=application/json,application/xml") public @ResponseBody Book getBook(@PathVariable final String id) {     logger.warn("id=" + id);     return new Book("12345", new Date(), "Sven Haiges"); } 
like image 869
Sven Haiges Avatar asked Feb 23 '11 21:02

Sven Haiges


People also ask

How spring boots handle exceptions globally?

You can define the @ExceptionHandler method to handle the exceptions as shown. This method should be used for writing the Controller Advice class file. Now, use the code given below to throw the exception from the API. The complete code to handle the exception is given below.

How do you handle an exception in spring boot using annotations?

The exception handler method takes in an exception or a list of exceptions as an argument that we want to handle in the defined method. We annotate the method with @ExceptionHandler and @ResponseStatus to define the exception we want to handle and the status code we want to return.

How do you handle exceptions in spring boot Microservices?

Exception Handling in Spring Boot helps to deal with errors and exceptions present in APIs so as to deliver a robust enterprise application. This article covers various ways in which exceptions can be handled in a Spring Boot Project. Let's do the initial setup to explore each approach in more depth.


2 Answers

Your method

@ExceptionHandler(IllegalArgumentException.class) public @ResponseBody Map<String, Object> handleException(final Exception e, final HttpServletRequest request, Writer writer) 

does not work because it has the wrong return type. @ExceptionHandler methods have only two valid return types:

  • String
  • ModelAndView.

See http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html for more information. Here's the specific text from the link:

The return type can be a String, which is interpreted as a view name or a ModelAndView object.

In response to the comment

Thanx, seems I overread this. That's bad... any ideas how to provides exceptions automatically in xml/json format? – Sven Haiges 7 hours ago

Here's what I've done (I've actually done it in Scala so I'm not sure if the syntax is exactly correct, but you should get the gist).

@ExceptionHandler(Throwable.class) @ResponseBody public void handleException(final Exception e, final HttpServletRequest request,         Writer writer) {     writer.write(String.format(             "{\"error\":{\"java.class\":\"%s\", \"message\":\"%s\"}}",             e.getClass(), e.getMessage())); } 
like image 105
three-cups Avatar answered Sep 17 '22 17:09

three-cups


Thanx, seems I overread this. That's bad... any ideas how to provides exceptions automatically in xml/json format?

New in Spring 3.0 MappingJacksonJsonView can be utilized to achieve that:

private MappingJacksonJsonView  jsonView = new MappingJacksonJsonView();  @ExceptionHandler(Exception.class) public ModelAndView handleAnyException( Exception ex ) {     return new ModelAndView( jsonView, "error", new ErrorMessage( ex ) ); } 
like image 26
Mikhail Skotnikov Avatar answered Sep 20 '22 17:09

Mikhail Skotnikov