Spring MVC SimpleMappingExceptionResolver Example

In some badly coded applications, when an unknown exception occurs then application server usually displays the evil exception stack trace to the user in webpage itself. In this case, users have nothing to do with this stack trace and complain that your application is not user friendly. Moreover, it can also prove a potential security risk, as you are exposing the internal method call hierarchy to users. Though a web application’s web.xml can be configured to display friendly JSP pages in case an HTTP error or class exception occur, Spring MVC supports a more robust approach to managing views for class exceptions.

HandlerExceptionResolver and SimpleMappingExceptionResolver

In a Spring MVC application, you can register one or more exception resolver beans in the web application context to resolve uncaught exceptions. These beans have to implement the HandlerExceptionResolver interface for DispatcherServlet to auto-detect them. Spring MVC comes with such a simple exception resolver i.e. SimpleMappingExceptionResolver to map each category of exceptions to a view in a configurable way.

Let’s say we have an exception class i.e. AuthException. And we want that everytime this exception is thrown from anywhere into application, we want to show a pre-determined view page /WEB-INF/views/error/authExceptionView.jsp. So the configuration would be.

SimpleMappingExceptionResolver configuration

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
	<property name="exceptionMappings">
		<props>
			<prop key="com.howtodoinjava.demo.exception.AuthException">
				error/authExceptionView
			</prop>
		</props>
	</property>
	<property name="defaultErrorView" value="error/genericView"/>
</bean>

The complete context configuration is :

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-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.howtodoinjava.demo" />

	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
	<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
	
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
	</bean>
	
	<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
	    <property name="basename" value="messages" />
	</bean>
	
	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
	    <property name="exceptionMappings">
	        <props>
	            <prop key="com.howtodoinjava.demo.exception.AuthException">
	                error/authExceptionView
	            </prop>
	        </props>
	    </property>
    	<property name="defaultErrorView" value="error/genericView"/>
	</bean>

</beans>

Notice the “defaultErrorView” property in last. If spring context detects any exception thrown from application which is not listed into “exceptionMappings” properties list, then it will render the view /WEB-INF/views/error/genericView.jsp.

Test SimpleMappingExceptionResolver Configured Application

For testing purpose, let’s create AuthException.java.

AuthException.java

package com.howtodoinjava.demo.exception;

import java.util.Date;

public class AuthException extends RuntimeException 
{
	private static final long serialVersionUID = 1L;
	
	private Date date;
	private String message;
	
	public AuthException(Date date, String message) {
		super();
		this.date = date;
		this.message = message;
	}

	public Date getDate() {
		return date;
	}

	public String getMessage() {
		return message;
	}

	@Override
	public String toString() {
		return "AuthException [date=" + date + ", message=" + message + "]";
	}
}

And throw this exception from any controller.

EmployeeController.java

@Controller
@RequestMapping("/employee-module")
public class EmployeeController 
{
	@RequestMapping(value="/getAllEmployees", method = RequestMethod.GET)
    public String welcome(Model model) 
	{
		throw new AuthException(new Date(), "Something bad happened dude !! Run Away :-(");
    }
}

And create two jsp files in path /WEB-INF/views/error/

authExceptionView.jsp

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

		<h2>Exception occured at: </h2><fmt:formatDate value="${exception.date}" pattern="yyyy-MM-dd" />
		<h2>Exception Message   : </h2>${exception.message}
	</body>
</html>

genericView.jsp

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<html>
	<head>
		<title>Generic Exception</title>
	</head>
	<body>
		<h2>Some generic error message</h2>
	</body>
</html>

And now hit the URL : http://localhost:8080/springmvcexample/employee-module/getAllEmployees

SimpleMappingExceptionResolver Example
SimpleMappingExceptionResolver Example

Now throw any other exception from controller such as NullPointerException as below.

@Controller
@RequestMapping("/employee-module")
public class EmployeeController 
{
	@RequestMapping(value="/getAllEmployees", method = RequestMethod.GET)
    public String welcome(Model model) 
	{
		throw new NullPointerException();
    }
}

And hit again the URL : http://localhost:8080/springmvcexample/employee-module/getAllEmployees

SimpleMappingExceptionResolver Generic Error Example
SimpleMappingExceptionResolver Generic Error Example

Clearly, application is now able to find correct views in case of exceptions. No more error stack traces in front view.

Happy Learning !!

2 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

Comments are closed for this article!

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.