Spring MVC - Exception Handling

Last Updated : 19 Jan, 2026

Exception handling in Spring MVC allows developers to handle runtime errors gracefully and return meaningful responses instead of application crashes. It helps in building robust, user-friendly, and maintainable web applications.

  • Prevents application failure due to unhandled runtime exceptions
  • Provides centralized and reusable error-handling mechanisms

Types of Exception Handling in Spring MVC

Spring MVC supports the following approaches:

1. Try–Catch Block

Try–catch is the most basic way of handling exceptions directly inside controller methods.

Java
@RequestMapping("/welcome")
public String processForm(@ModelAttribute Student student, Model model) {
    try {
        int roll = Integer.parseInt(student.getRollNo());
        model.addAttribute("roll", roll);
        return "welcome";
    } catch (NumberFormatException e) {
        model.addAttribute("err", "Invalid Roll Number");
        return "error";
    }
}

Key points:

  • Simple and easy to understand
  • Handles exceptions locally within the method
  • Not suitable for large applications

2. @ExceptionHandler

@ExceptionHandler handles specific exceptions at the controller level.

Java
@ExceptionHandler(NumberFormatException.class)
public String handleNumberFormat(Model model) {
    model.addAttribute("err", "Number Format Exception");
    return "error";
}

Drawbacks:

  • Cleaner than try–catch
  • Handles exceptions for a single controller
  • Improves code readability
  • Limited to one controller

3. @ControllerAdvice

@ControllerAdvice provides global exception handling across all controllers.

Example:

Java
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(NullPointerException.class)
    public String handleNull(Model model) {
        model.addAttribute("err", "Null Pointer Exception");
        return "error";
    }
}

Key points:

  • Centralized error handling
  • Applies to all controllers
  • Reduces duplicate code
  • Less control over individual controllers

4. @ResponseStatus

@ResponseStatus maps exceptions directly to HTTP status codes.

Example:

Java
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
}

Key Points:

  • Simple mapping to HTTP status
  • No extra handler methods required
  • Useful for REST APIs
  • Not suitable for complex error responses

5. HandlerExceptionResolver

HandlerExceptionResolver is a low-level interface for custom exception resolution.

Example:

Java
public class MyExceptionResolver implements HandlerExceptionResolver {
    public ModelAndView resolveException(
        HttpServletRequest request,
        HttpServletResponse response,
        Object handler,
        Exception ex) {

        ModelAndView mv = new ModelAndView("error");
        mv.addObject("err", ex.getMessage());
        return mv;
    }
}

Key Points:

  • Full control over exception handling
  • Works before controller execution ends
  • Highly customizable
  • More complex to implement

6. Spring Boot Default Exception Handling

Spring Boot provides built-in exception handling via BasicErrorController.

Example: No custom code required-Spring Boot automatically returns error responses like:-

{
"status": 404,
"error": "Not Found",
"path": "/invalid-url"
}

Key Points:

  • Enabled by default
  • Auto-configured error responses
  • Best for quick REST applications
  • Not suitable for custom UI error pages

Steps to Create the Application

Step 1: Create a Maven Web Application

  1. Open Eclipse IDE
  2. Create a New Maven Project
  3. Select maven-archetype-webapp
  4. Enter Group Id and Artifact Id
  5. Click Finish

After project creation, the basic project structure is generated automatically.

After clicking finish your project structure would look something like this:

Step 2: Project Structure

 After adding all the classes and configuration files your project would look something like this:

Screenshot20220304at114634PM
Project Structure

Step 3: Configure pom.xml

The pom.xml is auto-created with any maven project, it defines all the dependencies required for the project. Make sure to add all the dependencies mentioned in this file.

XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="https://maven.apache.org/POM/4.0.0
                             https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.gfg</groupId>
  <artifactId>SpringMvcExceptionHandling</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>SpringMvcExceptionHandling Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>  
        <groupId>org.springframework</groupId>  
        <artifactId>spring-webmvc</artifactId>  
        <version>5.1.1.RELEASE</version>  
    </dependency>  
    <dependency>  
        <groupId>org.apache.tomcat</groupId>  
        <artifactId>tomcat-jasper</artifactId>  
        <version>9.0.12</version>  
    </dependency>  
    <dependency>    
        <groupId>javax.servlet</groupId>    
        <artifactId>servlet-api</artifactId>    
        <version>3.0-alpha-1</version>    
    </dependency>  
    <dependency>  
        <groupId>javax.servlet</groupId>  
        <artifactId>jstl</artifactId>  
        <version>1.2</version>  
    </dependency>  
  </dependencies>

  <build>
    <finalName>SpringMvcExceptionHandling</finalName>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

Step 4: Configure web.xml

The web.xml file maps incoming requests to the DispatcherServlet, which is the front controller of Spring MVC.

XML
<web-app xmlns="http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html" 
         xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html 
                        http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    
    <servlet>
        <servlet-name>gfg</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/gfg-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>gfg</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

Step 5: Configure Spring MVC (gfg-servlet.xml)

This file enables:

  • Component scanning
  • Annotation-driven MVC
  • View resolution for JSP files
