Validating @RequestBody in Spring Boot — @Valid and Bean Validation
Fast recall
Quick revision
Core answer
Input validation knowledge — critical for any production API
Manually checking fields in service layer — use Bean Validation annotations instead
Show how to customize the 400 error response using @ControllerAdvice to catch MethodArgumentNotValidException
Interview-ready guide
Interview answer
For example, record CreateUser(@NotBlank String name, @NotBlank @Email String email, @Min(18) int age) can be accepted as @Valid @RequestBody CreateUser request. An empty name and malformed email create field violations before the method body runs. A duplicate email still needs a database/domain check because Bean Validation cannot make a race-free uniqueness guarantee.
Validating @RequestBody in Spring Boot — @Valid and Bean Validation
Direct Answer
Put Jakarta Bean Validation constraints on the request DTO and add @Valid or @Validated at the controller boundary. Spring first uses an HttpMessageConverter to deserialize the body and then validates the created object. Invalid method arguments normally raise MethodArgumentNotValidException; the default or custom exception handling decides the exact 400 response body.
Code Example
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody CreateUserRequest request) {
var user = userService.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
}
record CreateUserRequest(
@NotBlank(message = "Name is required") String name,
@Email(message = "Invalid email format") String email,
@Min(value = 18, message = "Must be at least 18") int age
) {}
// If client sends {"name":"","email":"bad-email","age":15}:
// Spring validates, finds 3 violations, throws MethodArgumentNotValidException
// Returns 400 with error details before createUser method runs
record User(Long id, String name, String email, int age) {}
Common Mistakes & Pitfalls
- Validating in service layer instead of controller: Freshers write if (user.getEmail() == null) throw exception logic in services. This is tedious and error-prone. Use Bean Validation annotations on the DTO and @Valid in the controller — validation happens automatically before service code runs.
- Forgetting @Valid annotation: You add validation annotations like at-NotNull to DTO fields but forget at-Valid on the @RequestBody parameter. Spring deserializes the object but never validates it, so invalid data reaches your service layer. Always pair Bean Validation annotations with at-Valid.
- Not customizing error responses: The default 400 response Spring returns is verbose and exposes internal field names. Freshers leave it as-is. Production APIs need clean error responses. Use at-ControllerAdvice with an at-ExceptionHandler for MethodArgumentNotValidException to return a structured error response with only the field name and user-friendly message.
Check your understanding
Answer these without looking back at the article.
- What exception does @Valid throw when validation fails?
- How do you return a custom error response when @Valid fails?
- What is the difference between @NotNull, @NotEmpty, and @NotBlank?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.