Spring MVC Exception Handling Example

In J2EE / servlet web application, you can map error page to specify exception like this :

web.xml

  <error-page>
	<error-code>404</error-code>
	<location>/WEB-INF/pages/404.jsp</location>
  </error-page>

  <error-page>
	<exception-type>com.mkyong.web.exception.CustomException</exception-type>
	<location>/WEB-INF/pages/error/custom_error.jsp</location>
  </error-page>
	
  <error-page>
	<exception-type>java.lang.Exception</exception-type>
	<location>/WEB-INF/pages/generic_error.jsp</location>
  </error-page>
  

The above code should be self-exploratory. If the exception handling function exists in the servlet container, why we still need to use the Spring to handle the exception?

Generally, there are two reasons :

  1. Customize Error Page – The servlet container will render the error page directly; While the Spring allows you to populate model or data to the error page, so that you can customize a more user friendly error page.
  2. Business logic – Spring allow you to apply extra business logic before rendering the error page, like logging, auditing and etc.

In this tutorial, we will show you two examples to handle the exception in Spring.

  1. For Spring 2.x, we use SimpleMappingExceptionResolver in the XML file.
  2. For Spring 3.x, we can simplify the XML configuration via @ExceptionHandler annotation.

1. SimpleMappingExceptionResolver Example

Review the directory structure.

spring-mvc-exception-example-directory

A custom exception.

CustomGenericException.java

package com.mkyong.web.exception;

public class CustomGenericException extends RuntimeException {

	private static final long serialVersionUID = 1L;

	private String errCode;
	private String errMsg;

	//getter and setter methods

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

}

This controller class, just throw a CustomGenericException with custom error code and error description.

CustomerController.java

package com.mkyong.web.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import com.mkyong.web.exception.CustomGenericException;

public class CustomerController extends AbstractController {

  @Override
  protected ModelAndView handleRequestInternal(HttpServletRequest request,
	HttpServletResponse response) throws Exception {

	throw new CustomGenericException("E888", "This is custom message - ABC");

  }

}

Review the SimpleMappingExceptionResolver below :

mvc-dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/mvc 
	http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<context:component-scan base-package="com.mkyong" />

	<bean
	class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

	<!-- Register the bean -->
	<bean class="com.mkyong.web.controller.CustomerController" />

	<bean
	  class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
	  <property name="exceptionMappings">
		<props>
			<prop key="com.mkyong.wb.exception.CustomGenericException">
				error/generic_error
			</prop>
			<prop key="java.lang.Exception">error/exception_error</prop>
		</props>
	  </property>
	</bean>

	<bean
	  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/pages/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>

	<mvc:annotation-driven />

</beans>

In above, when

  1. CustomGenericException is thrown, it will map to the view name “error/generic_error”.
  2. Any other Exceptions is thrown, it will map to the view name “error/exception_error”.

In the JSP page, you can access the exception instance via ${exception}.

pages/error/generic_error.jsp.jsp

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

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

	<c:if test="${not empty exception.errMsg}">
		<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-format="fluid"
     data-ad-layout="in-article"
     data-ad-client="ca-pub-2836379775501347"
     data-ad-slot="6894224149"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script><h2>${exception.errMsg}</h2>
	</c:if>
	
</body>
</html>

Demo – http://localhost:8080/SpringMvcExample/customer

spring-mvc-exception-handle-1

2. @ExceptionHandler Example

Since Spring 3.0, there is a new annotation @ExceptionHandler to simplify the XML configuration. Below is the equivalent version using @ExceptionHandler.

CustomerController.java

package com.mkyong.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
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 CustomerController {

	@RequestMapping(value = "/customer", method = RequestMethod.GET)
	public ModelAndView getPages() throws Exception {

		throw new CustomGenericException("E888", "This is custom message X");

	}

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

		ModelAndView model = new ModelAndView("error/generic_error");
		model.addObject("exception", ex);
		return model;

	}

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

		ModelAndView model = new ModelAndView("error/exception_error");
		return model;

	}

}

Nothing to declare in Spring XML file.

