开发者社区> 问答> 正文

fastjson反序列化时如果实例有多个引用时有Bug!!!?报错

@wenshao 你好,想跟你请教个问题:反序列化下面JSON数据时报错

{"@type":"com.game.util.json.TestA","c":{"d":2,"e":3},"hm":{"@type":"java.util.HashMap",12:{"@type":"com.game.util.json.TestB","b2b":{"@type":"java.util.HashMap",1:{"$ref":"$.c"}}}}}


Exception in thread "main" com.alibaba.fastjson.JSONException: set property error, b2b
at com.alibaba.fastjson.parser.deserializer.FieldDeserializer.setValue(FieldDeserializer.java:102)
at com.alibaba.fastjson.JSON.handleResovleTask(JSON.java:279)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:246)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:220)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:179)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:327)
at com.game.util.json.JsonUtil.fromJson(JsonUtil.java:86)
at com.game.util.json.TestA.main(TestA.java:68)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.alibaba.fastjson.parser.deserializer.FieldDeserializer.setValue(FieldDeserializer.java:99)
... 7 more


展开
收起
爱吃鱼的程序员 2020-06-22 11:49:39 1853 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    有注解可以避免陷入循环的有方法控制序列化的层数,自己看API去...温少早已说过.额,不是循环的问题,是多个引用的问题<preclass="brush:java;toolbar:true;auto-links:false;">packagecom.game.util.json;importjava.util.HashMap;importjava.util.Map;publicclassTestA{Map<Integer,TestB>hm=newHashMap<Integer,TestB>();privateTestCc;publicTestCgetC(){returnc;}publicTestBgetB(intindex){returnhm.get(index);}publicvoidsetC(TestCc){this.c=c;}publicTestA(){hm.put(12,newTestB());}publicMap<Integer,TestB>getHm(){returnhm;}publicvoidsetHm(Map<Integer,TestB>hm){this.hm=hm;}publicstaticvoidmain(String[]args){TestAa=newTestA();TestCc=newTestC();TestBbb=a.getB(12);bb.add(c);a.c=c;Stringja=JsonUtil.toJson(a);System.out.println(ja);TestAb=JsonUtil.fromJson(ja,TestA.class);System.out.println(JsonUtil.toJson(b));}}packagecom.game.util.json;importjava.util.HashMap;importjava.util.Map;/类说明:@authorJimson@versionV1.02014-2-19下午10:15:23/publicclassTestB{privateMap<Integer,TestC>b2b=newHashMap<Integer,TestC>();publicvoidadd(TestCc){b2b.put(c.hashCode(),c);}publicMap<Integer,TestC>getB2b(){returnb2b;}publicvoidsetTestC(TestCb2b){this.b2b.put(12,b2b);}publicvoidsetB2b(Map<Integer,TestC>b2b){this.b2b=b2b;}}packagecom.game.util.json;/类说明:@authorLouisYu@versionV1.02014年2月27日下午1:28:11/publicclassTestC{intd=2;publicintgetD(){returnd;}publicvoidsetD(intd){this.d=d;}}




    发现了一种解决问题方法就是,把TestB.setB2b(Map<Integer,TestC>b2b)改成 TestB. setB2b(Mapb2b)就行.TestB.setB2b(Map<Integer,TestC>b2b)是eclipse自动生成的getter,setter不过这样感觉不是解决问题的根本办法,希望温少能从根本上解决问题

    JSON.toJSONString(o,SerializerFeature.DisableCircularReferenceDetect);

    解决方法~

    默认fastjson是打开索引引用的。如果是null对象,或者对象多特定情况下,引用就会出$ref等字眼。

    解决方法,关闭索引。 

    原来本身是两个引用指向同一个实例, 关闭索引后,反序化后,两个引用就变成两个实例了,这就会造成新的问题了<spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;font-size:14px;line-height:normal;background-color:#FFFFFF;"><spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;font-size:14px;line-height:normal;background-color:#FFFFFF;">反序列化时TestB.<spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;font-size:14px;line-height:normal;background-color:#FFFFFF;"><spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;font-size:14px;line-height:normal;background-color:#FFFFFF;">setB2b(Mapb2b),传进的参数map的key还是int,但是实际使用反序列得到的实例时,key不知为啥变成String了,问题依然没解决.....<spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;font-size:14px;line-height:normal;background-color:#FFFFFF;">

    2020-06-22 11:49:55
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载

相关实验场景

更多