Handling Exceptions In Spring MVC – Part 1

To read Part 2 in this series, click here

New to Spring MVC ?

or maybe you’re experienced ?

or maybe you have just used it a bit, you know, here and there.

Whatever the case, Spring MVC can cater for anyones web development appetite, if it be a simple site using the defaults, or a complex custom configuration utilizing local resolvers, custom handler mappers, and various view resolvers for jstl, freemarker and pdf.

In this post I would like to talk specifically about handling exceptions in your Spring web based application and different ways you can cater for the unexpected (although, if you plan for the unexpected aren’t you then expecting and thus planning for the expected?). Exceptions can occur throughout your application, from your domain layer to your web controllers, and handling them correctly is very important for everyone involved, especially the person on the end of the browser using the application.

As to keep this post readable, as I waffle a bit, I have broken it up into a few different posts, most likely two (but I will see how I go), so I can discuss what you get out of the box with a servlet container, Springs pre-made offerings, and options for building your own and customization.

web.xml and the servlet container

If you are familiar with the servlet spec you will already know that servlet containers can handle exceptions and error codes, all with just a simple declaration within your web.xml. This declaration can look something like this:

<error-page>
<error-code>404</error-code>
<location>page-not-found.jsp</location>
</error-page>

<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>uncaught-error.jsp</location>
</error-page>

Ok then, well, if the servlet container can handle the exceptions (and error codes), why do we need to bother setting up Spring to handle them? Well, there are some good reasons why, but before I explain them I need to explain the difference between an ‘error code’ and exception.

Error codes, or status codes as they are better known, are part of the http rfc spec and are not treated as an exception, per se. Spring does not catch error codes, in fact, it can’t, it can write error codes by calling response.sendError but does not catch them as they are only handled by the servlet container. Some well known status codes include 404 (page not found), 408 (request time-out), 500 (internal server error) and 503 (service unavailable). Status codes can either be caught and handled by the servlet container, which happens in most cases, and have a pretty html page served to the client, or a response can be sent which just contains the status code leaving the client (web browser) to display a page or message to the person on the other end of it. This is not new information, and it is fair to say that since Spring can not handle error codes being raised (as in some cases Spring will be raising them), the web.xml is the best place to handle these error codes.

So then, if web.xml is handling our error codes, why not let it handle our exceptions as well? There are some good reasons (as mentioned before) and they are :

  1. Filters are by-passed – This was a problem which appeared in a development another team was working on in my organization. Sitemesh decorates the pages by working as a servlet filter, if the application came upon an error code or exception, the servlet container would by-pass the filters and just render the jsp. In Spring this would not happen as it would catch the exception and not let it propagate up to the servlet container.
  2. Reference Data – Since the servlet container will just render a page, it will not allow for business logic to run, for example, not populate the model with some reference data.
  3. Logging and Auditing – Again, since only a page is rendered no extra logging, auditing or notifcation can be added cleanly.
  4. and last of all, generally these are Application exceptions and should be handled by the application not a third party.

It sounds like I am advocating Spring should do everything and you should just let the web.xml do only what Spring can’t. Well, thats a combination of yes and no, both Spring and the servlet container need to work together to handle status codes and exceptions properly, but it is also important that each should be used to capture errors and exceptions which they are responsible for.

handling exceptions in Spring

When you declare a DispatcherServlet you get several components out of the box, for example you get a bean name handler mapper, an annotation handler mapper, three or four handler adapters and a view resolver, to name a few of them.

One thing you don’t get is a HandlerExceptionResolver set up for you, but it only takes a second to set one up.

If you’re familiar with the workflow involved with handling a request, you will know that a try catch block surrounds the HandleAdapter method handle in the DispatcherServlets doDispatch method. If an exception occurs the DispatcherServlet will call processHandlerException which will then see if a HandlerExceptionResolver is registered. You can have any number of HandlerExceptionResolvers registered, be it one (which suits for most cases), two, 10, or more, and because they implement the Ordered interface you get to decide which one gets the chance to try and handle the exception first.

