SpringBoot学习秒杀二、jsr303校验器

表单校验是我们在提交表单时不可缺少的一个环节,普通的校验方法是针对每个参数进行单独的判断,但是这样不仅麻烦,并且如果参数很多的情况下我们写过多的if会使得代码非常臃肿,并且可读性较差,以登录为例,假设我我们需要mobilepassword 两个参数,那么就需要进行如下的校验:

if(StringUtils.isEmpty(mobile)){
	return false;
}
if(!Validator.isMobile(mobile)){
	return false;
}
if(StringUtils.isEmpty(password)){
	return false;
}

这个时候,我们的jsr303就闪亮登场了
同样使用登录为例,我们先定义一个UserVO用来接收前端穿过来的参数:

public class UserVo {
    private String mobile;
    private String password;

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

然后我们定义我们的控制器UserController:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("login")
    public String login(UserVo userVo){
        return "";
    }

}

接下来在pom.xml中添加jsr303的依赖:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

这样在Controller传递参数的时候我们使用@Valid 来告诉系统这个参数我们需要进行校验
@Valid UserVo userVo
接下来我们只需要到Vo里边,在需要校验的变量上边使用注解即可,例如我们需要密码不为空,则可以使用@NotNull,如果还需要限制密码长度最小不得小于8位,可以使用@Length(min = 8),此外系统还为我们提供了许多注解:

 @NotNull                 注解元素必须是非空
 @Null                      注解元素必须是空
 @Digits                    验证数字构成是否合法
 @Future                   验证是否在当前系统时间之后
 @Past                       验证是否在当前系统时间之前
 @Max                      验证值是否小于等于最大指定整数值
 @Min                       验证值是否大于等于最小指定整数值
 @Pattern                  验证字符串是否匹配指定的正则表达式
 @Size                      验证元素大小是否在指定范围内
 @DecimalMax   验证值是否小于等于最大指定小数值
 @DecimalMin    验证值是否大于等于最小指定小数值
 @AssertTrue             被注释的元素必须为true
 @AssertFalse     被注释的元素必须为false

如果我们需要的校验方式系统中没有,我们也可以自己实现一个,例如我们需要校验mobile是否为一个正确的手机号码,则可以自己定义一个@IsMobile :

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = {IsMobileValidator.class}   // 此处是对参数进行校验的具体实现
)
public @interface IsMobile {

    boolean required() default true;   //自己定义 是否表示属性是否必须填写

    String message() default "手机号码格式错误";  //校验失败之后的提示

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

此时注解有了之后,我们需要来实现一个方法来校验手机号码,也就是上方注解 validatedBy = {IsMobileValidator.class}中的 IsMobileValidator 这个类,这个类需要实现 ConstraintValidator<注解,参数类型> 这个接口:

public class IsMobileValidator implements ConstraintValidator<IsMobile, String> {

    private boolean required = false;

    @Override
    public void initialize(IsMobile constraintAnnotation) {
        required = constraintAnnotation.required();
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        //如果参数是必须填写的,那么进行校验
        if(required){
            return ValidatorUtil.isMobile(s);
        }
        //如果参数不是必须填写的,那么如果是空的也算符合要求了
        if(StringUtils.isEmpty(s)){
            return  true;
        }
        return ValidatorUtil.isMobile(s);
    }
}

其中判断字符串是否为一个手机号的类的具体实现ValidatorUtil:

/**
 * 参数校验工具
 * author:shine
 */
public class ValidatorUtil {

    /**
     * 校验手机号
     * @param mobile
     * @return
     */
    public static boolean isMobile(String mobile){
        Pattern mobilePattern =  Pattern.compile("^((13[0-9])|(14[5,7,9])|(15[^4])|(18[0-9])|(17[0,1,3,5,6,7,8]))\\d{8}$");
        Matcher m = mobilePattern.matcher(mobile);
        return m.matches();
    }

}

好了,这样@IsMobile这个注解就实现了,我们在moble参数上写上这个注解:

public class UserVo {

    @IsMobile
    private String mobile;
    @NotNull
    @Length(min = 8)
    private String password;

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

接下来我们测试一下,由于我们还没有写页面,这里我们就用postman来模拟请求一下:
在这里插入图片描述
当我们手机号和密码都是正确的情况下,可以看到什么错误也没有报,说明我们的请求参数是通过校验了的,接下来我们试一下如果使用长度小于8的密码:
在这里插入图片描述
可以看到请求出来的是一个错误信息,接下来我们在使用一个不合法的手机号来测试一下:
在这里插入图片描述
可以看到我们自定义的校验也是可以的

猜你喜欢

转载自blog.csdn.net/JiayaoXu/article/details/104450949