Exception Handling in Spring Boot
Last Updated :
23 Jul, 2025
Exception handling in Spring Boot helps deal with errors and exceptions present in APIs, delivering a robust enterprise application. This article covers various ways in which exceptions can be handled and how to return meaningful error responses to the client in a Spring Boot Project.
Key Approaches to Exception Handling in Spring Boot
Here are some key approaches to exception handling in Spring Boot:
- Default exception handling by Spring Boot
- Using @ExceptionHandler annotation
- Using @ControllerAdvice for global exception handling
Spring Boot Exception Handling Simple Example Project
Let's do the initial setup to explore each approach in more depth.
Initial Setup
To create a simple Spring Boot project using Spring Initializer, please refer to this article. Now let's develop a Spring Boot RESTful web service that performs CRUD operations on a Customer Entity. We will be using a MYSQL database for storing all necessary data.
Step 1: Creating a JPA Entity Class Customer
We will create a Customer class, which represents the entity for our database. The class is annotated with @Entity.
Java
// Creating a JPA Entity class Customer with
// three fields: id, name, and address
package com.customer.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String address;
private String email;
}
The Customer class is annotated with @Entity annotation and defines getters, setters, and constructors for the fields.
Step 2: Creating a CustomerRepository Interface
Next, we create the repository interface for CRUD operations on the Customer entity. This interface extends JpaRepository, which provides built-in methods for data access.
Java
// Creating a repository interface extending JpaRepository
package com.customer.repository;
import com.customer.model.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {
Optional<Customer> findByEmail(String email);
}
Note: The CustomerRepository interface is annotated with @Repository annotation and extends the JpaRepository of Spring Data JPA .
Step 3: Creating Custom Exceptions
Now, we will create two custom exceptions:
CustomerAlreadyExistsException: This exception can be thrown when the user tries to add a customer that already exists in the database.
Java
// Creating a custom exception that can be thrown when a user tries to add a customer that already exists
package com.customer.exception;
public class CustomerAlreadyExistsException extends RuntimeException {
private String message;
public CustomerAlreadyExistsException() {}
public CustomerAlreadyExistsException(String msg) {
super(msg);
this.message = msg;
}
}
NoSuchCustomerExistsException: This exception can be thrown when the user tries to delete or update a customer record that doesn't exist in the database.
Java
// Creating a custom exception that can be thrown when a user tries to update/delete a customer that doesn't exist
package com.customer.exception;
public class NoSuchCustomerExistsException extends RuntimeException {
private String message;
public NoSuchCustomerExistsException() {}
public NoSuchCustomerExistsException(String msg) {
super(msg);
this.message = msg;
}
}
Note: Both Custom Exception classes extend RuntimeException.
Step 4: Creating the Service Layer
The CustomerService interface defines three different methods:
- Customer getCustomer(Long id): To get a customer record by its id. This method throws a NoSuchElementException exception when it doesn't find a customer record with the given id.
- String addCustomer(Customer customer): To add details of a new Customer to the database. This method throws a CustomerAlreadyExistsException exception when the user tries to add a customer that already exists.
- String updateCustomer(Customer customer): To update details of Already existing Customers. This method throws a NoSuchCustomerExistsException exception when the user tries to update details of a customer that doesn't exist in the database.
The Interface and service implementation class is as follows:
CustomerService Interface:
Java
// Creating service interface
package com.customer.service;
import com.customer.model.Customer;
public interface CustomerService {
// Method to get customer by its Id
Customer getCustomer(Long id);
// Method to add a new Customer
// into the database
String addCustomer(Customer customer);
// Method to update details of a Customer
String updateCustomer(Customer customer);
}
CustomerServiceImpl Implementation:
Java
// Implementing the service class
package com.customer.service;
import com.customer.exception.CustomerAlreadyExistsException;
import com.customer.exception.NoSuchCustomerExistsException;
import com.customer.model.Customer;
import com.customer.repository.CustomerRepository;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerRepository customerRespository;
// Method to get customer by Id. Throws
// NoSuchElementException for invalid Id
public Customer getCustomer(Long id) {
return customerRespository.findById(id).orElseThrow(
() -> new NoSuchElementException("NO CUSTOMER PRESENT WITH ID = " + id));
}
// Simplifying the addCustomer and updateCustomer
// methods with Optional for better readability.
public String addCustomer(Customer customer) {
Optional<Customer> existingCustomer = customerRespository.findById(customer.getId());
if (!existingCustomer.isPresent()) {
customerRespository.save(customer);
return "Customer added successfully";
} else {
throw new CustomerAlreadyExistsException("Customer already exists!!");
}
}
public String updateCustomer(Customer customer) {
Optional<Customer> existingCustomer = customerRespository.findById(customer.getId());
if (!existingCustomer.isPresent()) {
throw new NoSuchCustomerExistsException("No Such Customer exists!!");
} else {
existingCustomer.get().setName(customer.getName());
existingCustomer.get().setAddress(customer.getAddress());
customerRespository.save(existingCustomer.get());
return "Record updated Successfully";
}
}
}
Step 5: Creating the CustomerController
The controller exposes RESTful endpoints for customer-related operations. The methods in this class will throw exceptions, which we will handle using various exception handling techniques.
Java
// Creating Rest Controller CustomerController which
// defines various API's.
package com.customer.controller;
import com.customer.exception.CustomerAlreadyExistsException;
import com.customer.exception.ErrorResponse;
import com.customer.exception.NoSuchCustomerExistsException;
import com.customer.model.Customer;
import com.customer.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CustomerController {
@Autowired private CustomerService customerService;
// Get Customer by Id
@GetMapping("/getCustomer/{id}")
public Customer getCustomer(@PathVariable("id") Long id) {
return customerService.getCustomer(id);
}
// Add new Customer
@PostMapping("/addCustomer")
public String addcustomer(@RequestBody Customer customer) {
return customerService.addCustomer(customer);
}
// Update Customer details
@PutMapping("/updateCustomer")
public String updateCustomer(@RequestBody Customer customer) {
return customerService.updateCustomer(customer);
}
// Adding exception handlers for NoSuchCustomerExistsException
// and NoSuchElementException.
@ExceptionHandler(value = NoSuchCustomerExistsException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleNoSuchCustomerExistsException(NoSuchCustomerExistsException ex) {
return new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
}
@ExceptionHandler(value = NoSuchElementException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleNoSuchElementException(NoSuchElementException ex) {
return new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
}
}
Handling Exceptions in Spring Boot
Now let's go through the various ways in which we can handle the Exceptions thrown in this project.
1. Default Exception Handling by Spring Boot
The getCustomer() method defined by CustomerController is used to get a customer with a given Id. It throws a NoSuchElementException when it doesn't find a Customer record with the given id. On Running the Spring Boot Application and hitting the /getCustomer API with an Invalid Customer Id, we get a NoSuchElementException completely handled by Spring Boot as follows:

Spring Boot provides a systematic error response to the user with information such as timestamp, HTTP status code, error, message, and the path.
2. Using @ExceptionHandler Annotation
- @ExceptionHandler annotation provided by Spring Boot can be used to handle exceptions in particular Handler classes or Handler methods.
- Any method annotated with this is automatically recognized by Spring Configuration as an Exception Handler Method.
- An Exception Handler method handles all exceptions and their subclasses passed in the argument.
- It can also be configured to return a specific error response to the user.
So let's create a custom ErrorResponse class so that the exception is conveyed to the user in a clear and concise way as follows:
Java
// Custom Error Response Class
package com.customer.exception;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ErrorResponse {
private int statusCode;
private String message;
public ErrorResponse(String message)
{
super();
this.message = message;
}
}
The addCustomer() method defined by CustomerController throws a CustomerAlreadyExistsException when the user tries to add a Customer that already exists in the database else it saves the customer details.
To handle this exception let's define a handler method handleCustomerAlreadyExistsException() in the CustomerController. So, now when addCustomer() throws a CustomerAlreadyExistsException, the handler method gets invoked which returns a proper ErrorResponse to the user.
Java
// Exception Handler method added in CustomerController to handle CustomerAlreadyExistsException
@ExceptionHandler(value = CustomerAlreadyExistsException.class)
@ResponseStatus(HttpStatus.CONFLICT)
public ErrorResponse handleCustomerAlreadyExistsException(CustomerAlreadyExistsException ex) {
return new ErrorResponse(HttpStatus.CONFLICT.value(), ex.getMessage());
}
Note : Spring Boot allows to annotate a method with @ResponseStatus to return the required Http Status Code.
On Running the Spring Boot Application and hitting the /addCustomer API with an existing Customer, CustomerAlreadyExistsException gets completely handled by handler method as follows:

3. Using @ControllerAdvice for Global Exception Handling
In the previous approach, the @ExceptionHandler annotated method can only handle exceptions thrown by that particular class. If we want to handle any exception thrown throughout the application, we can define a global exception handler class and annotate it with @ControllerAdvice. This annotation helps to integrate multiple exception handlers into a single global unit.
The updateCustomer() method defined in CustomerController throws a NoSuchCustomerExistsException if the user tries to update details of a customer that doesn't already exist in the database. To handle this exception, define a GlobalExceptionHandler class annotated with @ControllerAdvice.
Java
// Class to handle exceptions globally
package com.customer.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = NoSuchCustomerExistsException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public @ResponseBody ErrorResponse handleException(NoSuchCustomerExistsException ex) {
return new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
}
}
On running the Spring Boot application and hitting the /updateCustomer API with invalid customer details, NoSuchCustomerExistsException gets thrown, which is completely handled by the handler method defined in the GlobalExceptionHandler class as follows:

Similar Reads
Spring Boot Tutorial Spring Boot is a Java framework that makes it easier to create and run Java applications. It simplifies the configuration and setup process, allowing developers to focus more on writing code for their applications. This Spring Boot Tutorial is a comprehensive guide that covers both basic and advance
10 min read
Spring Boot Basics and Prerequisites
Introduction to Spring BootSpring is one of the most popular frameworks for building enterprise applications, but traditional Spring projects require heavy XML configuration, making them complex for beginners.Spring Boot solves this problem by providing a ready-to-use, production-grade framework on top of Spring. It eliminate
4 min read
Difference between Spring and Spring BootSpring Spring is an open-source lightweight framework that allows Java developers to build simple, reliable, and scalable enterprise applications. This framework mainly focuses on providing various ways to help you manage your business objects. It made the development of Web applications much easier
4 min read
Spring - Understanding Inversion of Control with ExampleSpring IoC (Inversion of Control) Container is the core of the Spring Framework. It creates and manages objects (beans), injects dependencies and manages their life cycles. It uses Dependency Injection (DI), based on configurations from XML files, Java-based configuration, annotations or POJOs. Sinc
6 min read
Spring - IoC ContainerThe Spring framework is a powerful framework for building Java applications. It can be considered a collection of sub-frameworks, also referred to as layers, such as Spring AOP, Spring ORM, Spring Web Flow, and Spring Web MVC. We can use any of these modules separately while constructing a Web appli
2 min read
BeanFactory vs ApplicationContext in SpringThe Spring Framework provides two core packages that enable Inversion of Control (IoC) and Dependency Injection (DI):org.springframework.beansorg.springframework.contextThese packages define Spring containers that manage the lifecycle and dependencies of beans.Spring offers two main containers1. Bea
6 min read
Spring Boot Core
Spring Boot - ArchitectureSpring Boot is built on top of the Spring Framework and follows a layered architecture. Its primary goal is to simplify application development by providing auto-configuration, embedded servers and a production-ready environment out of the box.The architecture of Spring Boot can be divided into seve
2 min read
Spring Boot - AnnotationsAnnotations in Spring Boot are metadata that simplify configuration and development. Instead of XML, annotations are used to define beans, inject dependencies and create REST endpoints. They reduce boilerplate code and make building applications faster and easier. Core Spring Boot Annotations 1. @Sp
5 min read
Spring Boot ActuatorDeveloping and managing an application are the two most important aspects of the applicationâs life cycle. It is very important to know what is going on beneath the application. Also, when we push the application into production, managing it gradually becomes critically important. Therefore, it is a
5 min read
How to create a basic application in Java Spring BootSpring Boot is the most popular Java framework that is used for developing RESTful web applications. In this article, we will see how to create a basic Spring Boot application.Spring Initializr is a web-based tool using which we can easily generate the structure of the Spring Boot project. It also p
3 min read
Spring Boot - Code StructureThere is no specific layout or code structure for Spring Boot Projects. However, there are some best practices followed by developers that will help us too. You can divide your project into layers like service layer, entity layer, repository layer,, etc. You can also divide the project into modules.
3 min read
Spring Boot - SchedulingSpring Boot provides the ability to schedule tasks for execution at a given time period with the help of @Scheduled annotation. This article provides a step by step guideline on how we can schedule tasks to run in a spring boot application Implementation:It is depicted below stepwise as follows:Â St
4 min read
Spring Boot - LoggingLogging in Spring Boot plays a vital role in Spring Boot applications for recording information, actions, and events within the app. It is also used for monitoring the performance of an application, understanding the behavior of the application, and recognizing the issues within the application. Spr
8 min read
Exception Handling in Spring BootException handling in Spring Boot helps deal with errors and exceptions present in APIs, delivering a robust enterprise application. This article covers various ways in which exceptions can be handled and how to return meaningful error responses to the client in a Spring Boot Project. Key Approaches
8 min read
Spring Boot with REST API
Spring Boot - Introduction to RESTful Web ServicesRESTful Web Services REST stands for REpresentational State Transfer. It was developed by Roy Thomas Fielding, one of the principal authors of the web protocol HTTP. Consequently, REST was an architectural approach designed to make the optimum use of the HTTP protocol. It uses the concepts and verbs
5 min read
Spring Boot - REST ExampleIn modern web development, most applications follow the Client-Server Architecture. The Client (frontend) interacts with the server (backend) to fetch or save data. This communication happens using the HTTP protocol. On the server, we expose a bunch of services that are accessible via the HTTP proto
4 min read
How to Create a REST API using Java Spring Boot?Representational State Transfer (REST) is a software architectural style that defines a set of constraints for creating web services. RESTful web services allow systems to access and manipulate web resources through a uniform and predefined set of stateless operations. Unlike SOAP, which exposes its
4 min read
How to Make a Simple RestController in Spring Boot?A RestController in Spring Boot is a specialized controller that is used to develop RESTful web services. It is marked with the @RestController annotation, which combines @Controller and @ResponseBody. This ensures that the response is automatically converted into JSON or XML, eliminating the need f
2 min read
JSON using Jackson in REST API Implementation with Spring BootWhen we build REST APIs with Spring Boot, we need to exclude NULL values from the JSON responses. This is useful when we want to optimize the data being transferred, making the response more compact and easier to process for the client.In this article, we are going to learn the approach that is used
4 min read
Spring Boot with Database and Data JPA
Spring Boot with Kafka
Spring Boot Kafka Producer ExampleSpring Boot is one of the most popular and most used frameworks of Java Programming Language. It is a microservice-based framework and to make a production-ready application using Spring Boot takes very less time. Spring Boot makes it easy to create stand-alone, production-grade Spring-based Applica
3 min read
Spring Boot Kafka Consumer ExampleSpring Boot is one of the most popular and most used frameworks of Java Programming Language. It is a microservice-based framework and to make a production-ready application using Spring Boot takes very less time. Spring Boot makes it easy to create stand-alone, production-grade Spring-based Applica
3 min read
Spring Boot | How to consume JSON messages using Apache KafkaApache Kafka is a stream processing system that lets you send messages between processes, applications, and servers. In this article, we will see how to publish JSON messages on the console of a Spring boot application using Apache Kafka. In order to learn how to create a Spring Boot project, refer
3 min read
Spring Boot | How to consume string messages using Apache KafkaApache Kafka is a publish-subscribe messaging queue used for real-time streams of data. A messaging queue lets you send messages between processes, applications, and servers. In this article we will see how to send string messages from apache kafka to the console of a spring boot application. Appro
3 min read
Spring Boot | How to publish String messages on Apache KafkaApache Kafka is a publish-subscribe messaging system. A messaging queue lets you send messages between processes, applications, and servers. In this article, we will see how to send string messages to Apache Kafka in a spring boot application. In order to learn how to create a spring boot project, r
2 min read
Spring Boot | How to publish JSON messages on Apache KafkaApache Kafka is a publish-subscribe messaging system. A messaging queue lets you send messages between processes, applications, and servers. In this article, we will see how to send JSON messages to Apache Kafka in a spring boot application. In order to learn how to create a spring boot project, ref
4 min read
Spring Boot with AOP
Spring Boot - AOP(Aspect Oriented Programming)The Java applications are developed in multiple layers, to increase security, separate business logic, persistence logic, etc. A typical Java application has three layers namely they are Web layer, the Business layer, and the Data layer. Web layer: This layer is used to provide the services to the e
4 min read
How to Implement AOP in Spring Boot Application?AOP(Aspect Oriented Programming) breaks the full program into different smaller units. In numerous situations, we need to log, and audit the details as well as need to pay importance to declarative transactions, security, caching, etc., Let us see the key terminologies of AOP Aspect: It has a set of
10 min read
Spring Boot - Difference Between AOP and OOPAOP(Aspect-Oriented Programming) complements OOP by enabling modularity of cross-cutting concerns. The Key unit of Modularity(breaking of code into different modules) in Aspect-Oriented Programming is Aspect. one of the major advantages of AOP is that it allows developers to concentrate on business
3 min read
Spring Boot - Difference Between AOP and AspectJSpring Boot is built on the top of the spring and contains all the features of spring. And is becoming a favorite of developers these days because of its rapid production-ready environment which enables the developers to directly focus on the logic instead of struggling with the configuration and se
3 min read
Spring Boot - Cache ProviderThe Spring Framework provides support for transparently adding caching to an application. The Cache provider gives authorization to programmers to configure cache explicitly in an application. It incorporates various cache providers such as EhCache, Redis, Guava, Caffeine, etc. It keeps frequently a
6 min read