Spring 3 MVC Exception Handlers

The majority of the Spring 3 error handling sample code that I’ve come across only ever seems to give the simplest overview of its usage, yet how we handle errors is, some would say, more important than how the normal code works. This was borne out the other day when I came across a simple ‘GOTCHA’ in a Spring (2) error handler that brought a whole website down and almost killed the server, but more on that later.

Today’s blog examines the scenario of creating a simple Spring 3 servlet exception handler using the @ExceptionHandler annotation. Although you may have seen this before it provides me with a good place to start, and for this demonstration I’ve created a simple Spring 3 MVC webapp(1) where the home page (home.jsp) makes requests to a flaky controller class that throws exceptions (ExceptionDemoController)

/**
   * Whoops, throw an IOException
   */
  @RequestMapping(value = "/ioexception", method = RequestMethod.GET)
  public String throwIoException(Locale locale, Model model) throws IOException {

    logger.info("This will throw an IOExceptiom");

    boolean throwException = true;

    if (throwException) {
      throw new IOException("This is my IOException");
    }

    return "home";
  }

The flaky controller code above is the first step in generating an error. The idea is that it’s supposed to return the user to our home page, but in the mists of processing the user’s request it throws a simple IOException. Once thrown, the exception is caught by this method:

/**
   * Catch IOException and redirect to a 'personal' page
   */
  @ExceptionHandler(IOException.class)
  public ModelAndView handleIOException(IOException ex) {

    logger.info("handleIOException - Catching: " + ex.getClass().getSimpleName());
    return errorModelAndView(ex);
  }

  /**
   * Get the users details for the 'personal' page
   */
  private ModelAndView errorModelAndView(Exception ex) {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("error");
    modelAndView.addObject("name", ex.getClass().getSimpleName());
    modelAndView.addObject("user", userDao.readUserName());

    return modelAndView;
  }

To set this up is really simple, all you need to do is to add:

@ExceptionHandler(IOException.class)

… to a method signature, et voila you’re done …and that’s the simple bit over with.

There are some points worth noting here: firstly, using

@ExceptionHandler(IOException.class)

…will adhere to the usual contract for exception handling. This means that not only will the method above catch all IOExceptions, it’ll also catch all exceptions that are subclasses of IOException; hence, if my throwAnException(..) method threw a FileNotFoundException it’ll still be caught by my handleIOException(…) method.

Secondly, there is a very flexible, but ultimately limited, set of method signatures that you can use for exception handler methods. The full documentation for this is provided by Spring’s JavaDoc, but in summary you can devise a signature that contains any of the following input arguments in any order:

  • Exception or one of its subclasses
  • ServletRequest or HttpServletRequest
  • ServletResponse or HttpServletResponse
  • HttpSession
  • WebRequest or NativeWebRequest
  • Locale
  • InputStream or one of its subclasses to access the request’s content
  • OutputStream or one of its subclasses to access the response’s content
  • Reader or one of its subclasses
  • Writer or one of its subclasses

The method signature must also have one of the following return types:

  • ModelAndView
  • Model
  • Map
  • View
  • String – interpreted as a view name
  • void, but only if the method writes directly to the response object

All of which should be enough for any scenario under any circumstance.

Using @ExceptionHandler gives you the ability to perform fine grained exception handling that targets different error scenarios. In the case of the sample code, I create a new ModelAndView object and populate it with the user’s name in order to personally tell him/her that the system has lost their documents. Some may say that this is a limitation, as @ExceptionHandler is so fine-grained that you can only catch exceptions thrown by the controller that contains your @ExceptionHandler annotated method. I would disagree, if you want to catch exceptions thrown by multiple controllers in one place, then this technique is not for you and you should consider using a SimpleMappingExceptionResolver instead.

There’s lots to consider when implementing error handling such as: what happens if there’s an error in your error handler? Should you use coarse or fine grained exception handlers? What about setting the HTTP status code? So, my next few blogs will looking into error handling further, demonstrating how to assign multiple exception classes to a single @ExceptionHandler and how to combine the exception handler notation with @ResponseStatus to fine tune your server’s HTTP status code, and may be more…

Reference: Spring 3 MVC Exception Handlers from our JCG partner Roger Hughes at the Captain Debug’s Blog .


  1. The full webapp sample is available at:
    git://github.com/roghughe/captaindebug.git
  2. See the Spring documentation for reference material.
Related Whitepaper:

Introduction to Web Applications Development

Kick start your web apps development with this introductory ebook!

This 376 page eBook 'Introduction to Web Applications Development', starts with an introduction to the internet, including a brief history of the TCT/IP protocol and World Wide Web. It defines the basic concepts for web servers and studies the case of Apache, the most used webserver, while other free software webservers are not forgotten. It continues with webpage design focusing on HTML and JavaScript. XML Schemas, their validation and transformation are covered as well as dynamic webpages built with CGI, PHP or JSP and database access.

Get it Now!  

Leave a Reply


nine − 2 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close