V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Cbdy
V2EX  ›  Java

Java 世界有没有类似 joi 的验证库?

  •  
  •   Cbdy · 2018-03-08 15:29:50 +08:00 · 4457 次点击
    这是一个创建于 2213 天前的主题,其中的信息可能已经有所发展或是发生改变。

    api 比如可以是这样的

    ...
    var schema = Joi.type(Person.class)
                    .feild("name", Joi.string().alphanum().required())
                    .feild("age", Joi.integer().max(120).min(0))
                    .feild("address", Joi.type(Address.class).required());
                    
    var result = Joi.validate(schema, person);
    ...
    
    第 1 条附言  ·  2018-03-08 18:53:15 +08:00
    更正一个拼写错误:feild => field
    第 2 条附言  ·  2018-03-08 21:12:30 +08:00
    找了一下似乎没有比较满意的,只能自己动手撸了😳
    https://github.com/cbdyzj/joi
    21 条回复    2020-03-31 23:46:50 +08:00
    joysir
        1
    joysir  
       2018-03-08 15:53:49 +08:00
    可以看看 Bean Validation
    Cbdy
        2
    Cbdy  
    OP
       2018-03-08 18:55:34 +08:00
    @joysir 有了解过 jsr303,但是侵入性太大了,密密麻麻注解看得头晕
    hpeng
        3
    hpeng  
       2018-03-08 18:59:34 +08:00
    你那样才叫入侵性大.
    Cbdy
        4
    Cbdy  
    OP
       2018-03-08 20:01:36 +08:00
    @hpeng 怎么说?注解那个,要加到每个对象,侵入性不是更大吗?
    lhx2008
        5
    lhx2008  
       2018-03-08 20:04:47 +08:00
    我也比较喜欢用注解,joi 这样写在代码里面不是也要每个对象加吗,管理起来也不方便
    Cbdy
        6
    Cbdy  
    OP
       2018-03-08 21:16:31 +08:00
    @lhx2008 joi 实际是一种 dsl,写起来比较直观,也比较好维护,集中管理,不像直接分散在各个地方;其次验证实际是放在一层处理的,有的时候也许要单独验证某个属性字段之类的,joi 足够灵活性满足各种要求
    zjp
        7
    zjp  
       2018-03-08 21:32:18 +08:00 via Android
    佩服一言不合立马自己造轮子的

    基于注解 Bean Validation 配合反序列化很好用,不过灵活性可以说完全没有…
    JamesPan
        8
    JamesPan  
       2018-03-08 21:33:37 +08:00   ❤️ 1
    @Cbdy 主动调用的验证方案有 Apache 的 Commons Validator,你实现的类库本质上和这个类似;声明式的验证方案就是 @joysir 说的 Bean Validation,参考实现是 Hibernate Validator。


    @hpeng 说的侵入性,是指参数校验逻辑侵入了业务逻辑。Commons Validator 方案需要在对象验证时显示调用验证器,而 Bean Validation 则将验证预期以声明的方式给出,业务逻辑和验证逻辑完全分离。

    从趋势看 Bean Validation 优于 Commons Validator。
    boywang004
        9
    boywang004  
       2018-03-08 22:10:58 +08:00   ❤️ 1
    给你的轮子提一个建议:
    ObjectSchema<T> {
    public ObjectSchema<T> field(Function<T,?> getter, Schema schema);
    }
    强类型是编译重构友好的,更激进可以 public <I> ObjectSchema<T> field(Function<T,?> getter, Schema<I> schema);
    Cbdy
        10
    Cbdy  
    OP
       2018-03-08 23:58:31 +08:00
    @boywang004 谢谢,我对 Java 范型还要学习一个😂,第一个 T 是指验证的对象的类型吗?第二个 I 是指啥呢?没有看懂。。
    cbdyzj
        11
    cbdyzj  
       2018-03-09 01:00:03 +08:00 via Android
    @Cbdy 懂了😄
    boywang004
        12
    boywang004  
       2018-03-09 10:02:30 +08:00
    @Cbdy 第二个写错了
    public <I> ObjectSchema<T> field(Function<T,I> getter, Schema<I> schema);
    可以理解下嗯……
    调用时就是 Joi.type(Xxx.class).field(Xxx:getSomeField, integer().max()...);
    嘛,说多了,造轮子前多学习找轮子是个好习惯,多看看别的轮子啥的。
    Cbdy
        13
    Cbdy  
    OP
       2018-03-09 11:20:33 +08:00
    @boywang004 没有太理解为什么要用 getter,直接这样写也可以的吧,传一个 lambda 链式调用的时候稍显麻烦
    public <I> ObjectSchema<T> field(String field, Schema<I> schema);
    Cbdy
        14
    Cbdy  
    OP
       2018-03-09 13:22:43 +08:00
    @boywang004 我去了解的一下 Java8 的方法引用,了解了😂
    Cbdy
        15
    Cbdy  
    OP
       2018-03-09 13:23:16 +08:00
    @boywang004 本来只考虑了用反射。。。有点思维江化
    yoqu
        16
    yoqu  
       2018-03-09 14:14:19 +08:00
    其实我对 hibernate validte 有意见,根据 jsr303 规范要加注解在实体类上,当实体类需要在不同表单做不同规则的验证就很蛋疼了,而且将注解加入到实体类我觉得很操蛋,还不如单独写个配置类或者像 joi 这样来处理来的方便,不过还需要统一管理,而不是在 controller 层去做验证处理。
    Cbdy
        17
    Cbdy  
    OP
       2018-03-09 15:44:36 +08:00
    @yoqu jsr303 我觉得不好的地方是代码密密麻麻,看得烦,本来 Java 就就要写一堆 getter、setter 现在每个 field 再加一两个注解注解,本来 10 个属性,硬生生写出三五十行代码,增加了人眼 parse 代码的负担

    代码应该足够清晰、精简
    letitbesqzr
        18
    letitbesqzr  
       2018-03-09 16:06:50 +08:00
    Cbdy
        19
    Cbdy  
    OP
       2018-03-09 23:37:49 +08:00
    @letitbesqzr 恕我直言,Fluent Validator 这个库不是很 fluent
    amwyyyy
        20
    amwyyyy  
       2018-03-27 16:09:49 +08:00
    @yoqu 可以试试用 groups
    dcalsky
        21
    dcalsky  
       2020-03-31 23:46:50 +08:00
    https://gist.github.com/dcalsky/f380e7861392ee875e786d67616b49a9

    刚刚基于 Ktor 以及 Hibernate Validator 写的,轻便美观无侵入。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4562 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 09:56 · PVG 17:56 · LAX 02:56 · JFK 05:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.