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

2021-06-10 18:59:53 +08:00
 0576coder

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

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

2723 次点击
所在节点    Java
19 条回复
xuanbg
2021-06-10 19:11:49 +08:00
我还想用 Object 也收获同样的功能呢。。。
0576coder
2021-06-10 19:20:09 +08:00
@xuanbg
老哥 我是认真的- -
我是真的想校验 map 的属性,如果没有优雅实现的话只能就按我上面手动实现
dethan
2021-06-10 19:51:55 +08:00
结构不确定的 map,结构不确定你怎么写规则
fkdog
2021-06-10 19:52:30 +08:00
我自己的经验是,验证这种东西都尽量在 controller 层自己去手动判断,而不是借助于框架的 validation 。

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

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

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

工程问题从来都是取舍 tradeoff 。
neptuno
2021-06-11 14:52:30 +08:00
考虑尽量不用 map ?参数还是用指定的一个类去接收吧
0576coder
2021-06-11 15:53:50 +08:00
@Gary43
感谢老哥 我试试

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/782726

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX