Category: java
Validating Request Data with Bean Validation
Published on 24 Jul 2026
Explanation
Spring Boot integrates Jakarta Bean Validation to validate incoming request data. By using annotations such as @NotNull, @NotBlank, @Email, and @Size, invalid requests are rejected before reaching the business logic.
Code:
public class StudentDTO {
@NotBlank
private String name;
@Email
private String email;
@Min(18)
private int age;
}
Explanation
The @Valid annotation tells Spring Boot to validate the request object before executing the controller method. If validation fails, Spring automatically throws a validation exception instead of calling the service layer.
Code:
@PostMapping
public Student createStudent(@Valid @RequestBody StudentDTO student) {
return service.save(student);
}
Explanation
Custom validators are useful when built-in validation annotations cannot satisfy business requirements. You can create your own validation annotation and implement validation logic using the ConstraintValidator interface.
Code:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface ValidPhone {
String message() default "Invalid phone number";
}
Explanation
A class annotated with @RestControllerAdvice can catch validation exceptions from every controller. This provides a centralized place to return consistent and user-friendly error messages for invalid requests.
Code:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<String> handleValidationException() {
return ResponseEntity.badRequest().body("Validation Failed");
}
}
Explanation
Instead of returning a generic error message, collect all validation errors and return them in a structured JSON response. This helps API consumers identify exactly which fields failed validation and why.
Code:
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleErrors(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors()
.forEach(error -> errors.put(error.getField(), error.getDefaultMessage()));
return errors;
}