1. What is @Valid
in Spring Boot?
The @Valid
annotation is part of the Java Bean Validation (JSR-380) standard, implemented by libraries like Hibernate Validator. It is used to trigger validation on a Java object’s fields based on annotations such as @NotNull
, @Size
, @Email
, etc.
2. Dependencies Required
Spring Boot starter automatically includes Hibernate Validator if you use the spring-boot-starter-web
dependency.
But if you’re building a custom setup, add:
<!-- Maven --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
Or if you’re not using Spring Boot starter:
<dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> </dependency>
3. Simple Example: Validating a REST API Input
Step 1: Create a DTO class with validation constraints
import jakarta.validation.constraints.*; public class UserRequest { @NotBlank(message = "Name is required") private String name; @Email(message = "Email should be valid") private String email; @Min(value = 18, message = "Age should be at least 18") @Max(value = 100, message = "Age should not be more than 100") private int age; // Getters and Setters }
Step 2: Use @Valid
in your controller
import org.springframework.web.bind.annotation.*; import org.springframework.http.ResponseEntity; import jakarta.validation.Valid; @RestController @RequestMapping("/api/users") public class UserController { @PostMapping public ResponseEntity<String> createUser(@RequestBody @Valid UserRequest request) { return ResponseEntity.ok("User is valid!"); } }
3. How Validation Errors Are Handled
If the validation fails, Spring Boot will throw a MethodArgumentNotValidException
automatically.
Default response (without custom handler):
{ "timestamp": "2025-07-12T10:00:00.123+00:00", "status": 400, "errors": [ "Name is required", "Age should be at least 18" ] }
4. Customize Error Response Using @ControllerAdvice
You can customize the error response by writing a global exception handler.
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.RestControllerAdvice; import java.util.*; import java.util.stream.Collectors; @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<Map<String, Object>> handleValidationException(MethodArgumentNotValidException ex) { List<String> errors = ex.getBindingResult() .getFieldErrors() .stream() .map(error -> error.getField() + ": " + error.getDefaultMessage()) .collect(Collectors.toList()); Map<String, Object> response = new HashMap<>(); response.put("status", HttpStatus.BAD_REQUEST.value()); response.put("errors", errors); return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); } }
5. Validating Path Variables and Request Parameters
You can also use @Valid
or @Validated
with query parameters or path variables.
import jakarta.validation.constraints.Min; import org.springframework.validation.annotation.Validated; @RestController @Validated public class ProductController { @GetMapping("/products/{id}") public String getProductById(@PathVariable @Min(1) Long id) { return "Product ID: " + id; } }
Note: For validation of primitives or simple types, use @Validated
at the class level instead of @Valid
.
6. Nested Object Validation with @Valid
public class OrderRequest { @NotNull private String orderId; @Valid private UserRequest user; // Validates this nested object // Getters and Setters }
7. Supported Bean Validation Annotations
Here are some commonly used constraints from the Bean Validation API:
Annotation | Purpose |
@NotNull | Field must not be null |
@NotBlank | Not null and not empty string |
@NotEmpty | Not null and not empty collection |
@Email | Must be a valid email |
@Size(min, max) | Length of string or size of list |
@Min(value) | Number must be ≥ value |
@Max(value) | Number must be ≤ value |
@Pattern(regex) | Must match regex pattern |
@Positive | Value must be > 0 |
@Negative | Value must be < 0 |