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 largely
if-else
Flooded
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 redundancy
if-else
judge - 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
@RequestBody
Wrong 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
@Valid
Scenarios: nested object verification, integration with non-Spring frameworks - Priority use
@Validated
Scenario: Group verification and verification of Service layer method parameters are required
Key points of configuration:
- To use
@Valid
Must be addedspring-boot-starter-validation
rely - Failure to check will be thrown
MethodArgumentNotValidException
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.