自定义校验注解的开发

Posted 结构化思维wz

tags:

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

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

应用场景描述

业务中入参经常有开始时间结束时间,需要保证结束时间 > 开始时间,下面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注入校验注解。开发注解校验可以减少很多重复的校验代码。

以上是关于自定义校验注解的开发的主要内容,如果未能解决你的问题,请参考以下文章

Springboot之自定义校验注解

spring框架校验自定义注解

测试开发专题:spring-boot自定义返回参数校验错误信息

测试开发专题:spring-boot自定义返回参数校验错误信息

SpringBoot分组校验及自定义校验注解

SpringBoot系列之自定义枚举类的数据校验注解