15.9 Handling exceptions

15.9.1 HandlerExceptionResolver

Spring HandlerExceptionResolvers ease the pain of unexpected exceptions that occur while your request is handled by a controller that matched the request. HandlerExceptionResolvers somewhat resemble the exception mappings you can define in the web application descriptor web.xml. However, they provide a more flexible way to handle exceptions. They provide information about which handler was executing when the exception was thrown. Furthermore, a programmatic way of handling exception gives you more options for responding appropriately before the request is forwarded to another URL (the same end result as when you use the servlet specific exception mappings).

Besides implementing the HandlerExceptionResolver interface, which is only a matter of implementing the resolveException(Exception, Handler) method and returning a ModelAndView, you may also use the SimpleMappingExceptionResolver. This resolver enables you to take the class name of any exception that might be thrown and map it to a view name. This is functionally equivalent to the exception mapping feature from the Servlet API, but it is also possible to implement more finely grained mappings of exceptions from different handlers.

15.9.2 @ExceptionHandler

An alternative to the HandlerExceptionResolver interface is the @ExceptionHandler annotation. You use the @ExceptionHandler method annotation within a controller to specify which method is invoked when an exception of a specific type is thrown during the execution of controller methods. For example:

@Controller
public class SimpleController {

  // other controller method omitted

  @ExceptionHandler(IOException.class)
  public String handleIOException(IOException ex, HttpServletRequest request) {
    return ClassUtils.getShortName(ex.getClass());
  }
}

will invoke the 'handlerIOException' method when a java.io.IOException is thrown.

The @ExceptionHandler value can be set to an array of Exception types. If an exception is thrown matches one of the types in the list, then the method annotated with the matching @ExceptionHandler will be invoked. If the annotation value is not set then the exception types listed as method arguments are used.

Much like standard controller methods annotated with a @RequestMapping annotation, the method arguments and return values of @ExceptionHandler methods are very flexible. For example, the HttpServletRequest can be accessed in Servlet environments and the PortletRequest in Portlet environments. The return type can be a String, which is interpreted as a view name or a ModelAndView object. Refer to the API documentation for more details.