Using Spring's SimpleMappingExceptionHandler
Join the DZone community and get the full member experience.
Join For FreeMy last few blogs have talked about Spring’s @ExceptionHandler
annotation and how you can use it to deal with errors on a controller by
controller basis to give you fine-grained control over how you handle
errors in your code. The question to consider now is whether or not you
always want such fine grained control, to which I’m guessing that in
certain circumstances the answer will be no, and so to accommodate this
Spring have provided us with the SimpleMappingExceptionHandler.
The SimpleMappingExceptionHandler is an implementation of Springs HandlerExceptionResolver class, which, as I’ve mentioned before, Spring uses to manage exceptions thrown by your code. Spring has a limitation (if that’s what it is) in that it only loads one HandlerExceptionResolver implementation at any one time. The default implementation is AnnotationMethodHandlerExceptionResolver as mentioned in my previous blogs, which forces you to make a choice between using fine-grained exception handling as provided by AnnotationMethodHandlerExceptionResolver and more coarse grain exception handling provided by SimpleMappingExceptionHandler.
The Guy’s at Spring have made adding a SimpleMappingExceptionHandler to your app fairly straight forward. To demonstrate this I first of all need a flakey controller that will throw an exception for us. The code below, lifted from my previous blog, throws an IOException when called...
...and is guaranteed to break a webapp1
If you were intending to keep things ultra-simple, the final step would be to add the following XML to your Spring config file:
The XML above shows a very familiar Spring bean definition. The bean name is “exceptionResolver”, implemented by the SimpleMappingExceptionResolver class. This class has a map property, which is the most interesting part of this definition as it maps an exception class to a view name. In the sample I’m mapping IOException to a view called ‘io-exception’ and all other exceptions to a view called ‘generic-error’. Note that SimpleMappingExceptionHandler follows the standard Java exception handling rules, so when I say ‘all other exceptions’ I really mean all exceptions except IOException and its subclasses.
Although that about wraps it up for a trivial implementation. I’d like to add that I prefer to extend SimpleMappingExceptionHandler so that I can add in additional functionality, such as application specific error logging:
Once you’ve written your own exception handler, then all you have to do is to modify your Spring config so that it’s picked up by Spring when the webapp loads:
1 The full code for this blog is available from:
git://github.com/roghughe/captaindebug.git
The SimpleMappingExceptionHandler is an implementation of Springs HandlerExceptionResolver class, which, as I’ve mentioned before, Spring uses to manage exceptions thrown by your code. Spring has a limitation (if that’s what it is) in that it only loads one HandlerExceptionResolver implementation at any one time. The default implementation is AnnotationMethodHandlerExceptionResolver as mentioned in my previous blogs, which forces you to make a choice between using fine-grained exception handling as provided by AnnotationMethodHandlerExceptionResolver and more coarse grain exception handling provided by SimpleMappingExceptionHandler.
The Guy’s at Spring have made adding a SimpleMappingExceptionHandler to your app fairly straight forward. To demonstrate this I first of all need a flakey controller that will throw an exception for us. The code below, lifted from my previous blog, throws an IOException when called...
@RequestMapping(value = "/ioexception", method = RequestMethod.GET) public String throwAnIOException(Locale locale, Model model) throws IOException { logger.info("This will throw an IOException"); boolean throwException = true; if (throwException) { throw new IOException("This is my IOException"); } return "home"; }
...and is guaranteed to break a webapp1
If you were intending to keep things ultra-simple, the final step would be to add the following XML to your Spring config file:
<beans:bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <beans:property name="exceptionMappings"> <beans:map> <beans:entry key="java.io.IOException" value="io-exception" /> <beans:entry key="java.lang.Exception" value="generic-error" /> </beans:map> </beans:property> </beans:bean>
The XML above shows a very familiar Spring bean definition. The bean name is “exceptionResolver”, implemented by the SimpleMappingExceptionResolver class. This class has a map property, which is the most interesting part of this definition as it maps an exception class to a view name. In the sample I’m mapping IOException to a view called ‘io-exception’ and all other exceptions to a view called ‘generic-error’. Note that SimpleMappingExceptionHandler follows the standard Java exception handling rules, so when I say ‘all other exceptions’ I really mean all exceptions except IOException and its subclasses.
Although that about wraps it up for a trivial implementation. I’d like to add that I prefer to extend SimpleMappingExceptionHandler so that I can add in additional functionality, such as application specific error logging:
public class SampleExceptionHandler extends SimpleMappingExceptionResolver { private static final Logger logger = LoggerFactory.getLogger(SampleExceptionHandler.class); /** * Log the exception. * * @see org.springframework.web.servlet.handler.SimpleMappingExceptionResolver#doResolveException(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse, java.lang.Object, * java.lang.Exception) */ @Override protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { logger.error("A " + ex.getClass().getSimpleName() + " has occured in the application", ex); return super.doResolveException(request, response, handler, ex); } }
Once you’ve written your own exception handler, then all you have to do is to modify your Spring config so that it’s picked up by Spring when the webapp loads:
<!-- Definition(s) for the SimpleMappingExceptionResolver --> <beans:bean id="exceptionResolver" class="com.captaindebug.exceptions.SampleExceptionHandler"> <beans:property name="exceptionMappings"> <beans:map> <beans:entry key="java.io.IOException" value="io-exception" /> <beans:entry key="java.lang.Exception" value="generic-error" /> </beans:map> </beans:property> </beans:bean>
1 The full code for this blog is available from:
git://github.com/roghughe/captaindebug.git
From http://www.captaindebug.com/2012/02/using-springs-simplemappingexceptionhan.html
Spring Framework
Opinions expressed by DZone contributors are their own.
Comments