SoFunction
Updated on 2025-04-12

SpringBoot parameter verification: Detailed explanation of the use of @Valid and @Validated

1. Case (necessity of parameter verification)

Disadvantages of the traditional method (no annotation):

// Each field needs to be manually checked, the code is redundant and error-pronepublic String register(User user) {
    // Manually check each field    if (() == null || !isValidEmail(())) {
        throw new IllegalArgumentException("Emailbox format error");
    }
    if (().length() < 8) {
        throw new IllegalArgumentException("Password length must be ≥8 digits");
    }
    // Verification logic is coupled with business code, difficult to reuse}

Question summary

  • Code redundancy: Repeat the same verification logic
  • Difficulty in maintenance: The verification rules are scattered and the modification costs are high
  • Poor readability: Business logic is largelyif-elseFlooded

Advantages of annotation method

public class User {
    @Email(message = "The email format is illegal")  // One line of annotations replaces complex verification    private String email;
    
    @Size(min = 8, message = "Password length must be ≥8 digits")
    private String password;
}

@PostMapping("/register")
public String register(@Valid @RequestBody User user) { 
    // The verification logic is automatically processed by the framework    return "success";
}

Core advantages

  • Declarative verification: Automatically complete parameter verification through annotations
  • Concise code: reduce redundancyif-elsejudge
  • Unified specifications: Standardized verification rules to reduce maintenance costs

2. @Valid annotation

Introduction

  • Java standard annotations()
  • Used to trigger Bean Validation verification mechanism
  • VerifiedMethod parametersandMember Attributes

SpringBoot Configuration

<!--  Must rely on -->
<dependency>
    <groupId></groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Example of usage

public class User {
    @NotNull(message = "Username cannot be empty")
    private String name;
    
    @Min(value = 18, message = "Age must be ≥18 years old")
    private Integer age;
}

@PostMapping("/users")
public String createUser(@Valid @RequestBody User user) { // Trigger verification    return "success";
}

Global exception handling (core practice)

@RestControllerAdvice
public class GlobalExceptionHandler {
    
    // Handle verification exception thrown by @Valid/@Validated    @ExceptionHandler()
    public ResponseEntity<Map<String, String>> handleValidationException(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ().getFieldErrors().forEach(error -> 
            ((), ()));
        return ().body(errors);
    }
}

Effect: Automatically return structured error information (field name + error description)

3. @Validated annotation

Introduction

  • Spring framework annotations() (@Validated is provided by the Spring framework. The dependency imported by springboot will be automatically imported)
  • Supports Group Validation
  • Can be marked inClass, method, parametersuperior

Core functions

// Packet interface definitionpublic interface CreateGroup {} 
public interface UpdateGroup {}

public class User {
    @NotBlank(groups = )
    private String name;
    
    @NotNull(groups = {, })
    private Integer age;
}

// Use group verification@PostMapping("/users")
public String createUser(@Validated() @RequestBody User user) {
    return "success";
}

4. Common verification annotations

The most commonly used annotations:

annotation illustrate Example
@NotNull The value cannot be null @NotNull(message="field required")
@NotBlank String is not empty (after trim) Suitable for username, password, etc.
@Min/@Max Numerical range limit @Min(18)
@Pattern Regular expression verification @Pattern(regexp="^1[3-9]\\d{9}$")
@Valid Nested object verification Used for child object properties within an object

Commonly used annotations:

annotation Applicable Type illustrate Example
@Future Date The date must be in the future @Future(message="Invalid deadline")
@Digits Numerical type Integer and decimal limits @Digits(integer=3, fraction=2)
@Negative Numerical type Must be negative Commonly used in financial systems
@NotEmpty Collection/String Collection non-empty or string length >0 Looser than @NotBlank

Combination annotations (customized)

// Custom mobile phone number verification annotations@Documented
@Constraint(validatedBy = )
@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface Phone {
    String message() default "The mobile phone number format is illegal";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

// Verification logic implementationpublic class PhoneValidator implements ConstraintValidator<Phone, String> {
    private static final Pattern PHONE_PATTERN = ("^1[3-9]\\d{9}$");
    
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return value != null && PHONE_PATTERN.matcher(value).matches();
    }
}

Use scenarios: Reuse of enterprise-specific verification rules (such as company internal employee numbers)

5. The difference between @Valid and @Validated

characteristic @Valid @Validated
Standard Specifications JSR-303/JSR-349 Standard Spring Framework Extensions
Group verification Not supported support
Nested verification Need to explicitly add @Valid Nested verification is not automatically supported
Position of action Method parameters, member properties Class, method, parameter

6. High-frequency problems and best practices

Frequently Asked Questions

Annotations do not take effect

  • Check if you forgot to add@Valid/@Validated
  • Make sure the verification object is not@RequestBodyWrong package for annotation

Nesting verification failed

  • Confirm that it has been added to the nested object properties@Valid

Performance optimization suggestions

  • Avoid over-checking: Do basic verification in the Controller layer, and put complex logic into the Service layer
  • Use group verification: Reduce unnecessary verification overhead

Advanced Tips

// Dynamic group verification (determine the verification group based on the request parameters)@Validated
@RestController
public class UserController {
    
    @PostMapping("/users")
    public String createUser(
        @RequestParam String type,
        @Validated({, ("vip") ?  : }) 
        @RequestBody User user
    ) {
        return "success";
    }
}

Implementation principle: Dynamically select verification groups using Spring EL expressions

7. Key summary

Priority usage scenarios

  • Priority use@ValidScenarios: nested object verification, integration with non-Spring frameworks
  • Priority use@ValidatedScenario: Group verification and verification of Service layer method parameters are required

Key points of configuration

  • To use@ValidMust be addedspring-boot-starter-validationrely
  • Failure to check will be thrownMethodArgumentNotValidException

Best Practices

// Nested verification examplepublic class Order {
    @Valid  // Must be added explicitly    private User user;
}

// Group verification example@Validated()
public void updateUser(@RequestBody User user) {}

Verification process

Request parameters → Annotation declaration → Automatic verification → Exception handling (@ControllerAdvice)

Advantages of traditional parameter verification

  • Reduce the number of parameter verification codes by more than 70%
  • Standardization of error response through unified exception handling
  • Improve code maintainability and team collaboration efficiency

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.