我发布了一个自认为很厉害的 Java 参数校验组件,它几乎可以满足所有的参数校验场景,请各位 V 友发表一些看法

查看 53|回复 4
作者:sticki   
如题,组件名为 “SpEL Validator”,下面我会进行一些介绍,希望各位看完后可以发表一些看法。
「 SpEL Validator 」是基于 SpEL 的参数校验包,也是 javax.validation 的扩展增强包,用于简化参数校验。
解决了什么问题?

  • 枚举值字段校验:
    @SpelAssert(assertTrue = " T(cn.sticki.enums.UserStatusEnum).getByCode(#this.userStatus) != null ", message = "用户状态不合法")
    private Integer userStatus;

  • 多字段联合校验:
    @NotNull
    private Integer contentType;
    @SpelNotNull(condition = "#this.contentType == 1", message = "语音内容不能为空")
    private Object audioContent;
    @SpelNotNull(condition = "#this.contentType == 2", message = "视频内容不能为空")
    private Object videoContent;

  • 复杂逻辑校验,调用静态方法:
    // 中文算两个字符,英文算一个字符,要求总长度不超过 10
    // 调用外部静态方法进行校验
    @SpelAssert(assertTrue = "T(cn.sticki.util.StringUtil).getLength(#this.userName)

  • 调用 Spring Bean (需要使用 @EnableSpelValidatorBeanRegistrar 开启 Spring Bean 支持):
    // 这里只是简单举例,实际开发中不建议这样判断用户是否存在
    @SpelAssert(assertTrue = "@userService.getById(#this.userId) != null", message = "用户不存在")
    private Long userId;

  • 等待探索……

    我认为的特点
  • 强大的参数校验功能,几乎支持所有场景下的参数校验。
  • 扩展自 javax.validation 包,只新增不修改,无缝集成到项目中。
  • 基于 SpEL ( Spring Expression Language ) 表达式,支持复杂的校验逻辑。
  • 支持调用 Spring Bean ,可在表达式中使用注入过的 Spring Bean 。
  • 校验时基于整个对象,支持对象内字段间的校验逻辑。
  • 支持自定义校验注解,可根据业务需求自定义校验逻辑。
  • 无需额外的异常处理,校验失败时会上报到 javax.validation 的异常体系中。
  • 简单易用,使用方式几乎与 javax.validation 一致,学习成本低,上手快。

    使用方式

  • 添加依赖
    Latest Version:

        cn.sticki
        spel-validator
        Latest Version
        org.hibernate.validator
        hibernate-validator
        ${hibernate-validator.version}
        org.springframework.boot
        spring-boot-starter-web
        ${spring-boot-starter-web.version}

  • 在接口参数上使用 @Valid 或 @Validated 注解
    @RestController
    @RequestMapping("/example")
    public class ExampleController {
      /**
       * 简单校验示例
       */
      @PostMapping("/simple")
      public Resp simple(@RequestBody @Valid SimpleExampleParamVo simpleExampleParamVo) {
        return Resp.ok(null);
      }
    }

  • 在实体类上使用 @SpelValid 注解,同时在需要校验的字段上使用 @SpelNotNull 等约束注解
    @Data
    @SpelValid
    public class SimpleExampleParamVo {
      @NotNull
      private Boolean switchAudio;
      /**
       * 当 switchAudio 为 true 时,校验 audioContent ,audioContent 不能为 null
       */
      @SpelNotNull(condition = "#this.switchAudio == true", message = "语音内容不能为空")
      private Object audioContent;
    }

  • 发起请求,即可看到校验结果

    性能上我目前还没有进行测试,但代码里使用了很多的反射,会有一定的损耗,后面我准备多加一些缓存,尽量降低性能上的影响。
    大概就是这样
    以上是关于这个组件的大概介绍,希望各位大佬能够对此发表一些看法,好或者不好都可以发表,感谢各位~
    感兴趣的朋友也可以到 GitHub 或者掘金查看详细情况。
    GitHub 地址: https://github.com/stick-i/spel-validator
    我在掘金发布的详细说明文章: https://juejin.cn/post/7365698962531401766
  • jwj   
    下次一定用
    HojiOShi   
    我虽然不是搞后端这方向的,不过 java 一定有很多同类的库,你的这个和已有的库相比有什么优势吗?看到测试也没有写,怎么让人放心用到生产环境中去呢?
    sticki
    OP
      
    @HojiOShi
    1. 目前没有找到功能和我这个一样的库,它的优势就是我上面写到的 “解决了什么问题” 部分
    2. 目前确实没有写测试用例,只有少数的使用示例在一个单独的项目中,这块确实需要补充,感谢提醒
    fkdog   
    就这句:
    @SpelNotNull(condition = "#this.switchAudio == true", message = "语音内容不能为空")
    我自己定义一个静态方法,ExceptionUtils.throwIf(this.switchAudio, "语音内容不能为空")不就好了?
    为什么还要额外引入你一个类库呢,而且借助反射 API 还会降低额外性能。
    而且参数校验逻辑是一个很个性化的东西,javax validation 自带的满足最通用的足矣。
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部