Verifier 简单的 Java 校验工具

verifier

自己写的开源的、自由简单的 Java 校验工具,支持代码编写和注解方式,支持 Springboot 集成。github地址verifier

引入

<dependency>
  <groupId>online.qiqiang</groupId>
  <artifactId>verifier-spring-boot-starter</artifactId>
  <version>1.1.7-RELEASE</version>
</dependency>

简单使用案例

VerifierBuilderTest.java

文本校验

示例:

VerifierBuilder verifierBuilder = new VerifierBuilder();
String bookName = "";
String author = "";
Verifier verifier = verifierBuilder
  // 配置校验器,默认名称为类名简称 TextVerifier
  .addVerifier(new TextVerifier())
  // 配置自定义名称的校验器
  .addVerifier("myTextVerifier", new TextVerifier())
  .warningFormat("myTextVerifier", "%s必填!")
  // 用TextVerifier校验 bookName字段
  .add("TextVerifier", "bookName", "书名", bookName)
  // 用myTextVerifier校验 author字段
  .add("myTextVerifier", "author", "作者", author)
  .build();
VerifyResult verifyResult = verifier.verify();
logger.info(verifyResult.toString());
Assert.assertTrue(verifyResult.hasWarning());

结果:

{key='author', subject='作者', warning='作者必填!'}
{key='bookName', subject='书名', warning='书名校验失败'}

正则文本校验

示例:

VerifierBuilder verifierBuilder = new VerifierBuilder();
// 自定义日期校验
DateTextVerifier myDateTextVerifier = new DateTextVerifier();
myDateTextVerifier.setPattern("[1-2]\\d{3}\\d{2}\\d{2}");
// 自定义正则校验
TextRegexVerifier webSiteVerifier = new TextRegexVerifier(new ArrayList<>(), "http[s]?://www..*.com");
Verifier verifier = verifierBuilder
  // 日期校验,默认 yyyy-MM-dd
  .addVerifier(new DateTextVerifier())
  .addVerifier("myDateVerifier", myDateTextVerifier)
  .addVerifier("webSiteVerifier", webSiteVerifier)
  .warningFormat("webSiteVerifier","%s格式不正确")
  .add("DateTextVerifier", "publicationDate2", "出版日期2", "2020-01-01")
  .add("DateTextVerifier", "publicationDate3", "出版日期3", "2020-011-011")
  .add("myDateVerifier", "publicationDate4", "出版日期4", "2020-01-01")
  .add("myDateVerifier", "publicationDate6", "出版日期6", "90200101")
  .add("webSiteVerifier", "webSite", "网站", "https://www.baidu.cn")
  .build();
VerifyResult verifyResult = verifier.verify();
logger.info(verifyResult.toString());
Assert.assertTrue(verifyResult.hasWarning());

结果:

{key='publicationDate3', subject='出版日期3', warning='出版日期3校验失败'}
{key='publicationDate4', subject='出版日期4', warning='出版日期4校验失败'}
{key='publicationDate6', subject='出版日期6', warning='出版日期6校验失败'}
{key='webSite', subject='网站', warning='网站格式不正确'}

数字校验

示例

VerifierBuilder verifierBuilder = new VerifierBuilder();
Verifier verifier = verifierBuilder
  .addVerifier(new NumberVerifier())
  .add("NumberVerifier", "price", "价格", null)
  .build();
VerifyResult verifyResult = verifier.verify();
logger.info(verifyResult.toString());
Assert.assertTrue(verifyResult.hasWarning());

结果

{key='price', subject='价格', warning='价格校验失败'}

选择校验(单选和多选)

示例:

