Preface
The validator component of the Spring framework is an auxiliary component, which is very useful for data integrity and validity. By defining a certain validator, it can be used in other places where it is needed, and it is very common.
Before executing business logic, it is necessary to ensure that the received input data is legal and correct through verification. However, many times the same verification occurs many times, which leads to code redundancy, wasted time, and violates the DRY principle.
You can consider encapsulating the verification code to solve these problems.
JSR-303
JSR-303 is a standard framework provided by Java for Bean data legality verification. It defines a set of verification annotations that can be annotated on member variables and attribute methods.
Hibernate Validation provides this set of standard implementations. When we introduce Spring Boot web starter or Spring boot starter validation, Hibernate Validation will be introduced by default.
Usage example
After saying so much nonsense, add the code.
1. Introduce SpringBoot Project
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> </dependency> <!-- Introducing lomhok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
2. Write verification objects
@Datapublic class User { // The name is not allowed to be empty, and the length of the name is between 2 and 30 bits// If the length of the name does not pass, then the error message is prompted @NotNull @Size(min=2, max=30,message = "Please check if there is any problem with the length of the name") private String name; // The name is not allowed to be empty, and the minimum age is 18 @NotNull @Min(18) private Integer age;}3. Create a controller
@SpringBootApplication@RestControllerpublic class UserApplication{ public static void main(String[] args) { SpringApplication.run(UserApplication.class,args); } // 1. Add @Valid annotation before the parameter to be checked// 2. Follow it immediately, follow a BindingResult to store the verification information @RequestMapping("/test1") public Object test1( @Valid User user, BindingResult bindingResult ) { // If there is a problem with the verification, an error message will be returned// Here we return all the error information. In fact, custom information can be returned according to the bindingResult method as needed. // The usual solution is: JSR-303 + global ExceptionHandler if (bindingResult.hasErrors()){ return bindingResult.getAllErrors(); } return "OK"; } } 4. Run the application
After a brief demonstration of the results of the operation, it can be seen that the verification framework has taken effect.
Check age
Verify name
Verification passed
Common verification annotations
@Null The annotated element must be null
@NotNull The annotated element must not be null
@AssertTrue The annotated element must be true
@AssertFalse The annotated element must be false
@Min(value) The annotated element must be a number, and its value must be greater than or equal to the specified minimum value.
@Max(value) The annotated element must be a number, and its value must be less than or equal to the specified maximum value.
@DecimalMin(value) The annotated element must be a number, and its value must be greater than or equal to the specified minimum value
@DecimalMax(value) The annotated element must be a number, and its value must be less than or equal to the specified maximum value
@Size(max=, min=) The size of the annotated element must be within the specified range.
@Digits (integer, fraction) The annotated element must be a number and its value must be within an acceptable range.
@Past The annotated element must be a past date
@Future The annotated element must be a future date
@Pattern(regex=,flag=) The annotated element must comply with the specified regular expression
Check annotations provided by Hibernate Validator:
@NotBlank(message =) Verify that the string is not null and must be greater than 0
@Email The annotated element must be an email address
@Length(min=,max=) The size of the annotated string must be within the specified range.
@NotEmpty The commented string must be non-empty
@Range(min=,max=,message=) The annotated element must be within the appropriate range
Custom verification annotations
Sometimes, the verification type we want is not in the third-party library. Fortunately, the system provides good expansion capabilities, and we can customize the verification.
For example, we want to verify the user's mobile phone format and write the mobile phone number verification device.
1. Write verification annotations
// We can directly copy the annotation in the system such as @Min, copy it into our new annotation, and then modify it as needed. @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})@Retention(RUNTIME)@Documented//The implementation class of the annotated. @Constraint(validatedBy = {IsMobileValidator.class})public @interface IsMobile { //Default information for verification of errors String message() default "There is a problem with the mobile phone number format"; //Whether to force verification boolean isRequired() default false; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {};} 2. Write specific implementation classes
We know that annotations are just a mark, and the real logic must be implemented in a specific class. The annotation in the previous step specifies that the class that implements the verification function is IsMobileValidator.
// Custom annotations must implement the ConstraintValidator interface, two parameters in it // The first is the specific annotation to be verified // The second is the parameter type of the verification public class IsMobileValidator implements ConstraintValidator<IsMobile, String> { private boolean required = false; private static final Pattern mobile_pattern = Pattern.compile("1//d{10}"); //Tool method, determine whether it is a mobile phone number public static boolean isMobile(String src) { if (StringUtils.isEmpty(src)) { return false; } Matcher m = mobile_pattern.matcher(src); return m.matches(); } @Override public void initialize(IsMobile constraintAnnotation) { required = constraintAnnotation.isRequired(); } @Override public boolean isValid(String phone, ConstraintValidatorContext constraintValidatorContext) { //Is it an implementation of a mobile phone number if (required) { return isMobile(phone); } else { if (StringUtils.isEmpty(phone)) { return true; } else { return isMobile(phone); } } }} 3. Test the function of custom annotations
@Datapublic class User { @NotNull @Size(min=2, max=30,message = "Please check if there is any problem with the length of the name") private String name; @NotNull @Min(18) private Integer age; //This is the newly added annotation @IsMobile private String phone;}4. Test
pass
There is a problem with the mobile number
It can be seen that the custom annotation has taken effect.
We can also continue to optimize the place and create a new global exception. If the verification fails, throw global business exceptions, catch business exceptions, and then return user-friendly prompt information.
additional
It can also pass the verification of the method.
1. Add @Validated annotation to the controller
2. Add verification annotations, @Min, @Max, etc. to the controller method.
@Validated@RestController@SpringBootApplicationpublic class UserApplication{ public static void main(String[] args) { SpringApplication.run(UserApplication.class,args); } @RequestMapping("/test2") public String test2( @IsMobile String phone ){ return phone + "ok"; } @ExceptionHandler(ConstraintViolationException.class) @ResponseBody public Object handleConstraintViolationException(ConstraintViolationException cve){ HashSet<String> messageSet = new HashSet(); for (ConstraintViolation constraintViolation : cve.getConstraintViolations()) { messageSet.add(constraintViolation.getMessage()); } return messageSet; }} Class verification rules
at last
By using the verification device, we no longer need to check all the controllers. If the code is much refreshing, it will be. We write code very briefly, but we must think about how to write code simpler, clearer and more conducive to maintenance. Writing duplicate code is a waste of your time.
When you encounter parameter verification in the future, the first thing you think about is not to check it directly. You can find out whether you have written a certain type of verifier and you can use it directly.
Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.