Spring Global Exception Handling Using @ControllerAdvice Annotation
For several reasons, you may want a global solution to handle exceptions thrown by controllers across the whole application. Spring provides a mechanism that enables such functionality using @ControllerAdvice
annotation.
Overview
- We will build a simple Spring Boot application which includes three classes:
Controller.java
: Simple controller responding to GET requests mapped to /ok & /exception.ControllerAdvisor.java
: A class annotated with@ControllerAdvice
to handle exceptions.App.java
: Run the application
Dependencies
- Spring Boot
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Complete Maven dependencies is included in pom.xml
Spring MVC Controller
We will build a simple controller which has two services:
- First service
ok()
returns OK - The second service
exception()
throws anException
.
Controller.java
@RestController
public class Controller {
@RequestMapping("/ok")
public @ResponseBody String ok() throws Exception {
return "OK";
}
@RequestMapping("/exception")
public @ResponseBody String exception() throws Exception {
throw new Exception("Error");
}
}
- If we call
/exception
, “before implementing@ControllerAdvice
” we will see following message
- Also, notice that the HTTP status code is
500
Internal Server Error.
@ControllerAdvice
- We can handle the previous exception using
@ControllerAdvice
by defining a new class annotated with this annotation. - Methods of this class can be annotated by
@ExceptionHandler
which defines a single or a list of exceptions types to be handled. @ResponseStatus
is used to override the response status code to be returned by annotated methods.
@ControllerAdvice
public class ControllerAdvisor {
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public @ResponseBody String generalException(final Exception exception,
final HttpServletRequest request) {
return exception.getMessage()+" while calling: "+request.getRequestURI();
}
}
- Now, when calling the
/exception
service,@ControllerAdvice
class will handle the thrown exception and will set the status code to400
Bad Request.