Spring Boot @RestControllerAdvice vs @ControllerAdvice

🚀 Introduction: Understanding @RestControllerAdvice vs @ControllerAdvice

In Spring Boot, both @RestControllerAdvice and @ControllerAdvice are used for global exception handling, but they serve different purposes.

Key Differences:

Feature @ControllerAdvice @RestControllerAdvice
Purpose Used for global exception handling and applying cross-cutting concerns to controllers. Specifically used for exception handling in REST APIs.
Applies To @Controller (MVC controllers that return views) @RestController (REST APIs that return JSON responses)
Implicit Behavior Returns views (HTML pages) by default. Returns JSON responses by default (automatically applies @ResponseBody).
Common Usage Used in web applications with Thymeleaf/JSP. Used in REST APIs that return JSON responses.

1️⃣ Understanding @ControllerAdvice in Spring Boot

📌 Use @ControllerAdvice when handling exceptions in traditional web applications that return views (HTML, JSP, Thymeleaf).

Example: Using @ControllerAdvice to Handle Exceptions in an MVC App

@Controller
@RequestMapping("/web")
public class UserController {

    @GetMapping("/{id}")
    public String getUserById(@PathVariable int id, Model model) {
        if (id == 0) {
            throw new UserNotFoundException("User not found");
        }
        model.addAttribute("user", "User " + id);
        return "user-profile"; // Returns user-profile.html (Thymeleaf view)
    }
}

📌 Handling Exceptions Using @ControllerAdvice

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(UserNotFoundException.class)
    public String handleUserNotFound(UserNotFoundException ex, Model model) {
        model.addAttribute("errorMessage", ex.getMessage());
        return "error-page"; // Returns error-page.html
    }
}

📌 How It Works:

  • If a UserNotFoundException occurs, the user is redirected to error-page.html instead of getting an error.
  • The Model carries error details to the view.

Best for handling exceptions in MVC applications where responses are HTML pages.

2️⃣ Understanding @RestControllerAdvice in Spring Boot

📌 Use @RestControllerAdvice when handling exceptions in REST APIs that return JSON responses.

Example: Using @RestControllerAdvice to Handle Exceptions in a REST API

@RestController
@RequestMapping("/api/users")
public class UserRestController {

    @GetMapping("/{id}")
    public User getUserById(@PathVariable int id) {
        if (id == 0) {
            throw new UserNotFoundException("User not found");
        }
        return new User(id, "Ramesh");
    }
}

📌 Handling Exceptions Using @RestControllerAdvice

@RestControllerAdvice
public class GlobalRestExceptionHandler {

    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<String> handleUserNotFound(UserNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }
}

📌 How It Works:

  • If UserNotFoundException occurs, a JSON response with HTTP 404 status is returned instead of an error page.
  • The @RestControllerAdvice applies @ResponseBody automatically, so JSON is returned.

📌 Example API Response (GET /api/users/0):

{
  "error": "User not found"
}

Best for handling exceptions in REST APIs where responses are JSON.

3️⃣ Key Differences Between @ControllerAdvice and @RestControllerAdvice

Feature @ControllerAdvice @RestControllerAdvice
Applies To @Controller (Web MVC controllers) @RestController (REST APIs)
Response Type Returns views (HTML pages) Returns JSON responses
Automatically Includes @ResponseBody? ❌ No ✅ Yes
Exception Handling Scope Handles exceptions for web pages (Thymeleaf, JSP) Handles exceptions for RESTful APIs
Use Case Web applications with UI templates Microservices, REST APIs

📌 Best Practice:
✔ Use @ControllerAdvice for web apps with views.
✔ Use @RestControllerAdvice for REST APIs that return JSON.

4️⃣ Handling Multiple Exception Types

Example: Handling Multiple Exceptions in @RestControllerAdvice

@RestControllerAdvice
public class GlobalRestExceptionHandler {

    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<String> handleUserNotFound(UserNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<String> handleBadRequest(IllegalArgumentException ex) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid request: " + ex.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleGeneralException(Exception ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred: " + ex.getMessage());
    }
}

Ensures that different exception types return appropriate HTTP status codes and messages.

5️⃣ Using @ExceptionHandler Directly Inside Controllers

📌 You can also define @ExceptionHandler methods inside individual controllers instead of using global advice.

Example: Handling Exceptions Inside a Controller

@RestController
@RequestMapping("/api/products")
public class ProductController {

    @GetMapping("/{id}")
    public Product getProductById(@PathVariable int id) {
        if (id == 0) {
            throw new ProductNotFoundException("Product not found");
        }
        return new Product(id, "Laptop");
    }

    @ExceptionHandler(ProductNotFoundException.class)
    public ResponseEntity<String> handleProductNotFound(ProductNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }
}

Useful when exception handling is specific to a single controller.
For centralized exception handling across multiple controllers, use @RestControllerAdvice.

🎯 Summary: Best Practices for @RestControllerAdvice and @ControllerAdvice

Use @ControllerAdvice for handling exceptions in MVC applications (returning views).
Use @RestControllerAdvice for handling exceptions in REST APIs (returning JSON).
Use @ExceptionHandler inside a controller for controller-specific exceptions.
Always return appropriate HTTP status codes (404, 400, 500).
Use a global exception handler (@RestControllerAdvice) for better maintainability in REST APIs.

🚀 Following these best practices ensures clean, maintainable, and scalable exception handling in Spring Boot!

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare