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

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
    评论
Excel2Entity Excel2Entity实现了Java POI对xls文件的读取功能的封装,实现了批量导入Excel中的数据时自动根据Excel中的数据行创建对应的Java POJO实体对象的功能。 该类库也实现了在创建实体对象时对字段类型进行校验,可以对Excel中的数据类型合法性进行校验,通过实现扩展接口,可以实现自定义校验规则以及自定义实体对象字段类型等更加复杂的校验规则和字段类型转换。 应用场景 该类库主要用应用场景是在一般管理系统中批量数据导入。 安装配置 Excel2Entity类库已经加入到Maven中央仓库,如果你的项目使用了Maven,则可以通过添加下面的Maven依赖配置项将该类库加入到您的项目. cc.aicode.java.e2e ExcelToEntity 1.0.0.3 依赖 Excel2Entity依赖于Apache POI类库。 使用说明 使用示例请参考src/test/java/cc/aicode/e2e/Excel2Entity/AppTest测试用例。 普通实体创建 ExcelHelper eh = ExcelHelper.readExcel("111.xls"); List entitys = null; try { entitys = eh.toEntitys(Demo.class); for (Demo d : entitys) { System.out.println(d.toString()); } } catch (ExcelParseException e) { System.out.println(e.getMessage()); } catch (ExcelContentInvalidException e) { System.out.println(e.getMessage()); } catch (ExcelRegexpValidFailedException e) { System.out.println(e.getMessage()); } 注册新的字段类型 注册的新的字段类型类必须实现ExcelType抽象类。 ExcelHelper.registerNewType(MyDataType.class); 实体对象 实体类必须标注@ExcelEntity注解, 同时需要填充的字段标注@ExcelProperty注解 @ExcelEntity public class Demo { @ExcelProperty(value="Name", rule=MyStringCheckRule.class) private String name; @ExcelProperty("Sex") private String sex; // 基于正则表达式的字段校验 @ExcelProperty(value="Age", regexp="^[1-4]{1}[0-9]{1}$", regexpErrorMessage="年龄必须在10-49岁之间") private int age; @ExcelProperty(value="Tel") private Long tel; @ExcelProperty("创建时间") private Timestamp createDate; @ExcelProperty(value="Name", required=true) private MyDataType name2; ... [get/set方法] } 自定义校验规则 自定义校验规则必须实现ExcelRule接口 public class MyStringCheckRule implements ExcelRule { // 字段检查 public void check(Object value, String columnNam

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值