# Streamlining Exception Handling in Spring Boot with REST Controller Advice
Written on
Chapter 1: Introduction to REST Controller Advice
Spring Boot simplifies the management of exception handling through the REST Controller Advice annotation. This feature minimizes repetitive code and standardizes the response format, thereby enhancing the maintainability of web applications. By employing a REST Controller Advice interceptor for each defined exception, developers can ensure that error responses are consistent with the request format, facilitating seamless communication between the front-end and back-end systems.
Scenario
The development team is tasked with creating a web service application that manages user accounts, necessitating standardized exception handling for any errors that may arise during service execution.
Discussion
To address this requirement, the team opted to implement the REST Controller Advice annotation, designing a uniform response format for all exceptions encountered.
Implementation
The developer initiates a Java class and annotates it with REST Controller Advice. They define the exceptions that will utilize standardized responses and craft a Java bean to format these responses consistently. For instance, the REST Controller Advice annotation allows for the creation of user-related RESTful services, returning error responses in case of exceptions or validation issues.
CommonResponseBean Class
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class CommonResponseBean {
public long timestamp;
public List<ErrorBean> errors;
}
ErrorBean Class
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ErrorBean {
public String errorCode;
public String errorMessage;
}
UserProfile Class
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Data
public class UserProfile {
@NotEmpty
private String firstName;
@NotEmpty
private String lastName;
private String effectiveDate;
@Min(0)
private long age;
public UserProfile(String firstName, String lastName, int age, String effectiveDate) {
this.firstName = firstName;
this.lastName = lastName;
this.effectiveDate = effectiveDate;
this.age = age;
}
}
Creating a RESTful Service
import com.example.demo.bean.UserProfile;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@RestController
public class CreateUser {
@PostMapping(path = "/user", produces = "application/json")
public ResponseEntity<String> create(@Valid @RequestBody UserProfile userProfile) throws ParseException {
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
if (!userProfile.getEffectiveDate().isEmpty()) {
df.parse(userProfile.getEffectiveDate());}
return new ResponseEntity<>("created", HttpStatus.CREATED);
}
}
Exception Handlers
import com.example.demo.bean.CommonResponseBean;
import com.example.demo.bean.ErrorBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
@RestControllerAdvice
public class CommonExceptionHandlers {
@ExceptionHandler(ParseException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<CommonResponseBean> handleParseException(ParseException ex) {
CommonResponseBean res = new CommonResponseBean();
res.setTimestamp(new Date().getTime());
res.setErrors(new ArrayList<>());
res.getErrors().add(new ErrorBean("E0001", ex.getMessage()));
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(res);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<CommonResponseBean> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
CommonResponseBean res = new CommonResponseBean();
res.setTimestamp(new Date().getTime());
res.setErrors(new ArrayList<>());
res.getErrors().add(new ErrorBean("E0002", ex.getMessage()));
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(res);
}
}
Chapter 2: Testing the Implementation
The first video discusses the integration of RestControllerAdvice and @ExceptionHandler in Spring Boot, offering insights into its practical application and benefits.
Test Case Scenarios
Utilizing Postman simplifies the testing of various scenarios. The following test cases illustrate how the REST Controller Advice annotation functions:
- Test Case: Call the web service at /user.
- Expected Result: The response body should indicate "created" with an HTTP status of 201 (Created).
- Test Case: Call the web service at /user with an empty first name.
- Expected Result: The response body should return an error message with an HTTP status of 400 (Bad Request), including timestamps and error details, as defined in CommonResponseBean.
- Test Case: Call the web service at /user with an invalid effective date format.
- Expected Result: Similar to the previous case, this should return an error message with an HTTP status of 400 (Bad Request).
In summary, these scenarios demonstrate how exceptions listed in CommonExceptionHandlers utilize a custom error response format designed by the developer. This design approach significantly enhances maintainability.
Finally, the REST Controller Advice annotation streamlines the development of RESTful web services by consolidating all exception handling in a single class. This allows developers to efficiently manage various exceptions and tailor error responses, providing a consistent format that is beneficial for front-end developers.
Thank you for your attention!
The second video elaborates on custom error handling using @ControllerAdvice and @ExceptionHandler in Spring, providing practical examples and insights into best practices.