Global Exception Handling in Spring Boot
Introduction
When building projects with Spring Boot, handling complex business requirements often involves dealing with various exceptions. For example, during file I/O operations, you may encounter IOException or FileNotFoundException. When writing SQL statements or using JDBC, you may face SQLException. When working with reflection-related code, ClassCastException may occur.
In addition, there are many common exceptions such as NullPointerException, ArrayIndexOutOfBoundsException, ConcurrentModificationException (which occurs when modifying a collection while iterating over it), and arithmetic exceptions like division by zero (ArithmeticException), and so on.
When handling these exceptions, there are generally two approaches. The most straightforward and convenient way is to use the throws keyword to propagate the exception and let the upper-level method handle it. Another way is to catch exceptions using try-catch blocks. However, both approaches have obvious drawbacks. As the project grows larger and the number of exception handling points increases, handling exceptions one by one becomes inefficient and difficult to manage in a unified way.
So, is there a way to manage exceptions globally?
RestControllerAdvice and ExceptionHandler
Classes annotated with @RestControllerAdvice can be used to handle global exceptions. By annotating methods with @ExceptionHandler, you can specify which type of exception the method handles.
1 |
|
@ExceptionHandler accepts parameters of type Class[], representing the types of exceptions it can handle.
Define a basic exception interface and an enumeration class:
1 | public interface BaseException { |
1 | public enum ExceptionEnum implements BaseException { |
Define a Response class to unify the response format:
1 |
|
Let’s test it by intentionally creating an arithmetic exception in the controller:
1 |
|
Send a request in Postman:
You can see that the returned msg is "/ by zero", which corresponds exactly to the arithmetic exception, and the code is the predefined 500.
In this way, by setting up global exception handling, we can centrally manage all exceptions in the project without handling them one by one. This allows us to focus entirely on business logic, which is much more convenient.