XML
<beans xmlns="http://www.springframework.org/schema/beans/"
    xmlns:context="http://www.springframework.org/schema/context/"
    xmlns:mvc="http://www.springframework.org/schema/mvc/"
    xmlns:xsi="https://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/mvc/ 
                        http://www.springframework.org/schema/mvc//spring-mvc.xsd
                        http://www.springframework.org/schema/context/ \
                        http://www.springframework.org/schema/context//spring-context.xsd">

    <context:component-scan base-package="com.gfg" />
     <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/views/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
    <mvc:annotation-driven />
    
</beans>

Step 6: Create the Model Class (Student)

The rollNo field is intentionally kept as String to demonstrate a NumberFormatException.

Java
package com.gfg.model;
public class Student {

    private String firstName;
    private String lastName;
    private String rollNo;

    public Student(String firstName, String lastName,
                   String rollNo)
    {
        super();
        this.firstName = firstName;
        this.lastName = lastName;
        this.rollNo = rollNo;
    }

    public Student() {}

    public String getFirstName() { return firstName; }

    public void setFirstName(String firstName)
    {
        this.firstName = firstName;
    }

    public String getLastName() { return lastName; }

    public void setLastName(String lastName)
    {
        this.lastName = lastName;
    }

    public String getRollNo() { return rollNo; }

    public void setRollNo(String rollNo)
    {
        this.rollNo = rollNo;
    }
}

Step 7:Create Controller with Method-Level Exception Handling

  • The LoginController has two methods: showForm (GET) to display the login form, and processForm to handle form data using @ModelAttribute and Model. 
  • The rollNo field in the Student class is a String but parsed to int, which may throw a NumberFormatException if it's empty or contains letters.
  • To handle this, a method numberformatHandler is defined with @ExceptionHandler(NumberFormatException.class) to catch the error and improve user experience. 
Java
package com.gfg.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 com.gfg.model.Student;

@Controller
public class LoginController {
    
    @RequestMapping("/login")
    public String showForm(Model theModel) {
        theModel.addAttribute("student", new Student());
        return "portal";
    }
    @RequestMapping("/welcome")
    public String processForm(@ModelAttribute("welcome") Student student, Model mod) {    
        mod.addAttribute("FirstName", student.getFirstName());
        mod.addAttribute("LastName", student.getLastName());        
        int n = Integer.parseInt(student.getRollNo());
        mod.addAttribute("RollNo", n);    
        return "welcome";
    }
      @ExceptionHandler(value = NumberFormatException.class)
    public String numberformatHandler(Model theModel) {        
        theModel.addAttribute("err", "NumberFormatException");
        return "error";
    }
}

Step 8: Global Exception Handling Using @ControllerAdvice

  • The MyExceptionHandler class handles all exceptions in the app and shows user-friendly error pages.
  • By adding @ControllerAdvice, it applies to all controllers, allowing Spring MVC to use custom error methods instead of server-generated pages. This is an example of class-level exception handling.
Java
package com.gfg.errorhandler;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class MyExceptionHandler {
    
    @ExceptionHandler(value = NullPointerException.class)
    public String nullPointerHandler(Model theModel) {
        theModel.addAttribute("err", "NullPointerException");
        return "error";
    }
    
    @ExceptionHandler(value = Exception.class)
    public String AnyOtherHandler() {
        return "error";
    }
}

Step 9: Create JSP Views

This file in the views folder defines the Student login portal. 

portal.jsp

HTML
<%@ taglib prefix="form" url="http://www.springframework.org/tags/form" %>  

 <html>  
<head>  
</head>  
<body>  
    <h1>Student Portal</h1>
    <form:form action="welcome" modelAttribute="student">  
       <label>First name:</label>
         <form:input path="firstName" />
        <br><br>  
        
         <label>Last name:</label> 
         <form:input path="lastName" />  
        <br><br>    
        
         <label>Roll No:</label>
          <form:input path="rollNo" /> 
         <br><br>    
     
        <input type="submit" value="Submit" />  
      
    </form:form>  
</body>  
</html>  

welcome.jsp:

This page in the views folder defines the welcome page for our application.

HTML
<%@ taglib prefix="form" url="http://www.springframework.org/tags/form" %>  

 <html>  
<head>  
</head>  
<body>  
    <h1>Student Portal</h1>
    <form:form action="welcome" modelAttribute="student">  
       <label>First name:</label>
         <form:input path="firstName" />
        <br><br>  
        
         <label>Last name:</label> 
         <form:input path="lastName" />  
        <br><br>    
        
         <label>Roll No:</label>
          <form:input path="rollNo" /> 
         <br><br>    
     
        <input type="submit" value="Submit" />  
      
    </form:form>  
</body>  
</html>  

error.jsp

This page is a simple exception handler page that defines the name of the exception and informs the user about an exception.

HTML
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>Opps....</h1> 
    <h1> ${err} Exception caused</h1>
</body>
</html>

Step 10: Run the Application

Deploy the application on Apache Tomcat and access:

http://localhost:8080/SpringMvcExceptionHandling/login

Enter invalid roll number data to trigger exceptions.

Screenshot20220305at120030AM-660x577

When Roll No is invalid:

Screenshot20220305at120037AM-660x577
Exception occured

Fill Correct data:

Screenshot20220304at115959PM-660x577


Screenshot20220305at120005AM-660x577


Suggested Quiz

0 Questions

Quiz Completed Successfully

Your Score : 0/0

Accuracy : 0%

Comment