Spring MVC - Creating a custom HandlerExceptionResolver

[Updated: Jul 10, 2017, Created: Jan 20, 2017]

We have seen the basic concept and a simple usage of low level HandlerExceptionResolver interface.

In this tutorial we are going to demonstrate how to create a custom HandlerExceptionResolver to introduce new ways to handle exceptions in Spring MVC.



  1. Create a new annotation ErrorView, which will specify a view name and status code.
  2. Create a custom HandlerExceptionResolver implementation, HandlerExceptionToViewResolver, whose method resolveException() will find out whether the source handler method (where exception occurred) has annotation ErrorView. If yes, it will get the view name and status code from the annotation and after setting the specified status code to the response, it will return the specified error page. If the handler method doesn't have ErrorView annotation the default error processing will continue.
  3. Create a controller and a jsp page for testing.

Creating custom annotation ErrorView

public @interface ErrorView {

    String value ();

    HttpStatus status () default HttpStatus.INTERNAL_SERVER_ERROR;

Creating custom HandlerExceptionResolver

public class HandlerExceptionToViewResolver implements HandlerExceptionResolver {

    public ModelAndView resolveException (HttpServletRequest request,
                                          HttpServletResponse response,
                                          Object handler,
                                          Exception ex) {

        if (handler instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod) handler;
            ErrorView errorView = hm.getMethodAnnotation(ErrorView.class);
            if (errorView != null) {
                //preparing ModelAndView
                String viewName = errorView.value();
                ModelAndView model = new ModelAndView(viewName);
                model.addObject("requestUri", request.getRequestURI());
                model.addObject("exception", ex);

                HttpStatus status = errorView.status();
                model.addObject("statusValue", status.value());
                model.addObject("statusStr", status.getReasonPhrase());
                //setting status code

                return model;
        //returning null for default processing
        return null;

Registering custom HandlerExceptionResolver

public class AppConfig {

    HandlerExceptionResolver customExceptionResolver () {
        return new HandlerExceptionToViewResolver();

Creating the Controller

In the following controller we are creating two handler methods, first one with @ErrorView and second one without it. The second one throws an exception which should map to @ExceptionHandler method (the third method), we are doing that to make sure that the default processing is not broken.

public class ExampleController {

    @ErrorView(value = "test-error-view", status = HttpStatus.GONE)
    public String handleRequest () throws Exception {
        throw new Exception("test exception");

    public String handleRequest2 () throws Exception {
        throw new OperationNotSupportedException("exception thrown in test2");

    public String handleException (OperationNotSupportedException e) {
        return "exception :" + e.toString();

JSP error page

<%@ page language="java"
    contentType="text/html; charset=ISO-8859-1"

<h3>Test Error View</h3>
 <p>Request Uri: <b>${requestUri}</b></p>
 <p>Exception: <b>${exception['class'].name}</b></p>
 <p>Message: <b>${exception.message}</b></p>
 <p>Response status: <b>${statusValue} (${statusStr})</b></p>

Running embedded tomcat

mvn tomcat7:run-war



Confirming status code in HTTPie:


Example Project

Dependencies and Technologies Used :

  • spring-webmvc 4.3.5.RELEASE: Spring Web MVC.
  • javax.servlet-api 3.0.1 Java Servlet API
  • JDK 1.8
  • Maven 3.3.9

Custom Handler Exception Resolver Select All Download
  • custom-handler-exception-resolver
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • webapp
          • WEB-INF
            • views

See Also