Clean • Professional
@ControllerAdvice (Global Exception Handling)In Spring Boot, @ControllerAdvice is a global exception handling mechanism that intercepts exceptions thrown by any controller. It allows you to:
For REST APIs, use @RestControllerAdvice, which automatically returns JSON responses instead of HTML.
@ControllerAdvice?@ExceptionHandler methods inside the class.MethodArgumentNotValidException.In short:
@ControllerAdvice = centralized exception management for your Spring Boot app.
@ControllerAdvice?@ExceptionHandler in every controller.This example shows handling a specific exception, a generic exception, and validation errors globally.
@RestControllerAdvice
publicclassGlobalExceptionHandler {
// Handle specific exception
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse>handleUserNotFound(UserNotFoundException ex) {
ErrorResponseerror=newErrorResponse(
ex.getMessage(),
HttpStatus.NOT_FOUND.value(),
System.currentTimeMillis()
);
returnnewResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
// Handle all other exceptions
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse>handleAllExceptions(Exception ex) {
ErrorResponseerror=newErrorResponse(
"Something went wrong",
HttpStatus.INTERNAL_SERVER_ERROR.value(),
System.currentTimeMillis()
);
returnnewResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
// Handle validation errors globally
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, Object>>handleValidationErrors(MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(error -> error.getField() +": " + error.getDefaultMessage())
.toList();
Map<String, Object> response =newHashMap<>();
response.put("timestamp", System.currentTimeMillis());
response.put("status", HttpStatus.BAD_REQUEST.value());
response.put("errors", errors);
return ResponseEntity.badRequest().body(response);
}
}
The ErrorResponse DTO standardizes the JSON response format for all exceptions. The errors field can hold a list of validation errors, making responses clear and structured.
publicclassErrorResponse {
private String message;
privateint status;
private Object errors;// Can hold validation error list
privatelong timestamp;
publicErrorResponse(String message, int status, Object errors) {
this.message = message;
this.status = status;
this.errors = errors;
this.timestamp = System.currentTimeMillis();
}
// Getters and setters
}
UserNotFoundException: Shows a specific exception with a 404 HTTP status**.**
{
"message":"User not found",
"status":404,
"timestamp":1672567890123
}
Generic Exception: Represents any unhandled exceptions globally with a 500 HTTP status.
{
"message":"Something went wrong",
"status":500,
"timestamp":1672567890123
}
Validation Error: Shows detailed validation errors returned as a list for client feedback.
{
"timestamp":1672567890123,
"status":400,
"errors":[
"name: Name is required",
"email: Email should be valid",
"age: Age must be at least 18"
]
}
This flow shows how exceptions propagate from any controller to the global handler, and a structured JSON response is returned to the client.
Exception Thrown in Any Controller
|
v
Global @ControllerAdvice Handler
|
v
Appropriate @ExceptionHandler Executes
|
v
Returns Structured JSON Response
@ControllerAdvice is designed for centralized, reusable exception handling, making it ideal for large REST APIs and microservices.
| Feature | Description |
|---|---|
| Scope | Works across all controllers globally, so one class can handle exceptions for the entire application. |
| Reusability | High – Write your exception-handling logic once and reuse it for any controller, avoiding duplication. |
| Best For | Medium to large projects, microservices, and applications with multiple controllers. |
| Production Use | Recommended – Perfect for production-ready REST APIs with consistent error handling. |
| Error Response | Returns structured JSON for all exceptions, making API responses consistent, professional, and client-friendly. |
| Advantage | Description |
|---|---|
| Centralized Handling | One class handles all exceptions across all controllers. Avoids repeating @ExceptionHandler in every controller. |
| Cleaner Controllers | Business logic stays separate from error handling, making controllers simpler and easier to read. |
| Consistent API Responses | All exceptions return the same structured JSON format, making your API predictable and professional. |
| Supports Validation Errors | Automatically handles @Valid / @Validated exceptions globally. No repeated validation error code. |
| Customizable Responses | Define different JSON structures/messages for different exceptions (e.g., business errors vs generic errors). |
| Reusable & Scalable | Works across multiple controllers. Perfect for medium to large projects and microservices. |
| Easier Maintenance | Update exception handling logic in one place, instead of modifying multiple controllers. |
| Production-Ready | Makes REST APIs professional and ready for real-world usage with clear and structured responses. |
| Feature | @ExceptionHandler | @ControllerAdvice |
|---|---|---|
| Scope | Works only inside a single controller. Each controller needs its own handler. | Works globally across all controllers. One class handles exceptions for the entire application. |
| Reusability | Low – Cannot be reused across multiple controllers. | High – Write once, reuse for all controllers. Ideal for large projects. |
| Maintenance | Medium – Updating exception logic requires changes in multiple controllers. | Easier – Centralized handling, update once in one place. |
| Recommended For | Small apps or single-controller projects where centralized handling is not required. | Medium/Large applications, REST APIs, and production-ready projects. |
| Handles Validation? | Only if explicitly defined inside the controller using @ExceptionHandler(MethodArgumentNotValidException.class). | Handles validation errors globally by defining them once in the global handler. |
@ControllerAdvice is the preferred approach for global exception handling in Spring Boot. It ensures:
Use @RestControllerAdvice for REST APIs to automatically return JSON responses without additional configuration.