Skip to content

renfei/validator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Validator 验证器

Maven Central

在日常开发中总需要验证用户的数据是否正确,数据可能来自输入、可能来自导入,如果是庞大的对象校验起来,难道需要一串 if(){}else{} 嵌套判断吗?

这个验证器诞生了,就是为了防止 if 嵌套去校验对象,形成代码屎山。虽然我擅长在屎山上雕花。

使用

Maven项目可添加引用:

<dependency>
    <groupId>net.renfei</groupId>
    <artifactId>validator</artifactId>
    <version>1.0.0</version>
</dependency>

然后给需要校验的对象字段上增加注解,实例化一个Verifier校验器对象,执行verifier.verification(object),获得一个VerifiedReport 校验报告对象,例如使用内置的注解:

public class ObjectToBeVerified {
    @NotNullCheck(businessName = "统一社会信用代码不为空")
    @UnifiedCodeCheck(businessName = "统一社会信用代码")
    private String UnifiedCodeTestField2 = "91310000775785552L";
}

public class ValidatorTests {
    @Test
    public void test() {
        ObjectToBeVerified objectToBeVerified = new ObjectToBeVerified();
        Verifier verifier = new Verifier();
        VerifiedReport report = verifier.verification(objectToBeVerified);
        System.out.println("| 校验结果:" + report.getPassed());
        System.out.println("| 校验对象:" + report.getObjectName());
        System.out.println("| 结果详情:");
        for (VerifiedReportDetail detail : report.getDetailList()
        ) {
            System.out.printf("| 校验结果:【" + (detail.getPassed() ? "通过" : "不通过") + "】\t");
            System.out.printf("业务字段:【" + detail.getBusinessName() + "】\t");
            System.out.printf("数据原值:【" + detail.getFieldValue() + "】");
            System.out.println();
        }
    }
}

内置注解

注解 描述 参数
@ChinaIdCardCheck 中国身份证号校验 businessName=业务描述
@ChinaMobilePhoneCheck 中国移动通信手机号校验 businessName=业务描述
@ChinaMvnoPhoneCheck 中国手机虚拟运营商号校验 businessName=业务描述
@ChinaPhoneCheck 中国手机号校验 businessName=业务描述
@ChinaTelecomPhoneCheck 中国电信手机号校验 businessName=业务描述
@ChinaUnicomPhoneCheck 中国联通手机号校验 businessName=业务描述
@DomainNameCheck 域名格式校验 businessName=业务描述
@EmailCheck 电子邮箱格式校验 businessName=业务描述
@IsNullCheck 数据为空验证 businessName=业务描述
@LengthCheck 数据长度验证 length=长度,businessName=业务描述
@LengthMaxCheck 数据最大长度验证 max=长度,businessName=业务描述
@MaxCheck 数据最大值验证 max=长度,businessName=业务描述
@MinCheck 数据最小值验证 min=长度,businessName=业务描述
@NotNullCheck 数据不为空验证 businessName=业务描述
@PatternCheck 正则表达式验证 regexp=正则表达式,businessName=业务描述
@UnifiedCodeCheck 统一社会信用代码验证 rbusinessName=业务描述

自定义验证器与自定义注解

在很多复杂的业务中,数据校验可能需要联合多个字段进行校验,这个时候就需要自定义验证器,甚至自定义注解。

自定义验证器

在下面的案例中,我们将自定义一个验证器,例如需求是:当对象的name为空时,email为必填项:

public class Demo{
    public void test() {
        MyObj myObj = new MyObj();
        net.renfei.validator.Verifier verifier = new net.renfei.validator.Verifier();
        VerifiedReport report = verifier.verification(myObj);
        System.out.println("校验结果:" + report.getPassed());
        System.out.println("校验对象:" + report.getObjectName());
        System.out.println("结果详情:");
        for (VerifiedReportDetail detail : report.getDetailList()
        ) {
            System.out.printf("校验结果:【" + (detail.getPassed() ? "通过" : "不通过") + "】\t");
            System.out.printf("业务字段:【" + detail.getBusinessName() + "】\t");
            System.out.printf("数据原值:【" + detail.getFieldValue() + "】");
            System.out.println();
        }
    }
}

public class MyObj {
    private String name;
    @Validator(businessName = "邮箱字段", verifier = MyVerifier.class)
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

public class MyVerifier implements Verifier {
    @Override
    public VerifiedReportDetail verification(Annotation annotation, Object object, Field field) {
        VerifiedReportDetail report = new VerifiedReportDetail();
        field.setAccessible(true);
        if (object instanceof MyObj) {
            MyObj myObj = (MyObj) object;
            try {
                report.setPassed(true);
                if (myObj.getName() == null) {
                    if (myObj.getEmail() == null) {
                        report.setPassed(false);
                    }
                }
                report.setFieldValue(field.get(object) == null ? null : field.get(object).toString());
                report.setFieldType(field.getType().getName());
            } catch (IllegalAccessException e) {
                report.setPassed(false);
                e.printStackTrace();
            }
        } else {
            report.setPassed(false);
        }
        report.setFieldName(field.getName());
        report.setVerificationTime(new Date());
        report.setVerifierName(this.getClass().getName());
        report.setValidatorName(annotation.toString());
        report.setBusinessName(((Validator) annotation).businessName());
        return report;
    }
}

执行结果得到:

校验结果:false
校验对象:net.renfei.demo.MyObj
结果详情:
校验结果:【不通过】	业务字段:【邮箱字段】	数据原值:【null】

自定义注解

如果net.renfei.validator.annotation.Validator注解不够用,那就需要自定义注解,例如我们想传递年龄进去,那就这样:

@Inherited
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Validator(verifier = MyVerifier.class)
public @interface Age {
    long age() default 18;
}

那么在自定义验证器中这样获取注解:

public class MyVerifier implements Verifier {
    @Override
    public VerifiedReportDetail verification(Annotation annotation, Object object, Field field) {
        VerifiedReportDetail report = new VerifiedReportDetail();
        Age age = (Age) annotation;
        // 拿到注解中传递的值
        age.age();
        // 省略一些业务代码
        return report;
    }
}

About

Java 验证器

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Languages