Daily use: spring boot parameter verification, based on JSR303 specification

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

    • The first parameter A: the class of custom annotation
    • T is the type of value to be verified

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();
    }
}

Keywords: Java Mobile less Bean Validation

Added by LiamG on Fri, 15 Nov 2019 08:16:27 +0200