Early form of parameter verification
In the early days of Java, parameter verification stopped at the code level after obtaining parameters, like the following operations:
@PostMapping("/test")
public String test(@RequestBody TestRequest request) {
if (StringUtils.isEmpty(request.getName())) {
return "Name cannot be empty.";
}
if (request.getName().length() > 6) {
return "Name length cannot exceed 6";
}
if (StringUtils.isEmpty(request.getPhone())) {
return "The phone cannot be empty.";
}
if(! isPhone(request.getPhone())) {return "Incorrect phone number format";
}
return "SUCCESS";
}
/** * verify phone format */
private boolean isPhone(String phone) {
return true;
}
Copy the code
As seen in the code, each verification rule needs to be implemented in the code, so even parameter verification will cost developers a lot of energy, and the development efficiency will be greatly reduced.
JSR – 303
A Specification has been released in Java 6: JSR-303. JSR stands for Java Specification Requests, also known as Bean Validation.
JSR 303 is a standard framework provided by Java for bean data validation. Hibernate Validator is a reference implementation of Bean Validation.
Jsr-303 Parameter verification remarks
Built-in annotations in Bean Validation
Hibernate Validator additional annotations
Use JSR303 specification for parameter verification
We will modify the above code that does not use JSR303
@Data
public class TestRequest {
@NotEmpty(message = "Name cannot be empty.")
@Length(min = 1, max = 6, message = "The name must be 1-6 in length.")
private String name;
@NotBlank(message = "Phone number cannot be empty.")
@Pattern(regexp = "134-8 0 ^ \ \ d {7} $| ^ 13 [^ 4] \ \ d {8} $| ^ 14 [5-9] \ \ d {8} $| ^ 15 [^ 4] \ \ d {8} $| ^ 16 [6] \ \ d {8} $| ^ 17 [0 to 8] \ \ d {8} $| ^ 18 [\ \ d] {9} $| ^ 19 [8, 9] \ \ d {8 } $", message = "Incorrect phone number format")
private String phone;
@Email(message = "Mail format is incorrect")
private String email;
@NotNull(message = "Age cannot be empty.")
@Max(value = 18,message = "No older than 18.")
private Integer age;
}
Copy the code
Check the controller with @valid
@PostMapping("/test")
public String test(@RequestBody @Valid TestRequest request) {
return "SUCCESS";
}
Copy the code
Modification effect
Difference between @Valid and @Validated
First take a look at the packages they belong to:
You can see that @Validated belongs to Spring and @Valid belongs to Javax.
- @ Validated:
org.springframework.validation.annotation.Validated
- @ Valid:
javax.validation.Valid
However, in actual basic use, there is no difference between the two. (Note that basic use is used; in other words, using @Valid and @Validated is equivalent.)
@Validated Verifies the controller
@PostMapping("/test")
public String test(@RequestBody @Validated TestRequest request) {
return "SUCCESS";
}
Copy the code
You can get the same result by substituting the comment:
Two annotated source
- @Valid
@Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
public @interface Valid {
}
Copy the code
- @Validated
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interfaceValidated { Class<? >[] value()default {};
}
Copy the code
“@”, “Validated”, “Validated”, “Validated”, “Validated”, “Validated”, “Validated”, “Validated”, “Validated”
The @ provides a grouping function. When verifying parameters, you can use different verification mechanisms based on different groups. When no grouping attribute is added, the default validates the ungrouped validation attribute.
@Validated Group verification
Write checksum group identifier:
public class ValidatedGroup {
public interface Add extends Default {}
public interface Delete extends Default {}
public interface Update extends Default {}
public interface Query extends Default {}
}
Copy the code
Test request class:
@Data
public class TestSaveRequest {
@NotNull(groups = {ValidatedGroup.Update.class, ValidatedGroup.Delete.class}, message = "Id cannot be empty when updating or deleting")
private Long id;
@NotBlank(groups = {ValidatedGroup.Update.class}, message = "Name cannot be empty when updating")
private String name;
@NotNull(groups = {ValidatedGroup.Add.class}, message = "The balance cannot be empty when adding.")
@Digits(integer = 10, fraction = 2)
private BigDecimal balance;
@NotBlank(groups = {ValidatedGroup.Add.class}, message = "Phone cannot be empty when adding")
@Pattern(regexp = "134-8 0 ^ \ \ d {7} $| ^ 13 [^ 4] \ \ d {8} $| ^ 14 [5-9] \ \ d {8} $| ^ 15 [^ 4] \ \ d {8} $| ^ 16 [6] \ \ d {8} $| ^ 17 [0 to 8] \ \ d {8} $| ^ 18 [\ \ d] {9} $| ^ 19 [8, 9] \ \ d {8 } $", message = "Incorrect phone number format")
private String phone;
@NotBlank(groups = {ValidatedGroup.Add.class}, message = "Mail cannot be empty when new")
@Email
private String email;
}
Copy the code
Based on the type of test request we wrote, we can expect:
- If the verification group is Add, the balance, phone, and Email request fields are verified
- If the verification group is Update, the ID and name fields are verified
The tests are as follows:
@PostMapping("/testAdd")
public String testAdd(@RequestBody @Validated(value = ValidatedGroup.Add.class) TestSaveRequest request) {
return "SUCCESS";
}
@PostMapping("/testUpdate")
public String testUpdate(@RequestBody @Validated(value = ValidatedGroup.Update.class) TestSaveRequest request) {
return "SUCCESS";
}
Copy the code
TestAdd results:
TestUpdate results:
The results are exactly in line with expectations. @ validation A lot of additional development can be saved when grouping validation, especially when adding and updating.
A case where you need to pass a primary key and a case where you don’t need to pass a primary key, where you used to need an AddRequest and an UpdateRequest, now you just need one.
Nested check
What is nested verification? The code:
@Data
public class TestNestRequest {
@NotNull(message = "Id cannot be empty")
private Long id;
@NotNull(message = "Nested object request data cannot be empty")
private ItemRequest itemRequest;
}
Copy the code
@Data
public class ItemRequest {
@NotEmpty(message = "Name cannot be empty")
private String name;
}
Copy the code
@PostMapping("/testNest")
public String testNest(@RequestBody @Valid TestNestRequest request) {
return "SUCCESS";
}
Copy the code
The test results are as follows:
Only the ID is checked, not the name attribute in the nested object.
If you need to validate properties in nested objects, you need to modify the TestNestRequest class.
The @valid annotation to the itemRequest attribute validates the attributes in the nested object
The transformation is as follows:
@Data
public class TestNestRequest {
@NotNull(message = "Id cannot be empty")
private Long id;
@Valid
@NotNull(message = "Nested object request data cannot be empty")
private ItemRequest itemRequest;
}
Copy the code
Test results:
It is important to note that nested validation must be used@Valid
Annotation.
Follow wechat public account: IT elder brother
Java actual combat project video tutorial: you can get 200G, 27 sets of actual combat project video tutorial
Reply: Java learning route, you can get the latest and most complete a learning roadmap
Re: Java ebooks, get 13 must-read books for top programmers
Java foundation, Java Web, JavaEE all tutorials, including Spring Boot, etc
Reply: Resume template, you can get 100 beautiful resumes