VerifierBuilder verifierBuilder = new VerifierBuilder();
Verifier verifier = verifierBuilder
  // 单选
  .addVerifier(new SelectVerifier())
  // 多选
  .addVerifier(new MultipleSelectVerifier())
  .add("SelectVerifier", "classify", "分类", "散文", (SelectVerifierOptionsFunction) () -> {
    List<String> options = new ArrayList<>(2);
    options.add("小说");
    options.add("诗歌");
    return options;
  })
  .add("MultipleSelectVerifier", "hobbies", "爱好", new ArrayList<String>() {{
    add("打篮球");
    add("踢足球");
    add("打游戏");
  }}, (SelectVerifierOptionsFunction) () -> {
    List<String> options = new ArrayList<>(2);
    options.add("打篮球");
    options.add("踢足球");
    options.add("睡觉觉");
    return options;
  })
  .build();
VerifyResult verifyResult = verifier.verify();
logger.info(verifyResult.toString());
Assert.assertTrue(verifyResult.hasWarning());

结果:

{key='classify', subject='分类', warning='分类选项非法'}
{key='hobbies', subject='爱好', warning='爱好选项非法'}

自定义校验器

示例:

VerifierBuilder verifierBuilder = new VerifierBuilder();
Verifier verifier = verifierBuilder
  .addVerifier("myVerifier", new AbstractVerifier() {
    @Override
    public Optional<VerifyResponse> test(VerifyItem verifyItem) {
      // 自定义校验逻辑
      return Optional.of(new VerifyResponse(verifyItem.getKey(), verifyItem.getSubject(), "任何信息都是错误的"));
    }
  })
  .add("myVerifier", "key", "subject", "12345")
  .build();
VerifyResult verifyResult = verifier.verify();
logger.info(verifyResult.toString());
Assert.assertTrue(verifyResult.hasWarning());

结果

{key='key', subject='subject', warning='任何信息都是错误的'}

基于注解方式

编写需要校验的对象类,省略了setget方法

@VerifyObject({
  // 配置校验器,未指定名字,默认是简单类名
  @VerifierConfig(verifier = TextVerifier.class),
  @VerifierConfig(verifier = DateTextVerifier.class),
  @VerifierConfig(verifier = CollectionVerifier.class),
  @VerifierConfig(verifier = SelectVerifier.class),
  @VerifierConfig(verifier = MultipleSelectVerifier.class),
  // 指定校验器类型和名字还有警告格式
  @VerifierConfig(verifier = TextVerifier.class, name = "myTextVerifier",warningFormat = "我的自定义校验%s未通过"),
  @VerifierConfig(verifier = NumberVerifier.class),
})
// 可继承父类的成员变量,并校验
public class BookForm extends BaseForm{
  // 定义校验主题,可设置多个,如果校验失败会产生多条校验失败的记录
  // 指定通过verifier、verifyIndex或者verifierName指定校验器
  @VerifySubject(subject = "bookName", verifier = TextVerifier.class)
  @VerifySubject(subject = "书名", verifyIndex = 0)
  private String bookName;
  @VerifySubject(verifierName = "myTextVerifier")
  private String author;
  @VerifySubject(subject = "publicationDate", verifyIndex = 1)
  private String publicationDate;
  @VerifySubject(subject = "代理商", verifyIndex = 2)
  private Collection<String> proxy;
  @VerifySubject(subject = "分类", verifyIndex = 3)
  // 定义可选项
  @SelectionOptions({"小说", "诗歌", "散文"})
  private String classify;
  @VerifySubject(subject = "分类2", verifyIndex = 4)
  @SelectionOptions({"小说", "诗歌", "散文"})
  private List<String> classify2;
}

public class BaseForm {
    @VerifySubject(subject = "id", verifier = NumberVerifier.class)
    private Integer id;
}

校验示例:

BookForm bookForm = new BookForm();
ArrayList<String> proxy = new ArrayList<>();
proxy.add("代理商1");
bookForm.setProxy(proxy);
bookForm.setClassify("杂志");
bookForm.setClassify2(new ArrayList<>());
VerifierBuilder verifierBuilder = new VerifierBuilder();
Verifier verifier = verifierBuilder.verifyObject(bookForm)
  .build();
VerifyResult verifyResult = verifier.verify();
logger.info(verifyResult.toString());
Assert.assertTrue(verifyResult.hasWarning());

