When we write Controller or Service, we often write a large number of data verification codes in methods, as follows
if(StringUtils.isEmpty(pass)){ return Result.error(ErrorCodeEnum.PASSWORD_EMPTY); }else if(!ValidatorUtil.isMobile(mobile)){ return Result.error(ErrorCodeEnum.MOBILE_PATTERN_WRONG); }
Not only waste time, but also make the business logic code more complex. Next, we use JSR303 to provide verification tools for us to avoid excessive code verification.
JSR303
JSR 303 - Bean Validation is a specification for data validation. If it does not meet the specification, a specific message will be returned indicating the error of the specification
- The following notes provide verification for us
@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 whose value must be greater than or equal to the specified minimum value @Max(value) the annotated element must be a number whose value must be less than or equal to the specified maximum value @DecimalMin(value) the annotated element must be a number whose value must be greater than or equal to the specified minimum value @DecimalMax(value) the annotated element must be a number whose 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 @The annotated element of Digits (integer, fraction) must be a number, and its value must be within the acceptable range @The element that paste is annotated must be a date in the Past @Future annotated element must be a future date @Pattern(value) the annotated element must conform to the specified regular expression
- For example: a encapsulated login information class LoginVo
@Data public class LoginVo { @NotNull @Length(max = 11,min = 11) private String mobile;//Cell-phone number @NotNull @Length(min = 32) private String password;//Password }
We use @ NotNull annotation to declare the field to be non empty, that is, the parameter passed from the front end must have a specific value and cannot be null
@The Length annotation is the critical condition for the longest and shortest field declaration string. The data from the front end must meet the requirements
- Finally, we annotate @ Valid where we log in the encapsulation class (such as the Controller parameter) to verify our encapsulation class
public Result doLogin( @Valid LoginVo loginVo)
Custom validator
To learn more about JSR303, we will implement a custom validator (the custom annotation implements the specific validation code), and observe how it works
- Now we need to check the mobile number for the mobile field in the login information class (check whether it is a mobile number, and return the format error message in case of format error)
- We declare it as @ IsMobile annotation
By observing the above comments, we find that the general code of the verifier is as follows
- validatedBy: to pass in a specific custom validator class (to implement the validator logic)
- Message method: the specific error message of verification failure is returned here
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) @Repeatable(IsMobile.List.class) @Documented @Constraint( validatedBy = {MobileValidator.class}//Here, validatedBy is to pass in a specific custom validator class (to implement the validator logic) ) public @interface IsMobile { boolean required() default true;//You can use this field to declare whether or not you must String message() default "Illegal mobile number format";//The specific error information of verification failure is returned here Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface List { IsMobile[] value(); } }
-
So we need to write a class to implement the validator logic MobileValidator
Validators need to implement the ConstraintValidator interface, which specifies two parameters with generics
Override the isValid method
public class MobileValidator implements ConstraintValidator<IsMobile, String> { private boolean required = true; @Override public void initialize(IsMobile constraintAnnotation) { } @Override public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) { if(required){//If it has to be stated to be passed in, validation will be carried out return ValidatorUtil.isMobile(s); }else {//If you don't have to specify, you can check whether it is empty before verifying if (StringUtils.isEmpty(s)) { return false; } else return ValidatorUtil.isMobile(s); } } }
- ValidatorUtil utility class user authentication
public class ValidatorUtil { //Use regular matching to match 11 digits at the beginning of 1 private static final Pattern mobile_pattern = Pattern.compile("1\\d{10}"); //If the match returns true, the phone number format is correct public static boolean isMobile(String s){ if(StringUtils.isEmpty(s)){ return false; } Matcher m = mobile_pattern.matcher(s); return m.matches(); } }