How to handle exceptions in spring 3 mvc using @ExceptionHandler annotation

Exception handling is very essential feature of any java program. Every good open source framework allows to write the exception handlers in such a way that you can separate then from your application code. Well, Spring 3 also allows you to do so using annotation @ExceptionHandler.  Lets see how all this works.

For demonstration, I am adding exception handler in already build code for this article [related to implementing interceptors in spring 3]. So in case any query to project files, please refer to linked post.

Download source code for this article

Adding exception handler

For this all you need is to define a method in your controller class and use the annotation @ExceptionHandler on it. Spring’s configuration will detect this annotation and register the method as exception handler for given exception and all of its subclasses. There are as such no other guidelines only related to method request and response parameters.

@ExceptionHandler(NullPointerException.class)
public ModelAndView handleException(NullPointerException ex)
{
	//Do something additional if required
	ModelAndView modelAndView = new ModelAndView();
	modelAndView.setViewName("error");
	modelAndView.addObject("message", ex.getMessage());
	return modelAndView;
}

Now every time, controller encounter above exception in request processing for any web request, control will automatically come to this handler method.

For example, below URL is intentionally returning NullPointerException.

@RequestMapping(value="/demo/not-exist", method = RequestMethod.GET,  headers="Accept=*/*")
public @ResponseBody ModelAndView oneFaultyMethod()
{
	if(true)
	{
		throw new NullPointerException("This error message if for demo only.");
	}
	//Dead code
	//Read more: http://howtodoinjava.com/2012/11/28/dead-code-and-unreachable-code-in-java-puzzle/
	return null;
}

If we deploy above application and hit the URL [http ://localhost:8080/firstSpringApplication/users/demo/not-exist] in browser, it will show the error page as configured.

< %@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
< %@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
< %@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
< %@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql" %>


	<head>
		<title>This is sample error page</title>
	</head>
	<body>
		<h1>This is sample error page : <c:out value="${message}"></c:out></h1>
	</body>

Below will be the output in browser.

message-on-browser

Handling multiple exceptions of different types

As mentioned earlier, above exception handler will handle all exceptions which are either instance of given class or sub-classes of it. But, if you want to configure multiple exceptions of different types, then you can specify all such exceptions in form of array.

@ExceptionHandler({NullPointerException.class, ArrayIndexOutOfBoundsException.class, IOException.class})
public ModelAndView handleException(NullPointerException ex)
{
	//Do something additional if required
	ModelAndView modelAndView = new ModelAndView();
	modelAndView.setViewName("error");
	modelAndView.addObject("message", ex.getMessage());
	return modelAndView;
}

Download source code for this article

Recommended Reading : http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html

Happy Learning !!

Lokesh

I have 7 Years of rich experience in java technology. This has only increased my hunger to learn more. In this blog, i will be writing on different topics occasionally, and would love to engage in some meaningful serious discussions with you folks.

You may also like...

3 Responses

  1. Puneet says:

    Hi Lokesh, I have a little confussion in this exception handling… i have a controller which have 5-8 @RequestMapping annotations(ModelAndView methods). if i use 1 @ExceptionHandler(Exception.class) for this controller, does it handles any exception which comes in this controller?

  2. Hi Lokesh,

    I appreciate your work on Spring 3 . Good work keep it up.
    past 7 years I have been practicing java -j2ee working with reputed organization
    I have few questions on Spring Annotation , would like to discuss with you ,please provide me your valuable reply on those .

    1)@Configuration is introduced in Spring3 , which is the primary class reading that annotation and doing all necessary steps like instantiation , wiring and disposing bean .
    2)pls observe below code snippet which does creation of bean and disposing bean

    /*
    * To change this license header, choose License Headers in Project Properties.
    * To change this template file, choose Tools | Templates
    * and open the template in the editor.
    */

    package annotationparser;

    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;

    /**
    *
    * @author chinni
    */
    public class AnnotationParser {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) throws ClassNotFoundException {
    // TODO code application logic here

    Class aimpl= (Class) Configuration.class.getClassLoader().loadClass(Configuration.class.getName());
    Annotation a[]= aimpl.getDeclaredAnnotations();
    for(Annotation m :a){
    System.out.println(m.getDeclaredAnnotations()[0]);
    }
    }
    }

    using bove code we can get list of all configuration classes and we can instantiate object and return back

    3)is it possible to invoke super class constructor using java.lang.reflect , if yes please send me the code
    snippet

    4) same question on this keyword
    5) can we write annotations to inject Author and date time stamp on the fly ?

    I am working on big project with Annotations , hence I have got all these questions . pls reply me back

    Thanks
    Sitaram Venkata
    Hyderabad

Note:- In comment box, please put your code inside [java] ... [/java] OR [xml] ... [/xml] tags otherwise it may not appear/post as intended.


Want to ask any question? Or suggest anything?