How to handle Exception in Spring MVC?

So far we have seen all the concepts related to Spring MVC. If you haven’t check it yet please check this Introduction to Spring Framework. In this article of this tutorial, we will understand How to handle exceptions in Spring MVC.

As we know, an Exception is an unwanted event that arises during the execution of a program, therefore these need to be handled in the program.

The Unwanted Exception can be thrown at run time. So it’s the developer’s responsibility to handle it in the code. In fact, in Spring MVC, Handling Exceptions is quite easy as we don’t have to do lots of stuff. In Spring Framework, Spring provides two approaches to handle the exception.

  •  XML Based Approach: In this, we just need to declare a bean called  SimpleMappingExceptionResolver in the config file and then map the exception type with the view.
  • Exception Handler method: In this, we just need to add an annotation type @ExceptionHandler.

Here, we will use the 2nd approach from the above-mentioned.

How to Handle Exception in Spring MVC?

In Spring MVC, Exception is handled using @ExceptionHandler annotation. This annotation is used on the controller class or handler methods. Spring configuration will detect this annotation and register the method as an exception handler.

Steps to Handle Exception

  • Create an Exception Class and add the annotation @ControllerAdvice.
  • Add the ExceptionHandler method with Exception as an argument and return the error view.

Example to handle Exception in Spring MVC

In this example, we will create a form student and will accept the name, age. if the age we entered in the string it should throw an exception and that exception thrown will be handled by @ExceptionHandler.

Create a Spring Project Go to File> New > Other > Search maven > Select Maven Project > Next > Search Filter org.apche.maven.archetypes/webapp > Next > Enter Group Id & Archetype id > Finish.

First, Create a pom.xml file to add all the dependencies needed for Spring MVC Configuration

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>co</groupId>
  <artifactId>SpringMVCExample</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>SpringMVCExample Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.5</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.3.5</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.3.5</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.3.5</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.3</version>
      <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.5</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>SpringMVCExample</finalName>
  </build>
</project>

Create a web.xml file

  •  Web.xml is a deployment descriptor that is used by the server to map the incoming request.
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>    
    <servlet-name>spring</servlet-name>    
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/Spring-servlet.xml</param-value>
    </init-param>   
    <load-on-startup>1</load-on-startup>      
</servlet>    
<servlet-mapping>    
    <servlet-name>spring</servlet-name>    
    <url-pattern>/</url-pattern>    
</servlet-mapping>  
</web-app>

Create a Spring-servlet.xml

  • Here, we have used <context:component-scan> detects the annotation by package scanning.
  • To resolves views such as JSP, we have used InternalResourceViewResolver.
<?xml version="1.0" encoding="UTF-8"?>
<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"
   xsi:schemaLocation="
   http://www.springframework.org/schema/beans     
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context.xsd">
   
   <!--  component scan -->
   <context:component-scan base-package="org.mvc.controller"></context:component-scan>
   
   
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/views/" />
      <property name="suffix" value=".jsp" />
  </bean>
   </beans>

Create a Model Class – Student.java

package org.mvc.controller;

import java.util.List;

public class Student {

  private String name;
  
  private int age;
  

  
  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

}

Create a Controller – HomeController.java

  • The @Controller here defines the class as Controller in SpringMVC.
  • The @RequestMapping is used to map the URL.
package org.mvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HomeController {

  @RequestMapping("/")
  public String home(Model m) {
    Student student = new Student();
    m.addAttribute("student", student);
    return "index";
  }

  @RequestMapping("/form")
  public String form(@ModelAttribute("student") Student student, Model m)  {
    
    System.out.println(student);
    
    return "result";

  }
  
}

Create a class MyCustomeException.java

  • Create an exception handler method to handle exceptions and return the error view page.
  • Use the @ExceptionHandler(Exception. class) on the method to handle exceptions.
  • Annotate the class with @ControllerAdvice that can be declared explicitly as Spring beans or auto-detected via classpath scanning.
package org.mvc.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class MyCustomeException{
  @ExceptionHandler(Exception.class)
  public String exceptionHandler(Exception e) {
    return "error";
  }
}

Create Views

index.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="f" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
 <style>
      .error {
         color: #ff0000;
      }

   </style>
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<title>Spring MVC</title>
</head>
<body style="background-color: #e2e2e2">
<div class="container mt-5">
  <div class="card " style="width: 25rem; ">
    <div class="card-body">
      <h5 class="card-title " align="center" >Student Form</h5>
      <f:form modelAttribute="student" action="form" method="post">
      <div class="form-group">
          <label for="exampleInputEmail1">Name</label>
          <f:input path="name" class="form-control" />
          
        </div>
        
        <div class="form-group">
          <label for="exampleInputEmail1">Age</label>
          <f:input path="age" class="form-control" />
        </div>
        <br>
        <div class="form-group mt-2 ">
        <center>	<input type="submit" value="Submit" class="btn btn-warning"></center>
        </div>

      </f:form>

    </div>
  </div>
</div>	
</body>
</html>

errror.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body  style="background-color: #e2e2e2">
<center><h1>Oops!! Something went Wrong</h1></center>
<br>
<p><center><h3>Please try again later..</h3></center></p>

</body>
</html>

result.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body style="background-color: #e2e2e2">
Welcome!!!
</body>
</html>

Now, deploy the application on the server and see the following output

Thus, in this way we handle exceptions in spring using @ExceptonHandler.