阿昌教你自定义注解验证Bean对象

Posted 阿昌喜欢吃黄桃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阿昌教你自定义注解验证Bean对象相关的知识,希望对你有一定的参考价值。

前言

在之前阿昌写过一篇 【Springboot的注解字段校验,并统一设置返回值 】的文章,讲了常见的一些注解,和自定义的报错返回处理器,没看过的可以去看一下。

在Springboot中本身就可以通过大量的注解来实现对一些请求参数的校验。

这里在做一点的补充,关于自定义注解,去校验MVC,Web请求中的数据校验


正文

接下来我们就通过自定义注解的方式,为大家介绍两个手机号 & 是否是日期

在此之前,都到这里了,你别问我注解是一个什么东西,这边建议您回炉一下 (≖‿≖

1、自定义手机号校验

  • 自定义注解
@Target({ElementType.FIELD})//用来描述属性字段
@Retention(RetentionPolicy.RUNTIME)//用来描述运行时状态
@Constraint(validatedBy = IsPhoneValidator.class)//指定自定义校验器
public @interface IsPhone {
    //校验错误信息
    String message() default "手机号格式有误";
    //是否强制校验
    boolean isRequired() default false;
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
  • 自定义校验器

这里我用了hutool包的【正则表达式池】 (ฅ’ω’ฅ

//实现ConstraintValidator,泛型为: <校验注解,需要校验的值的类型>
public class IsPhoneValidator implements ConstraintValidator<IsPhone,String> {

    private Boolean isRequired = false;

    @Override
    public void initialize(IsPhone constraintAnnotation) {
        isRequired = constraintAnnotation.isRequired();
    }

    //参数1:传来的参数内容
    //参数2:上下文(可以获取到注解填写的内容)
    @Override
    public boolean isValid(String phone, ConstraintValidatorContext constraintValidatorContext) {
        if (isRequired){
            return isPhone(phone);
        }else {
            if (!StringUtils.isEmpty(phone)){
                return isPhone(phone);
            }else {
                return true;
            }
        }
    }

    //采用hutool包中的正则表达式池来校验手机号
    public boolean isPhone(String phone){
        return ReUtil.isMatch(Validator.MOBILE,phone);
    }
}
  • 测试

这样子定义完就可以使用了

    @PostMapping("/test")
    public R test(@Validated @RequestBody TestBean testBean){
        System.out.println(testBean.getPhone());
        return R.ok();
    }

因为我这里没有定义自定义拦截校验拦截器,就是如下的情况:↓

这样子就算完成了 (•˘_˘•


2、自定义校验时间是否为合法

那一开始肯定也是定义我们的自定义注解

  • 自定义注解
/**
 * @author 阿昌 自定义校验时间是否为合法
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DateValidator.class)
public @interface IsDate {
    String message() default "时间格式不正确";
    String formatter() default "";//校验的格式
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
  • 自定义日期合法校验器
public class DateValidator implements ConstraintValidator<IsDate, String> {
    @Override
    public void initialize(IsDate isDate) {}
    
    //time:传入需要校验的字符串时间
    //constraintValidatorContext:注解上下文内容
    @Override
    public boolean isValid(String time, ConstraintValidatorContext constraintValidatorContext) {
        try {
            // 获取指定的时间格式化formatter
            // 获取到上下文中传入的校验日期格式
            String formatter =
                (String) ((ConstraintDescriptorImpl) ((ConstraintValidatorContextImpl) constraintValidatorContext).getConstraintDescriptor()).getAnnotationDescriptor().getAttribute("formatter");
            // 如果时间传值为 04-31,DateUtils.toLocalDate()返回结果会是 04-30,
            // 所以需要比较一下转换为时间之后的值与原值是否相同,不同则格式输入有误
            // 如果这里formatter格式不是yyyy-MM-dd,那么需要判断转换之前是否是以转换之后的日结尾,因为不同的话也只是最后的日不同
            LocalDate date = DateUtils.toLocalDate(time,formatter);
            return time.endsWith(String.valueOf(date.getDayOfMonth()));
        } catch (Exception e) {
            return false;
        }
    }
}
  • 对对应Bean类型的时间字段进行验证


以上就是这次的所有内容,感谢你能看到这里! `・ω・´)ゞ!

以上是关于阿昌教你自定义注解验证Bean对象的主要内容,如果未能解决你的问题,请参考以下文章

阿昌教你自定义拦截器&自定义参数解析器&自定义包装HttpServletRequest

阿昌教你自定义拦截器&自定义参数解析器&自定义包装HttpServletRequest

阿昌教你自定义Spring配置文件提示

阿昌教你自定义Spring配置文件提示

阿昌教你使用常用Lombok@注解

阿昌教你使用常用Lombok@注解