The HandlerExceptionResolver is an interface which contains only one method :

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

Spring is nice enough to give you a simple implementation which should be of use to most applications from the get go, its a simple exception resolver (SimpleMappingExceptionResolver) which maps exception types to error pages. Its configuration looks something like :

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<map>
<entry key="DataAccessException" value="data-error"/>
</map>
</property>
<property name="defaultErrorView" value="general-error" />
</bean>

As you can see all you need to do is create a list of exception types and link them to error pages, a very similar setup to SimpleUrlHandlerMapping.

The SimpleMappingExceptionResolver is a nice stable basic implementation which provides a good solid foundation for building and extending upon. In fact, the Spring team themselves recommend this as they provide many hooks for doing so. This is my first recommendation, use the SimpleMappingExceptionResolver in some shape or form, if it be for your main exception resolver or for extending upon, it provides a good solid base to work from and is very functional.

a quick summary

So far we know that the web.xml can do some things Spring can’t, like catch 404 or 500 status codes, but Spring on the other hand provides a HandlerExceptionResolver implementation which exposes many hooks ready for extension. Should one be used over another, no, should they be used together, well, yes, but its about using them together correctly, a topic I would like to leave until my next post, including possible ways to extend the SimpleMappingExceptionResolver, as this one is getting a bit long.

Thanks for reading

Josh

To read Part 2 in this series, click here

14 Comments

Filed under Spring MVC

14 responses to “Handling Exceptions In Spring MVC – Part 1

  1. Good article. Although i am already using Spring’s Exception Resolver mechanism, the reasons you provided for using it against web.xml equivalent was great. looking forward for your next one.

  2. srikanta

    how to pass model in error pages while using org.springframework.web.servlet.handler.SimpleMappingExceptionResolver
    class.

  3. Nice article,
    Helped me in dealing with excelview.

    From your example.

    java.lang.Exception
    uncaught-error.jsp

    Can we map java.lang.Exception to an error page ?
    I think it should be ServletException or its subclass.

  4. Nayha

    But Spring’s exception handler doesn’t handle exceptions thrown by filters which are called before we hit dispatcher servlet ….. how do we handle them?

  5. Josh Kalderimis

    Hi Nayha,

    Why are your filters throwing exceptions? The Spring Exception strategy is only for controllers, so if you can’t stop your filters throwing exceptions, I would put an exception catch in the web.xml for the specific error and general Exception error.

    Hope this helps,

    Josh

  6. Josh Kalderimis

    Although, I really do need to finish the 3rd article in this series, once I find a spare moment I will try too (traveling Europe at the moment).

  7. Monalisa

    I’m using the spring exceptionResolver for session expire exception and redirecting to the login page. How can I show a message to the user that the session has expired and then redirect to the login page. Any suggestion is highly appreciated.

  8. natt

    Hi! I have the same problem as Monalisa. I have tried to use the SimpleMappingExceptionResolver but it doesn’t work. What can i do?
    Thank you very much.

  9. Bala

    A good article never seen before!!!!

  10. Jan

    Nice article šŸ™‚
    I was wondering about the same question that Srikanta raised:
    How does one go about passing a model with additional information to the errorview(s) resolved by the exceptionresolver…?

    Well, the only way to create context specific information is to catch the exception, add more information and then re-throw the exception, right?
    Some might feel that doing this sort of defeats the purpose of the exceptionresolver… But it still prevents your controller from having to know about the error view.
    What I did was to create a model map with the context specific information (just a user-friendly high-level error message actually..) and then add this as a request attribute, which is available in my exceptionresolver override, from where it is easily added to the ModelAndView.

  11. Pingback: Ideal Way Of Exception Handling In Multi Layer Java Web Application | GoosPoos

  12. Pingback: Spring MVC Error Handling « DuckTools

  13. Pingback: Ideal Way of Exception Handling In Multi Layer Java Web Application | Kanthikiran's Blog

Leave a reply to Servlet Cancel reply