json 序列化有没有办法保存对象的类型? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
abcbuzhiming
V2EX    Java

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

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

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

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

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

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

    Class {

    }
    abcbuzhiming
        14
    abcbuzhiming  
    OP
       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
        15
    meepo3927  
       2017-07-10 10:29:33 +08:00
    json 源于描述 Javascript 的对象和数据,而后广泛应用。

    所以,json 本身肯定不携带 Class 咯
    wenzhoou
        16
    wenzhoou  
       2017-07-10 11:32:04 +08:00 via Android
    这个 AAA 的实现类是固定的 AAAImpl , 还是 根据情况分为 AAAa 和 AAAb 的不同实现类?
    abcbuzhiming
        17
    abcbuzhiming  
    OP
       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
        18
    wenzhoou  
       2017-07-10 18:34:48 +08:00 via Android
    根据不同的情况分不同的实现类的话。如果用我链接的方法不行的话。你需要直接转成 map 然后自己根据情况,把 map 再转成对应的类。暂时没别的想法。
    decken
        19
    decken  
       2017-07-10 19:46:12 +08:00
    @meowu #10 能举个例子吗? 我用着一直没遇到啥大问题, 除了上次 1.2.29 修复安全漏洞, 限制了 autoType 对某些老版本在特定 case 下不兼容
    woshixiaohao1982
        20
    woshixiaohao1982  
       2017-07-23 15:32:51 +08:00
    @slixurd 序列化版本可以方便缓存部分失效,例如你发布了新版的程序,这样旧版留存的对象保存在 redis 里面就自动失效了
    关于     帮助文档     助推广系统     博客     API     FAQ     Solana     4481 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 05:35 PVG 13:35 LAX 22:35 JFK 01:35
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86