Spring Boot
REST
Exception Handling
Java
Web Development

Spring Boot REST service exception handling

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Spring Boot is a popular Java-based framework used to create stand-alone, production-grade Spring-based applications. One of the key features of Spring Boot is its support for building RESTful web services using Spring MVC. Exception handling in REST services is crucial for providing meaningful feedback to the client and ensuring that the application behaves predictably and gracefully under error conditions. This article discusses various techniques for handling exceptions in Spring Boot REST services.

Why Exception Handling is Important in REST Services

Exception handling is important in REST services for the following reasons:

  • Client Communication: Clients need to know what went wrong when they send requests to a service. Proper exception handling provides clear and meaningful error responses.
  • Code Readability: Clearly managing and defining the response for each exception enhances the overall readability and maintainability of the codebase.
  • System Stability: Well-defined exception handling can prevent unexpected crashes and ensure the system remains stable and secure.

Spring Boot Exception Handling Techniques

1. Using @ExceptionHandler

The simplest way to handle exceptions in Spring Boot is to define an exception handler method in your controller. The @ExceptionHandler annotation is used to specify which exception type the method should handle.

java
1@RestController
2public class MyRestController {
3
4    @GetMapping("/resource")
5    public Resource getResource() {
6        // logic to retrieve resource
7        throw new ResourceNotFoundException();
8    }
9
10    @ExceptionHandler(ResourceNotFoundException.class)
11    public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
12        ErrorResponse error = new ErrorResponse("Resource Not Found", "The requested resource was not found.");
13        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
14    }
15}

2. Global Exception Handling with @ControllerAdvice

While @ExceptionHandler is useful for handling exceptions within a specific controller, @ControllerAdvice allows you to handle exceptions globally across all controllers.

java
1@ControllerAdvice
2public class GlobalExceptionHandler {
3
4    @ExceptionHandler(Exception.class)
5    public ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex) {
6        ErrorResponse error = new ErrorResponse("Internal Server Error", ex.getMessage());
7        return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
8    }
9
10    @ExceptionHandler(ResourceNotFoundException.class)
11    public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
12        ErrorResponse error = new ErrorResponse("Resource Not Found", "The requested resource was not found.");
13        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
14    }
15}

3. Using @ResponseStatus

The @ResponseStatus annotation can be used to specify the HTTP status code that should be returned for a particular exception. This is useful for creating custom exceptions with specific response statuses.

java
1@ResponseStatus(HttpStatus.NOT_FOUND)
2public class ResourceNotFoundException extends RuntimeException {
3    public ResourceNotFoundException(String message) {
4        super(message);
5    }
6}
7
8@RestController
9public class MyRestController {
10
11    @GetMapping("/resource")
12    public Resource getResource() {
13        // logic to retrieve resource
14        throw new ResourceNotFoundException("Resource not found");
15    }
16}

4. Implementing HandlerExceptionResolver

For a more customized approach, you can implement the HandlerExceptionResolver interface. This allows you to define custom logic for resolving exceptions.

java
1@Component
2public class CustomExceptionResolver implements HandlerExceptionResolver {
3
4    @Override
5    public ModelAndView resolveException(HttpServletRequest request,
6                                         HttpServletResponse response,
7                                         Object handler, Exception ex) {
8        try {
9            if (ex instanceof ResourceNotFoundException) {
10                response.sendError(HttpStatus.NOT_FOUND.value(), ex.getMessage());
11            } else {
12                response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Internal Server Error");
13            }
14        } catch (IOException e) {
15            // handle IO exception
16        }
17        return new ModelAndView(); // return empty ModelAndView to signal no further handling
18    }
19}

Error Response Representation

When a REST service throws an exception, it's often advisable to send a structured error response to the client. A common practice is to return a JSON object that provides more context about the error.

Here's an example of how an error response might be structured:

java
1public class ErrorResponse {
2    private String error;
3    private String message;
4
5    public ErrorResponse(String error, String message) {
6        this.error = error;
7        this.message = message;
8    }
9
10    // getters and setters
11}

Best Practices in Exception Handling

  • Use Standard HTTP Status Codes: Make sure to use appropriate HTTP status codes corresponding to the error condition.
  • Keep Error Messages Consistent: Ensure error messages are consistent and provide clear information to the client.
  • Log Detailed Information: While the client should receive a simplified error message, detailed logs should be maintained on the server for debugging purposes.
  • Avoid Exposing Stack Traces: Sensitive information should not be exposed to the client; use logs for detailed tracebacks instead.

Summary Table

Exception Handling TechniqueDescriptionExample API
@ExceptionHandlerHandles specific exceptions within a controller.handleResourceNotFound
@ControllerAdviceGlobal exception handler across all controllers.GlobalExceptionHandler
@ResponseStatusMaps exceptions to HTTP status codes.ResourceNotFoundException
HandlerExceptionResolverInterface for custom exception resolution logic.CustomExceptionResolver

Conclusion

Effective exception handling in Spring Boot REST services is essential for building robust applications. By using the techniques described in this article, you can ensure that your services provide meaningful error responses and maintain stability, even when facing unexpected conditions.


Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.