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

关于 spring boot 的参数校验的问题,如何不用注解以及具体对象来校验 Map 里的属性

  •  
  •   0576coder · 4 天前 · 1065 次点击

    spring boot 里自带 validator 。使用方式基本上就是具体的类上加上注解比如我定一个 class A 然后在这个类里面加个属性 a1 加上注解 @NotNULL,这种。

    目前有个需求是这样的,我有个结构不确定的 Map,但是我那边有个需求就是要做参数校验,比如我手动写是可以实现的。代码如下

            Map<String, Object> a = new HashMap<>();
            a.put("a1", 12);
            a.put("a2", "sad1231dsad");
            Object a2 = a.get("a2");
            if(a2 instanceof String) {
                System.out.println("true");
            } else {
                System.out.println("false");
            }
    
    

    我目前的期望是,我不想再实现一遍 validator 校验的功能,如何实现对一个动态的 map 参数校验 我的想法是入参是两个 map 一个 map 传参数校验的 rule 另一个 map 传需要被校验的 map

    除了纯手写,有无更优雅的实现封装办法

    19 条回复    2021-06-11 15:53:50 +08:00
    xuanbg
        1
    xuanbg   4 天前
    我还想用 Object 也收获同样的功能呢。。。
    0576coder
        2
    0576coder   4 天前
    @xuanbg
    老哥 我是认真的- -
    我是真的想校验 map 的属性,如果没有优雅实现的话只能就按我上面手动实现
    dethan
        3
    dethan   4 天前 via Android
    结构不确定的 map,结构不确定你怎么写规则
    fkdog
        4
    fkdog   4 天前
    我自己的经验是,验证这种东西都尽量在 controller 层自己去手动判断,而不是借助于框架的 validation 。

    因为框架验证需要传入借助很多注释 api,过于侵入 pojo 。有时候不止 api 层需要做 validation,orm 层也需要 validation,有时候一个 pojo 里有多种 validation 会很奇怪。而且许多的项目,虽然你在 controller 层禁止某个字段 NULL,但是实际上在数据库里存的是允许为 NULL,这样其他人看着就很困惑。

    另外有时候多版本兼容、需求变更,可能某个接口里某个字段是允许为空的。这样的情况比比。

    所以还是手动写比较好。
    0576coder
        5
    0576coder   4 天前
    @dethan
    就是这个 map 可能有十几种情况 我如果不想写十几个具体的类
    我想传入一个 rule map 来动态的校验
    FreeEx
        6
    FreeEx   4 天前
    如果是 json 格式的话可以用 json schema 校验。
    securityCoding
        7
    securityCoding   4 天前
    设计一个小的核心组件,抽象一个 filter 接口 ,把所有情况用 filter 实现一遍
    echo1937
        8
    echo1937   4 天前
    @fkdog #4 你这是把 DO/DTO/BO/VO 这些全部用一个 pojo 来处理,那么自然会出现多种 validation 啊
    aragakiyuii
        9
    aragakiyuii   4 天前 via iPhone
    map 维护起来真的是…还是写个类维护吧…validator 可以做分组校验
    fkdog
        10
    fkdog   4 天前
    @echo1937
    说是这么说,但是实际开发里很多场景这些 object 都可以一个搞定。
    feitxue
        11
    feitxue   4 天前
    之前用百度的 FluentValidator 做复杂的校验...
    不过感觉对你来说还说这个框架还是太重了
    https://github.com/neoremind/fluent-validator
    lostSoul
        12
    lostSoul   4 天前
    那你这不适合在控制层做校验了 正如楼上说的 filter 和 json 校验 可以单独写一个 filter 拿到 json 对他进行规则校验 单纯的拿 map 一个一个 get 或者 entrySet 都不是很雅
    iseki
        13
    iseki   4 天前
    纯手写是最糟糕的做法,逻辑全部耦合死。不知道你输入是什么样子的,如果是 json,Jackson 之类的多态反序列化是可以处理的
    0576coder
        14
    0576coder   4 天前
    @lostSoul
    感谢老哥 我知道我这个不适合再控制层校验,主要我那边有特殊场景就是要这样用 map,我试试你推荐的
    0576coder
        15
    0576coder   4 天前
    @echo1937
    其实我写了差不多一年的 java 我感觉各种 O 是不是太多了,纯粹是为了面向对象而面向对象。还是说 java 都是这样的,我感觉是不是大家都受福报厂影响太深,他们的傻逼规范都变成了行业标杆
    Gary43
        16
    Gary43   4 天前
    echo1937
        17
    echo1937   4 天前
    @0576coder #15 你的 O 指的是返回给上层的实体类吧?当然可以不用啊,用 Map 来封装。需要自己详细记好 map 中 key-value 映射的关系,尤其的记好自己给每个数据库字段所定义的 key 值以做中间过程的查看或修改。其次,当你的代码不止你一个维护时,你的同事并不能通过查看实体类来获知你这个业务所传递的具体字段,只有通过询问或查看 Map 文件或者调试才能知晓,也不利于自己后期的 codeReview 。而且 Java 这种静态类型的语言,你取 value 的时候还需要从 object 强转。

    工程问题从来都是取舍 tradeoff 。
    neptuno
        18
    neptuno   4 天前
    考虑尽量不用 map ?参数还是用指定的一个类去接收吧
    0576coder
        19
    0576coder   3 天前
    @Gary43
    感谢老哥 我试试
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3458 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:07 · PVG 15:07 · LAX 00:07 · JFK 03:07
    ♥ Do have faith in what you're doing.