RestControllerAdvice annotation
The `@RestControllerAdvice` annotation in Spring is used to handle exceptions globally across the whole application. It combines the functionality of `@ControllerAdvice` with `@ResponseBody`, making it a convenient way to handle exceptions and provide consistent error responses in RESTful web services.
Table of Contents
- `@ControllerAdvice`: Used to define a global exception handler, apply advice (e.g., validation, binding), and add cross-cutting concerns to multiple controllers.
- `@ResponseBody`: Indicates that the return value of the methods should be written directly to the HTTP response body.
Example
- Step 1: Create a Spring Boot Application
- Ensure you have the necessary dependencies in your `pom.xml` (for Maven) or `build.gradle` (for Gradle).
Maven Dependency
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
```
Gradle Dependency
```groovy
implementation 'org.springframework.boot:spring-boot-starter-web'
```
- Step 2: Create the Main Application Class
- Create the main class for the Spring Boot application.
Example
```java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
```
Explanation:
- `@SpringBootApplication`: Indicates a configuration class that declares one or more `@Bean` methods and also triggers auto-configuration and component scanning.
- Step 3: Create a Custom Exception
- Define a custom exception class.
Example
```java
package com.example.demo.exception;
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String message) {
super(message);
}
}
```
Explanation:
- `UserNotFoundException`: A custom exception extending `RuntimeException` to represent a specific type of error.
- Step 4: Create a Global Exception Handler
- Define a global exception handler using `@RestControllerAdvice`.
Example
```java
package com.example.demo.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleUserNotFoundException(UserNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGlobalException(Exception ex) {
return new ResponseEntity<>("An error occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
```
Explanation:
- `@RestControllerAdvice`: Combines `@ControllerAdvice` and `@ResponseBody` to create a global exception handler that returns responses directly to the body.
- `@ExceptionHandler(UserNotFoundException.class)`: Handles `UserNotFoundException` and returns a `404 Not Found` response with the exception message.
- `@ExceptionHandler(Exception.class)`: Catches all other exceptions and returns a generic `500 Internal Server Error` response with the exception message.
- Step 5: Create a Controller
- Create a controller class that may throw exceptions.
Example
```java
package com.example.demo.controller;
import com.example.demo.exception.UserNotFoundException;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users/{id}")
public String getUser(@PathVariable("id") Long id) {
if (id <= 0) {
throw new UserNotFoundException("User with ID " + id + " not found.");
}
return "User ID: " + id;
}
}
```
Explanation:
- `@RestController`: Indicates that this class is a REST controller, and the return values of methods are written directly to the HTTP response body.
- `@RequestMapping(“/api”)`: Specifies that all methods in this class handle requests starting with `/api`.
- `@GetMapping(“/users/{id}”)`: Maps GET requests to `/api/users/{id}` to the `getUser` method.
- `@PathVariable(“id”)`: Binds the `{id}` path variable from the URL to the `id` method parameter.
- Step 6: Running the Application
- Run the application from the main class (`DemoApplication`). You can test the endpoint using a tool like Postman or by navigating to the URL in your browser:
- GET request to `http://localhost:8080/api/users/0` should return a `404 Not Found` status with the message `”User with ID 0 not found.”`.
- GET request to `http://localhost:8080/api/users/1` should return `”User ID: 1″`.
Conclusion
- `@RestControllerAdvice`: Used for global exception handling in REST controllers. It combines `@ControllerAdvice` and `@ResponseBody` to provide centralized error handling and response management.
- Example: Demonstrated how to use `@RestControllerAdvice` to handle exceptions globally and provide consistent error responses.