How to Use @ControllerAdvice in Spring for Global Exception Handling
@ControllerAdvice to create a class that handles exceptions globally across all controllers in a Spring application. Annotate methods inside this class with @ExceptionHandler to define how specific exceptions should be processed and what response to send.Syntax
The @ControllerAdvice annotation marks a class as a global handler for exceptions and other controller-related concerns. Inside this class, methods annotated with @ExceptionHandler specify which exceptions they handle. You can also use @ResponseStatus to set HTTP status codes for responses.
@ControllerAdvice: Declares a global handler class.@ExceptionHandler(ExceptionType.class): Handles specific exceptions.@ResponseStatus(HttpStatus.CODE): Sets HTTP status for the response.
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(IllegalArgumentException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleIllegalArgument(IllegalArgumentException ex) { return ex.getMessage(); } }
Example
This example shows a Spring Boot application with a controller that throws an exception and a @ControllerAdvice class that catches it globally. The handler returns a custom error message with HTTP 400 status.
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } @RestController class SampleController { @GetMapping("/test") public String test(@RequestParam(required = false) String input) { if (input == null) { throw new IllegalArgumentException("Input parameter is missing"); } return "Input was: " + input; } } @ControllerAdvice class GlobalExceptionHandler { @ExceptionHandler(IllegalArgumentException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleIllegalArgument(IllegalArgumentException ex) { return "Error: " + ex.getMessage(); } }
Common Pitfalls
- Not annotating the handler class with
@ControllerAdvicemeans exceptions won't be caught globally. - Forgetting
@ExceptionHandleron methods causes them not to handle exceptions. - Returning raw strings without proper response formatting can cause unclear client responses.
- Using
@ResponseStatusincorrectly may send wrong HTTP status codes.
/* Wrong: Missing @ControllerAdvice */ public class WrongHandler { @ExceptionHandler(NullPointerException.class) public String handleNullPointer(NullPointerException ex) { return "Null error"; } } /* Right: With @ControllerAdvice */ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ControllerAdvice public class RightHandler { @ExceptionHandler(NullPointerException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public String handleNullPointer(NullPointerException ex) { return "Null error occurred"; } }
Quick Reference
@ControllerAdvice creates a global exception handler class.
@ExceptionHandler(Exception.class) marks methods to handle specific exceptions.
@ResponseStatus(HttpStatus.CODE) sets the HTTP status code for the response.
Use these together to centralize error handling and keep controllers clean.
| Annotation | Purpose |
|---|---|
| @ControllerAdvice | Marks a class as a global exception handler |
| @ExceptionHandler(ExceptionType.class) | Handles specific exceptions in methods |
| @ResponseStatus(HttpStatus.CODE) | Sets HTTP status code for the response |
| @RestControllerAdvice | Shortcut for @ControllerAdvice + @ResponseBody |