自定义校验注解的开发

在这里插入图片描述

在业务中,会涉及到很多参数校验,通常情况下,我们会使用注解在入参中进行标注。但是一些特定的业务校验注解需要我们自定义开发。

应用场景描述

业务中入参经常有开始时间结束时间,需要保证结束时间 > 开始时间,下面Demo演示了如何自定义一个参数校验注解。

自定义注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(DateValidate.List.class)
@Constraint(validatedBy = DateValidator.class)
public @interface DateValidate {

    String startDateName();
    String endDateName();
    //作为校验注解必须属性
    String message();
    //作为校验注解必须属性
    Class<?>[] groups() default {};
    //作为校验注解必须属性
    Class<? extends Payload>[] payload() default {};

    //java8新增的可重复注解
    @Target(TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface List{
        DateValidate[] value();
    }

}

定义校验方法

/**
 * @Description 时间验证,依赖于Hutool工具包做时间解析,DateUtil.parse方法会自动识别一些常用格式,使用方法:在入参类上标注,可标注多个 @DateValidate(startDateName = "startTime",endDateName = "endTime",message = "开始时间不能大于结束时间")
 * @Date 2022/11/1 15:58
 * @Version 1.0
 **/

@Slf4j
public class DateValidator implements ConstraintValidator<DateValidate,Object> {

    private String startDateName;
    private String endDateName;

    @Override
    public void initialize(DateValidate constraintAnnotation) {
        this.startDateName = constraintAnnotation.startDateName();
        this.endDateName = constraintAnnotation.endDateName();

    }

    @Override
    public boolean isValid(Object object, ConstraintValidatorContext context) {
        Date startDate;
        Date endDate;
        try {
            Field fsd = object.getClass().getDeclaredField(startDateName);
            fsd.setAccessible(true);
            startDate = DateUtil.parse((String)fsd.get(object));
            Field fed=object.getClass().getDeclaredField(endDateName);
            fed.setAccessible(true);
            endDate = DateUtil.parse((String)fed.get(object));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //如果有时间为空放过校验,让@NotNull注解去处理
        if(startDate == null || endDate == null){
            return true;
        }
        return endDate.after(startDate);
    }


}

使用方式

入参中:

@Data
@DateValidate(startDateName = "startTime",endDateName = "endTime",message = "开始时间不能大于结束时间")
public class ListForm extends PageQuery {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "开始时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private String startTime;

    @ApiModelProperty(value = "结束时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private String endTime;
}

Controller中:
给ListForm加入@Valid 注解

结果演示

请求结果(全局异常捕获的)

{
  "code": "110104",
  "data": {},
  "msg": "参数错误, 开始时间不能大于结束时间"
}

拓展

在业务需求中,还有很多可以自定义的校验注解,例如手机号码校验注解,防止sql注入校验注解。开发注解校验可以减少很多重复的校验代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

结构化思维wz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值