mvc-dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/mvc 
		http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<context:component-scan base-package="com.mkyong" />

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/pages/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>

	<mvc:annotation-driven />

</beans>
Note
You may interest at this Spring MVC @ExceptionHandler Example

Reference

  1. SimpleMappingExceptionResolver JavaDoc
  2. @ExceptionHandler JavaDoc
  3. Spring MVC @ExceptionHandler Example

About the Author

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

Comments

Leave a Reply

avatar
newest oldest most voted
danstorre
Guest
danstorre

I got to say Man mkyong you’re great thaks for this tutorial!

arun singh
Guest
arun singh

thanks for the information.

Erico Souza
Guest
Erico Souza

it’s great, but you have a example that don’t use web.xml, and the configuration it’s in java code, extends AbstractAnnotationConfigDispatcherServletInitializer or extends WebMvcConfigureAdapter?

trackback
Spring MVC Tutorial

[…] Exception handling example Exception handling in Spring MVC. […]

Sahar
Guest
Sahar

More than helpful, as always!
Thanks a lot!

Sanjib
Guest
Sanjib

Hi MK,

This solution is working only for those methods in controller which has ModelAndView as return type ,but in case of Responseentity this exception handling is not working.

Please tell how to show that error page if the exception has occurred in Response entity return type method.

Thankx

Sandeep
Guest
Sandeep

Thanks Yong..
have read atleast 4 articles of urs which have helped me learn concepts very fast.

Thanks for sharing.

Ganesh K Thiagarajan
Guest
Ganesh K Thiagarajan
Dear MkYong Our application has the following layers and interaction: View (JSP) -> Ajax calls -> MyController (implements Spring Controller) -> through a custom service lookup -> MyService (implements Base Service) -> My DAOimpl Our idea is to use AOP for logging exceptions. To keep the AOP intercepts simple, we decided to define the cuts on the Controllers. The Controllers have a few methods like onLoad, onUpdate (related to CRUD ops) which are called from the handleRequest method, and we would like to define these methods for the poitncut. Ie., any exception at the Service layer or below, will bubble… Read more »
Ganesh K Thiagarajan
Guest
Ganesh K Thiagarajan
Hi , I would like to apply AOP for logging the error messages using Spring Framework. By configuring for service and dao layers AOP happens to work for what so ever methods configured, but fails in Controller Layer. Experimented with in Controller ,but noticed the cut happens only with the handelRequest(). Please advice me on how to apply on methods that are defined by me.. Ex: I have methods by name onLoad(), onSave()… public class MyController extends BaseController(){ public void onLoad(…){} public void onSave(…){} } public class BaseController implements Controller{ public abstract void onLoad(…); public abstract void onSave(…); public ModelAndView… Read more »
Allan Story
Guest
Allan Story

hello guys! this is an awesome tutorial, thanks!

but I have a doubt, is possible in case of a com.mkyong.common.exception.GenericException, redirect the “process” for a Controller?

This example for this is that every error generated send an email to the web master.

Thank you in advance!

Anshu
Guest
Anshu

how can i get a common error page to handle any exception than doesn’t lies within the defined exceptions in our xml file.

Chandrakant
Guest
Chandrakant

Thank you so much for your help I did the same but I got stuck in one problem
Please help me out.
When java runtime exception rised then the error page get open in the parent dialog.
I want to open error.jsp file in new tab as well as I want to close the session and redirect user to login page!!!
How can I achieve this??
Please help

batz
Guest
batz

thx for the tutorial.

Jonatan
Guest
Jonatan

First of all, thanks a lot for your tutorials. You are doing a very good job sharing this and I really appreciate.

I found a strange behavior using UrlBasedViewResolver with an specific viewClass, for Tiles2 purposes, instead of InternalResourceViewResolver. Its always resolved to the prop defined with the java.lang.Exception and never goes to the xxx.xxx.xxx.GenericException.
One thing I’ve noticed is when I put a breakpoint in the handleRequestInternal of the controller class, the program never stops there when an exception is produced.

Do you have any idea why may be the reason?

TIA