自定义字段依赖性校验注解

1.目前springboot框架校验的注解也有不少,但是暂时没有发现一种字段校验是根据其他校验字段来做校验的;

比如纳税人为公司那么纳税号必须填写,纳税人是个人的话纳税号不用填写了。这种情况当然可以写个判断就行了,如果一个类或者多个类都这样那就得一行行的写校验了,写校验也是很耗时间的

其实这个可以统一做个注解来校验就OK了

所以这里也算个小需求吧,开始造轮子

方法:基于spring aspect切面来做的,具体看下面代码

/**
 * 条件字段和值得关系
 **/
public enum RelationEnums {
    /**
     * 相等
     */
    EQ,
    /**
     * 小于
     */
    LT,
    /**
     * 大于
     */
    RT,
    /**
     * 包含
     */
    CONTAINS,
    ;
    RelationEnums(){}

}

/**
 * 属性校验注解
 */
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConditionValid {
    /**
     * 字段关系枚举
     *
     */
    RelationEnums relation() default RelationEnums.EQ;

    /**
     *
     * 默认是 字段依赖校验
     */
    boolean isDependency() default true;

    /**
     * 条件字段
     *
     */
    String conditionFiled() default "";

    /**
     * 条件字段值
     *
     */
    String conditionValue() default "";

    /**
     * 需要检验的字段
     */
    String field() default "";

    /**
     * 提示信息
     */
    String message() default "";

    /**
     * 扩展
     */
    @Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE,ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @interface List{
       ConditionValid[] values();
    }


}

/**
 * 复杂校验标识用于扫描,标注则标识启用上面的校验
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ComplexValid {

}

/**
* 带标识注解的方法
*/
@ComplexValid
public Boolean addInvoiceHead(@Valid InvoiceHeadDTO invoiceHeadDTO) {
        return invoiceHeadService.addOrUpdate(invoiceHeadDTO);
}

/**
*统一处理校验
*/
@Aspect
@Component
@Order(1)
public class ValidateAop {


    /**
     * 切面填充属性
     * @param joinPoint 切点
     * @param valid 属性
     * @return obj
     * @throws Throwable e
     */
    @Around(value = "@annotation(valid)")
    public Object validate(ProceedingJoinPoint joinPoint, ComplexValid valid) throws Throwable {
        Object[] args = joinPoint.getArgs();
        try {
            Class<?> aClass = args[0].getClass();
            ConditionValid.List annotation = aClass.getAnnotation(ConditionValid.List.class);
            if(annotation!=null){
                for (ConditionValid value : annotation.values()) {
                    Method method = aClass.getMethod(getMethodName(value.conditionFiled()));
                    Object invoke = method.invoke(args[0]);
                    Method t = aClass.getMethod(getMethodName(value.field()));
                    Object tv = t.invoke(args[0]);
                    String formatT = String.format(value.message(), value.conditionFiled(), value.conditionValue(), value.field());
                    if(value.relation()== RelationEnums.EQ&&value.conditionValue().equals(invoke.toString())&& ValidateUtils.isEmpty(tv)){
                        throw new RuntimeException(formatT);
                    }else if(value.relation()== RelationEnums.CONTAINS&&value.conditionValue().contains(invoke.toString())&&ValidateUtils.isEmpty(tv)){
                        throw new RuntimeException(formatT);
                    }

               //todo 这里可以继续扩展的
                }
            }
            return joinPoint.proceed();
        } catch (Throwable e) {
          e.printStackTrace();
          throw e;
        }
    }

    /**
     * 用反射getXX方法,获取字段值
     * @param field 字段
     * @return String
     */
    public static String getMethodName(String field){
        String s = field.substring(0, 1).toUpperCase();
        String end = field.substring(1);
        return "get"+s+end;
    }

}






这里举个例子:如果纳税人公司,那么纳税号不能为空



@ConditionValid.List(values =
        {
                @ConditionValid(conditionFiled = "headType", conditionValue = "0",relation = RelationEnums.CONTAINS,
                        field = "taxPlayerIdNum", message = "when %s = %s then %s is not empty")
        }
)
public class InvoiceHeadDTO{

    /**
     * 纳税方
     */
    @NotBlank(message = "taxPlayer is blank")
    private String taxPlayer;

    /**
     * 抬头类型0:企业发票,1个人非企业
     */
    private Integer headType;
    /**
     * 纳税人识别号
     */
    private String taxPlayerIdNum;

}

上面也看到了NotBlank是框架有的,那么我们可以综合使用,还是挺好用的吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值