FastJson在反序列化时如果HashSet中有引用,则会多null的节点

huangzhtao01 发布于 2014/04/10 16:48
阅读 2K+
收藏 0

【Gopher China万字分享】华为云的Go语言云原生实战经验!>>>

@wenshao 你好,想跟你请教个问题:

我们在使用FastJson做序列化和反序列化的时候,发现一个问题,如果HashSet中有引用,则会多null的节点。

代码如下

Deal类:

package com.testset;

public class Deal{
	private Long id;
	private String name;
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

DealGroup类:

package com.testset;

import java.util.HashSet;

public class DealGroup{
	private String name;
	private Deal deal;
	private HashSet<Deal> hset;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public HashSet<Deal> getHset() {
		return hset;
	}
	public void setHset(HashSet<Deal> hset) {
		this.hset = hset;
	}
	public Deal getDeal() {
		return deal;
	}
	public void setDeal(Deal deal) {
		this.deal = deal;
	}
}

测试类:

package com.testset;

import java.util.HashSet;
import com.alibaba.fastjson.JSON;

public class Test {
	public static void main(String[] args) {
		Deal d1 = new Deal();
		Deal d2 = new Deal();

		d1.setId(123L);
		d1.setName("aaa");

		d2.setId(223L);
		d2.setName("bbb");

		DealGroup dg = new DealGroup();
		dg.setName("ccc");
		dg.setDeal(d1);
		HashSet<Deal> hs = new HashSet<Deal>();
		hs.add(d1);
		hs.add(d2);
		hs.add(d1);
		hs.add(d2);
		dg.setHset(hs);
		System.out.println(dg.getHset().size());

		String jsonString = JSON.toJSONString(dg);
		System.out.println(jsonString);
		
		
		DealGroup u = JSON.parseObject(jsonString, DealGroup.class);
	
		System.out.println(u.getHset().size());
	}

}



运行结果:

2
{"deal":{"id":123,"name":"aaa"},"hset":[{"$ref":"$.deal"},{"id":223,"name":"bbb"}],"name":"ccc"}
3



可以看到Set结构中多了一个item,该item所有属性均为null,此问题应该是个bug。

经测试对List没有此问题。


加载中
0
如梦技术
如梦技术
有个范型帮助类的 名字忘记了,具体请看文档
0
一个程序猿的异常
一个程序猿的异常
为什么我这文档网站都打不开了
0
huangzhtao01
huangzhtao01

引用来自“孤独的3”的评论

有个范型帮助类的 名字忘记了,具体请看文档
应该是 CollectionResolveFieldDeserializer 吧
但是具体该如何用呢?
0
大喵哥
大喵哥

JSON.toJSONString(dg,SerializerFeature.DisableCircularReferenceDetect);

0
huangzhtao01
huangzhtao01

引用来自“Singer”的评论

JSON.toJSONString(dg,SerializerFeature.DisableCircularReferenceDetect);

不能DisableCircularReferenceDetect啊,因为定义中存在循环。

0
Spance
Spance

很明显,这跟bug半毛钱关系都没有。

CircularReference 循环引用,如果你知道这个意思,那么就不会有此想法了。

fastjson把循环引用转为$ref这种语法正是它的一个明显特点,否则就要陷入死循环了。

另外一点,放入hash结构中的数据,要实现hashcode方法,用于区别不同的对象,这也就是你只看到了一个$ref的原因。 

0
huangzhtao01
huangzhtao01

引用来自“gohsy”的评论

很明显,这跟bug半毛钱关系都没有。

CircularReference 循环引用,如果你知道这个意思,那么就不会有此想法了。

fastjson把循环引用转为$ref这种语法正是它的一个明显特点,否则就要陷入死循环了。

另外一点,放入hash结构中的数据,要实现hashcode方法,用于区别不同的对象,这也就是你只看到了一个$ref的原因。 

我不知道你有没有认真看我的问题或者做下测试。
我的问题并不是对$ref提出问题,相反我们正是在利用这个特性。这个问题在List上也没有问题,在HashSet中存在问题。
0
abcbuzhiming
abcbuzhiming

引用来自“gohsy”的评论

很明显,这跟bug半毛钱关系都没有。

CircularReference 循环引用,如果你知道这个意思,那么就不会有此想法了。

fastjson把循环引用转为$ref这种语法正是它的一个明显特点,否则就要陷入死循环了。

另外一点,放入hash结构中的数据,要实现hashcode方法,用于区别不同的对象,这也就是你只看到了一个$ref的原因。 

引用来自“huangzhtao01”的评论

我不知道你有没有认真看我的问题或者做下测试。
我的问题并不是对$ref提出问题,相反我们正是在利用这个特性。这个问题在List上也没有问题,在HashSet中存在问题。
兄弟,你这个问题我也遇到了,不仅hashset,map里也存在,但是唯独list没有,list的反序列化能正常的到值,map反序列化,值对象里面直接为空
返回顶部
顶部