结构不固定的 json 值要怎么反序列化成对象比较好?

2021-09-01 14:12:17 +08:00
 x97bgt

json 里面有互斥的字段,要怎么序列化成对象?

比如下面的例子里,要么只有refund字段,要么只有purchase,而且两个字段里的结构是不一样的。

{
    "id": "1234567890",
    "amount": 100,
    "refund": {
        "date": "2021-04-23T18:25:43.511Z",
        "confirmed": true,
        "refund_id": 1234456
    }
}

{
    "id": "1234567890",
    "amount": 100,
    "purchase": {
        "date": "2021-04-23T18:25:43.511Z",
        "purchase_id": 789621
    }
}

现在到的最粗暴的办法,是把每个字段都塞进对象。但这太难看了,而且容易造成混乱。

这种结构下,要怎么设计对象的结构比较好?

3298 次点击
所在节点    Java
34 条回复
2kCS5c0b0ITXE5k2
2021-09-01 14:17:57 +08:00
应该要好好想想 为什么 id 能有重复的吧.
xiaokongwu
2021-09-01 14:19:27 +08:00
@emeab 人家只是随便写个例子吧
binux
2021-09-01 14:20:56 +08:00
两个类,反序列化之前判断一下是哪个。
wccc
2021-09-01 14:21:49 +08:00
加 type 结构保持一致
xiaokongwu
2021-09-01 14:23:34 +08:00
要不用 map 接吧……
jenlors
2021-09-01 14:24:10 +08:00
结构合并在一起,某些值可为空
micean
2021-09-01 14:26:21 +08:00
自己写个自定义的反序列化适配就可以了,但是还不如塞 2 个对象呢
YJi
2021-09-01 14:31:38 +08:00
要是非用一个类,感觉只能枚举所有字段了.. (蹲一个其他方案
thtznet
2021-09-01 14:35:32 +08:00
动态
BigDogWang
2021-09-01 14:36:13 +08:00
接口设计的不合理吧,难不成你要用的时候还要判断下这两个对象哪个不为 null ?
lower
2021-09-01 14:39:43 +08:00
type: 区分类型
data:存数据,直接用 Object 或者泛型
cpstar
2021-09-01 14:40:02 +08:00
json 本来就不是固定结构的,用编程语言的话叫不是强类型
反序列化到对象,肯定得是两个类了,一个类是 refund,一个类是 purchase,至于这两个类是否从一个 super class 中派生,那是另外一个事情了。
然后上工厂模式,factory.unserialize(json)
Puteulanus
2021-09-01 14:40:10 +08:00
早点判断早点分开比较好吧,感觉是过度抽象了,两个东西内容不一样硬要捏在一起的话,后面写会到处是 if 判断的
sankemao
2021-09-01 14:44:43 +08:00
加一个 type 用以区分
chendy
2021-09-01 14:46:27 +08:00
既然传进来之后要做区分,为什么不直接在接口一层就做区分呢?
不过确实存在一些一个接口怼所有类型的情况(比如一些 webhook ),我的做法是做一个包含所有可能字段的大类接参数进来(还好没有冲突)然后区分类型转换成需要的类型然后传给对应的业务
qinxi
2021-09-01 14:46:28 +08:00
加个 type 区分一下 然后用多态 JsonSubTypes
Kilerd
2021-09-01 15:20:48 +08:00
rust 里面的 enum 可以很好的处理这种情况。其他语言就只能自己些 deserializer 去判断 type 了
x97bgt
2021-09-01 15:25:47 +08:00
@wccc
@lower
@sankemao
@qinxi
加一个`type`和`data`,`type`用于判断类型,`data`则是一个抽象类或 Object,使用的时候强制转换。是这样对么?
zhady009
2021-09-01 16:11:44 +08:00
感觉类设计有点不太合理
建议还是根据 refund 字段是否为空来分组分开来分别序列化成对应的类型
Jooooooooo
2021-09-01 16:16:09 +08:00
弄个 type 呀.

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

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

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

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

© 2021 V2EX