Spring SimpleMappingExceptionResolver Example

In some badly coded applications, when an unknown exception occurs the application server usually displays the evil exception stack trace to the user in the 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.

1. Spring 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 every time this exception is thrown from anywhere into the application, we want to show a pre-determined view page /WEB-INF/views/error/authExceptionView.jsp. So the configuration would be:

<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 the last. If spring context detects any exception thrown from an application that is not listed in “exceptionMappings” properties list, then it will render the view /WEB-INF/views/error/genericView.jsp.

2. Demo

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

AuthException.java

public class AuthException extends RuntimeException {
   
  private Date date;
  private String message;
   
  //Setters and Getters
}

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 the 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, the application is now able to find correct views in case of exceptions. No more error stack traces in the front view.

Happy Learning !!

Comments

Subscribe
Notify of
guest
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

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.