Main Tutorials

Spring MVC @ExceptionHandler Example

In this tutorial, we show you how to do exception handling in Spring MVC frameworks. Normally, we use @ExceptionHandler to decide which “view” should be returned back if certain exception is raised.

P.S This @ExceptionHandler class is available since Spring 3.0

1. Project Structure

Review the project directory structure, a standard Maven project.

directory structure

2. Custom Exception

A custom exception, with custom error code and error description.

CustomGenericException.java

package com.mkyong.web.exception;

public class CustomGenericException extends RuntimeException {

	private static final long serialVersionUID = 1L;

	private String errCode;
	private String errMsg;

	public String getErrCode() {
		return errCode;
	}

	public void setErrCode(String errCode) {
		this.errCode = errCode;
	}

	public String getErrMsg() {
		return errMsg;
	}

	public void setErrMsg(String errMsg) {
		this.errMsg = errMsg;
	}

	public CustomGenericException(String errCode, String errMsg) {
		this.errCode = errCode;
		this.errMsg = errMsg;
	}

}

3. Spring Controller

A Spring controller, review the execution-flows below :

  1. If user provide a /error request, it throws “CustomGenericException”, and the handleCustomException() method will be fired.
  2. If user provide a /io-error request, it throws “IOException”, and the handleAllException() method will be fired.
MainController.java

package com.mkyong.web.controller;

import java.io.IOException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.mkyong.web.exception.CustomGenericException;

@Controller
public class MainController {

	@RequestMapping(value = "/{type:.+}", method = RequestMethod.GET)
	public ModelAndView getPages(@PathVariable("type") String type)
		throws Exception {

	  if ("error".equals(type)) {
		// go handleCustomException
		throw new CustomGenericException("E888", "This is custom message");
	  } else if ("io-error".equals(type)) {
		// go handleAllException
		throw new IOException();
	  } else {
		return new ModelAndView("index").addObject("msg", type);
	  }

	}

	@ExceptionHandler(CustomGenericException.class)
	public ModelAndView handleCustomException(CustomGenericException ex) {

		ModelAndView model = new ModelAndView("error/generic_error");
		model.addObject("errCode", ex.getErrCode());
		model.addObject("errMsg", ex.getErrMsg());

		return model;

	}

	@ExceptionHandler(Exception.class)
	public ModelAndView handleAllException(Exception ex) {

		ModelAndView model = new ModelAndView("error/generic_error");
		model.addObject("errMsg", "this is Exception.class");

		return model;

	}

}

4. JSP Pages

pages/index.jsp

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
	<h2>Spring MVC @ExceptionHandler Example</h2>

	<c:if test="${not empty msg}">
		<h2>${msg}</h2>
	</c:if>
	
</body>
</html>
pages/error/generic_error.jsp

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>

	<c:if test="${not empty errCode}">
		<h1>${errCode} : System Errors</h1>
	</c:if>
	
	<c:if test="${empty errCode}">
		<h1>System Errors</h1>
	</c:if>

	<c:if test="${not empty errMsg}">
		<h2>${errMsg}</h2>
	</c:if>
	
</body>
</html>

5. Testing

Review following 3 test cases :

1. http://localhost:8080/SpringMvcExample/anything

spring-exceptional-handle-result-normal

2. http://localhost:8080/SpringMvcExample/error

spring-exceptional-handle-result-error

3. http://localhost:8080/SpringMvcExample/io-error

spring-exceptional-handle-result-io-error

6. @ControllerAdvice Example

The above @ExceptionHandler example is only apply to a single controller, to apply it globally (all controllers), annotate a class with @ControllerAdvice.

GlobalExceptionController.java

package com.mkyong.web.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import com.mkyong.web.exception.CustomGenericException;

@ControllerAdvice
public class GlobalExceptionController {

	@ExceptionHandler(CustomGenericException.class)
	public ModelAndView handleCustomException(CustomGenericException ex) {

		ModelAndView model = new ModelAndView("error/generic_error");
		model.addObject("errCode", ex.getErrCode());
		model.addObject("errMsg", ex.getErrMsg());

		return model;

	}

	@ExceptionHandler(Exception.class)
	public ModelAndView handleAllException(Exception ex) {

		ModelAndView model = new ModelAndView("error/generic_error");
		model.addObject("errMsg", "this is Exception.class");

		return model;

	}
	
}

7. Download Source Code

References

  1. Spring @ExceptionHandler JavaDoc
  2. Spring @ControllerAdvice JavaDoc
  3. Spring MVC Exception Handling Example

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
13 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
UhhhBuddyuhh
5 years ago

The “handle All exceptions” scenario does Not work as that language specifically implies.

That handler for Exception.class Only handles the class “Exception” specifically, not everything under Exception.

Nobody has bothered clarifying this absolutely critical detail and that’s rather annoying because it makes all the difference in the world whether “Exception.class” in your annotation covers ALL EXCEPTIONS, or literally just Exception.class itself.

Tuanvn64
1 year ago

Hi
How to return one dialog with message “this is Exception.class in function handleAllException

and my page stay.

Rahul Singh
5 years ago

Hi I need 2 Exception handler in spring mvc. One for Web APIs which return Error page with html tags. Othe for the REST API which will return custom json data in response. How could I have both in same web application. Currently web application works on default /error page for any error.

arun singh
6 years ago

thanks

Raju Madanu
7 years ago

I am losing the stacktrace when the exception is handled in controlleradvice. Can you please advise?

Pankaj
7 years ago

How to deploy it in tomcat ? Please any body can help me. Thanks advance

Krishnan Chandrashekar
9 years ago

nice tutorial thanks

Naman
9 years ago

Thanks !

Kisna
10 years ago

This won’t catch any filter related exceptions that originate outside the controller scope, how would you handle exceptions in filter?

jackson
10 years ago

Nice! Can you tell me how to handle the AJAX call. Currently full error page is loaded in AJAX success dialog.

zofi
10 years ago

what is the code in javascript to go on picture’site and search images and display in a window

zeroo
10 years ago

Thanks !

James
8 years ago

Is it possible to make a generic exception handler for any class? I would like to implement an ExceptionHandler type solution for a listener class.