json 序列化有没有办法保存对象的类型?

2017-07-09 12:15:25 +08:00
 abcbuzhiming
最近在工作上遇到一个问题,才意识到 jdk 序列化和 json 序列化比起来,多保存了对象的类型,于是 json 序列化在遇到反序列化时,要把你反序列化得到的对象赋值给一个接口的时候,json 序列化就吃瘪了,jvm 此时往往会告诉你 json 库不知道该把你的反序列化对象转化成什么类型。而 jdk 序列化完全没有这个问题,因为 jdk 序列化后得到的流里保存了对象的真实类型,这个问题有解吗?
6571 次点击
所在节点    Java
20 条回复
sagaxu
2017-07-09 12:21:20 +08:00
json 不可能保存对象类型,json 反序列化的时候,你不是自己可以指定对象类型吗?
slixurd
2017-07-09 12:21:54 +08:00
这个难道不是优势么....
JSON 反序列化只要显式指定反序列化的 Class Reference,就可以被反序列化
JDK 的 Serializable 最大的问题就是需要匹配上 Full-qualified name.....
还有需要通过 Version ID 来判断版本,否则会错位....
wwqgtxx
2017-07-09 12:44:04 +08:00
主要是因为 json 很多的用在跨语言序列化中,要是保存了类型,怎么跨语言呢,难道再根据类型给各个语言实例化一个版本?
yinzhili
2017-07-09 12:45:44 +08:00
json 跨语言的啊,不同语言的类型都不一样,没法指定。
miao1007
2017-07-09 13:41:38 +08:00
楼主需要 RPC 中的 SDL
0915240
2017-07-09 13:45:18 +08:00
序列化的时候不可能保存对象类型啊

所以你需要在反序列化的时候去指定啊,恩,没毛病。
DeadLion
2017-07-09 15:45:55 +08:00
最近在用 dubbo 的时候也发现了这个问题
消费方对于嵌套泛型无法准确反序列化 使用 json 做序列化的时候

不过楼上有人说了,使用 Class Reference 就可以转成指定的对象了。
zjsxwc
2017-07-09 15:56:52 +08:00
可以自定制个 json 类型(某个字段包含对象的类型),以及对应的序列化与反序列化方法

其实楼主的需求最好还是用 xml 来表示,序列化可以先把对象转换为 xml 对象再转 json ; 反序列化先转为 xml 对象再转为实际对象。
decken
2017-07-09 16:07:27 +08:00
fastjson 有这个特性
meowu
2017-07-09 23:40:05 +08:00
@decken fastjson 是坑 项目做的大的话 千万别用
wenzhoou
2017-07-10 07:55:13 +08:00
abcbuzhiming
2017-07-10 10:14:10 +08:00
@wenzhoou 谢了,虽然对我的项目没啥用

@DeadLion 我现在发现 json 序列化的坑挺大的,以前都是序列化有明确类型的对象,所以感觉不到,现在要序列化的对象,内部接口套接口,有些接口你都不知道它的具体实现是啥,这种是不是就没法应用 json 序列化了
abcbuzhiming
2017-07-10 10:18:11 +08:00
@slixurd 你指的是类似这种 Map<Class,Class>
但我面对的情况挺麻烦的

Class {

}
abcbuzhiming
2017-07-10 10:22:36 +08:00
@slixurd 无意中发出去了,我遇到的情况是这样的类型
public class XXXXX{
private AAA aaa; //这个 AAA 是个 interface
private Map<Object, Object> attributes;
}
jasckson 序列化这个类的对象时没有问题,但是反序列化 json 字符串到这个 XXXXX 类的时候就会吃瘪,而且这个 XXXXX 类似别人定义的,我没法改
meepo3927
2017-07-10 10:29:33 +08:00
json 源于描述 javascript 的对象和数据,而后广泛应用。

所以,json 本身肯定不携带 Class 咯
wenzhoou
2017-07-10 11:32:04 +08:00
这个 AAA 的实现类是固定的 AAAImpl , 还是 根据情况分为 AAAa 和 AAAb 的不同实现类?
abcbuzhiming
2017-07-10 11:51:12 +08:00
@wenzhoou 多个,不同的实现类,而且这只是其中一个困扰点,
另外一个 private Map<Object, Object> attributes;这个困扰点很麻烦,我发现 jackson 对反序列化 Map<String, Object>存在漏洞,什么都不设定的情况下,它把 Object 全部当 LinkHashMap 来处理,但是如果提供的字符串内容中有类似"[111,222,333]"这样的数组结构,它还是按 Map 处理,然后直接就抛异常
wenzhoou
2017-07-10 18:34:48 +08:00
根据不同的情况分不同的实现类的话。如果用我链接的方法不行的话。你需要直接转成 map 然后自己根据情况,把 map 再转成对应的类。暂时没别的想法。
decken
2017-07-10 19:46:12 +08:00
@meowu #10 能举个例子吗? 我用着一直没遇到啥大问题, 除了上次 1.2.29 修复安全漏洞, 限制了 autoType 对某些老版本在特定 case 下不兼容
woshixiaohao1982
2017-07-23 15:32:51 +08:00
@slixurd 序列化版本可以方便缓存部分失效,例如你发布了新版的程序,这样旧版留存的对象保存在 redis 里面就自动失效了

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

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

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

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

© 2021 V2EX