结果:

{key='publicationDate', subject='publicationDate', warning='publicationDate校验失败'}
{key='author', subject='author', warning='我的自定义校验author未通过'}
{key='classify', subject='分类', warning='分类选项非法'}
{key='bookName', subject='bookName', warning='bookName校验失败'}
{key='bookName', subject='书名', warning='书名校验失败'}
{key='id', subject='id', warning='id校验失败'}

高级扩展

基于注解的自定义校验器

@VerifyObject(
  value = @VerifierConfig(verifier = MyRuleVerifier.class),
  handlers = MyRuleAppendHandler.class)
public class RuleModel {
  @MyRuleTag(rule = 1)
  @VerifySubject(subject = "姓名", verifyIndex = 0)
  private String name;
  @VerifySubject(subject = "地址", verifyIndex = 0)
  @MyRuleTag(rule = 0)
  private String address;

  @Override
  public String toString() {
    return "RuleModel{" +
      "name='" + name + '\'' +
      ", address='" + address + '\'' +
      '}';
  }
}


/**
 * 定义一个规则注解
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyRuleTag {
    int rule() default -1;
}

public class MyRuleAppendHandler implements AppendHandler<MyRuleVerifier> {
    @Override
    public Object[] handle(Field field, Object source) {
        MyRuleTag annotation = field.getAnnotation(MyRuleTag.class);
        int rule = annotation.rule();
        // 将校验规则和源对象作为附加对象
        return new Object[]{rule, source};
    }
}

public class MyRuleVerifier extends AbstractVerifier {
    @Override
    public Optional<VerifyResponse> test(VerifyItem verifyItem) {
        // 获取附加对象
        Object[] append = verifyItem.getAppend();
        // 从附加对象中获取源对象
        System.out.println("源对象为" + append[1].toString());
        // 从附加对象中获取校验规则
        int rule = (int) append[0];
        if (rule == 1) {
            System.out.println(verifyItem.getSubject() + "按规则1校验");
        } else if (rule == 0) {
            System.out.println(verifyItem.getSubject() + "按规则0校验");
        }
        return Optional.empty();
    }
}

结果:

源对象为RuleModel{name='null', address='null'}
姓名按规则1校验
源对象为RuleModel{name='null', address='null'}
地址按规则0校验

和 Spring Boot 集成

具体使用参见SpringBoot集成案例

  1. 配置application.yml

    verifier:
      #  默认使用 @TargetVerifyMethod 拦截,可自定义
      target-verify-method: com.qingcha.verifier.spring.TargetVerifyMethod
      # 只校验@Service类,可以自定义,未指定则是所有 Bean
      target-verify-class: org.springframework.stereotype.Service
      #  拦截顺序
      order: 1234
    
  2. 启动类添加注解

    @SpringBootApplication
    @EnableVerifier
    public class ExampleApplication {
      public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(ExampleApplication.class);
        StudentService studentService = context.getBean(StudentService.class);
        Student student = new Student();
        student.setGrade("六年级");
        student.setHobbies(Collections.singletonList("睡觉"));
        studentService.addStudent(student);
      }
    }
    
  3. 编写自定义校验回调

    @Component
    public class ExampleVerifierWarningCallback implements VerifierWarningCallback {
    
      @Override
      public void finallyWarningCallback(VerifyResult verifyResult) throws Throwable {
        // 此处如果不满足校验条件,可以抛出异常终止操作
        System.out.println(verifyResult);
      }
    }
    
  4. 指定拦截方法

    @Service
    public class StudentServiceImpl implements StudentService {
    
      @TargetVerifyMethod
      @Override
      public String addStudent(Student student) {
        return student.getName();
      }
    }
    
  5. 结果

    {key='grade', subject='年级', warning='年级选项不合法'}
    {key='name', subject='姓名', warning='姓名必填'}
    {key='hobbies', subject='爱好', warning='爱好选项非法'}
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值