在SpringBoot中,如何自定义实现一个请求参数校验注解

157 阅读3分钟

在日常开发中,我们经常会去校验各种前端请求的参数,如果参数的校验代码全部都手动去实现,写起来真的非常痛苦。而熟悉Spring的都知道,在Spring全家桶中,有一个轮子叫Validation,他可以通过注解的方式帮我们去校验前端传过来的各种参数。

但是,它并不是所有需求都能满足,当遇到不同需求的校验方式的时候,我们只能自己去写校验方法.
如果同时这个校验方法有很多地方可以共用,那么如何跟Validation一样,去用注解的方式来实现?

在springboot中,引入Validation的start包。

如果我们想要实现上面的自定义注解需求,那么我们首先需要在maven去引入Validation的start包。

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

随后,创建一个登录接口,以及前端传过来的参数对象

    @PostMapping("/doLogin")
    @ResponseBody
    public R login(@Valid  LoginVO loginVO){
        System.out.println("登录成功");
      return R.ok();
    }
@Data
public class LoginVO {
    @NotNull
    private String mobile;
    @NotNull
    private String password;
}

这时候,需求是校验手机号码,但是Validation包没有提供校验手机号的注解,那么我们只能自己去写校验方法。而我们这里则根据Validation来实现自定义校验注解。

实现自定义校验注解

1.创建校验注解

创建自定义注解类IsMobile

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(value = IsMobile.List.class)
@Documented
@Constraint(validatedBy = { IsMobileValida.class})    //validatedBy中填入的是我们校验规则的类
public @interface IsMobile {


    boolean required()  default true; //默认这个注解为true
    String message() default "手机号错误";  //错误信息

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

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




    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    @Retention(RUNTIME)
    @Documented
    @interface List {

        IsMobile[] value();
    }

2.创建规则对象

既然有了自定义注解,那么就需要给自定义注解加上他对应的规则,必须满足规则才能通过。
注意的是:这里需要集成ConstraintValidator接口,`ConstraintValidator`接口包含两个泛型类型参数,分别是`A``T`,代表了要验证的注解类型和要验证的目标类型。
/**
 * 电话号码校验规则类
 */
public class IsMobileValida implements ConstraintValidator<IsMobile,String> {

    //定义一个阈值
    private boolean  required=false;

    //校验规则方法
    public static boolean validatePhoneNumber(String phoneNumber) {
        String regex = "^(13[0-2]|145|15[56]|166|17[156]|18[56])\\d{8}$";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(phoneNumber);

        boolean matches = matcher.matches();
        return matches;
    }
    //校验规则
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
      if (required){
       return    validatePhoneNumber(value);
      }else {
          //如果是非必填
          if (value.isEmpty()){
              //如果没有值,不进行校验,直接放行
              return true;
          }else {
              //如果是非必填的清空下,还是填写了,那么我们就进行校验
             return validatePhoneNumber(value);
          }
      }
    }
    //初始化。获取使用自定义校验注解的变量是非必填还是必填
    @Override
    public void initialize(IsMobile constraintAnnotation) {
         required = constraintAnnotation.required();
    }
}

3.在指定的参数上加上注解

在电话号码上加上注解,以及完成自定义校验配置,并且默认为true

image.png

测试结果

当我们输入错误的电话号码时,则会校验不通过,并且展示我们自定义的错误信息。

image.png

image.png