fastjson在反序列Set时出现多余空对象的问题

wing21st 发布于 2014/05/07 13:02
阅读 2K+
收藏 2

 

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

我们在使用FastJson对循环饮用对象进行序列化和反序列化的时候,发现一个问题,如果Set对象里包含对之前对象的引用时,会多反序列化出来一个空对象。

测试代码如下,最终反序列化出来的blist只有一个对象是正确的,而bset里多了一个空对象。

生成的json代码如下:

{"b":{"id":"2"},"d":{"blist":[{"$ref":"$.b"}],"bset":[{"$ref":"$.b"}]},"id":"1"}

JunitTest:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import junit.framework.Assert;

import org.junit.Test;

import com.alibaba.fastjson.JSON;
public class PlainCTest {
	@Test
	public void testChange() {
		PlainA a = new PlainA();
		a.setId("1");

		PlainB b = new PlainB();
		b.setId("2");
		a.setB(b);

		PlainD d = new PlainD();
		Set<PlainB> bset = new HashSet<PlainB>();
		bset.add(b);
		List<PlainB> blist = new ArrayList<PlainB>();
		d.setBset(bset);
		d.setBlist(blist);
		blist.add(b);
		a.setD(d);

		String text = JSON.toJSONString(a);
		PlainA aFromJson = JSON.parseObject(text, PlainA.class);
		Assert.assertEquals(1, aFromJson.getD().getBlist().size());
		Assert.assertEquals(1, aFromJson.getD().getBset().size());
	}
}

 

PlainA:

public class PlainA {
	private PlainB b;
	private PlainD d;
	private String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public PlainD getD() {
		return d;
	}

	public void setD(PlainD d) {
		this.d = d;
	}

	public PlainB getB() {
		return b;
	}

	public void setB(PlainB b) {
		this.b = b;
	}
}

PlainB:

package com.alcatel.acc;

public class PlainB {
	private String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

}

PlainD:

import java.util.List;
import java.util.Set;

public class PlainD {
	private List<PlainB> blist;
	private Set<PlainB> bset;

	public List<PlainB> getBlist() {
		return blist;
	}

	public void setBlist(List<PlainB> blist) {
		this.blist = blist;
	}

	public Set<PlainB> getBset() {
		return bset;
	}

	public void setBset(Set<PlainB> bset) {
		this.bset = bset;
	}
}
加载中
0
wing21st
wing21st

找到问题的原因了,ListResolveFieldDeserializer和CollectionResolveFieldDeserializer的构造方法中都会传入一个包含空对象的collection对象,不过二者实现的setValue方法是不同的。

CollectionResolveFieldDeserializer

public void setValue(Object object, Object value) {
        collection.add(value);
    }
ListResolveFieldDeserializer
public void setValue(Object object, Object value) {
        list.set(index, value);
        。。。。。。。。。。。。。
}

index默认为0,所以list会自动覆盖掉这个空对象,而Set的空对象则被保留下了。

这是一个bug,马克一下。

 

0
名字是什么能吃吗
名字是什么能吃吗

之前我也出这个问题 [{"$ref":"$.b"}] 不知道这个是怎么来的  换成toJSON就好了

0
huangzhtao01
huangzhtao01

引用来自“wing21st”的评论

找到问题的原因了,ListResolveFieldDeserializer和CollectionResolveFieldDeserializer的构造方法中都会传入一个包含空对象的collection对象,不过二者实现的setValue方法是不同的。

CollectionResolveFieldDeserializer

public void setValue(Object object, Object value) {
        collection.add(value);
    }
ListResolveFieldDeserializer
public void setValue(Object object, Object value) {
        list.set(index, value);
        。。。。。。。。。。。。。
}

index默认为0,所以list会自动覆盖掉这个空对象,而Set的空对象则被保留下了。

这是一个bug,马克一下。

 

我也遇到同样问题了,后面是怎么解决的?
0
huangzhtao01
huangzhtao01

引用来自“wing21st”的评论

找到问题的原因了,ListResolveFieldDeserializer和CollectionResolveFieldDeserializer的构造方法中都会传入一个包含空对象的collection对象,不过二者实现的setValue方法是不同的。

CollectionResolveFieldDeserializer

public void setValue(Object object, Object value) {
        collection.add(value);
    }
ListResolveFieldDeserializer
public void setValue(Object object, Object value) {
        list.set(index, value);
        。。。。。。。。。。。。。
}

index默认为0,所以list会自动覆盖掉这个空对象,而Set的空对象则被保留下了。

这是一个bug,马克一下。

 

@wenshao 已经被这个问题困扰好多天了,尝试了各种方法都没有解决。
0
libvirus
libvirus
问题解决了没有??  我也遇到这个问题了 
0
陈文锦的秘密
陈文锦的秘密
我也遇到了,排查了好长时间...
0
陈文锦的秘密
陈文锦的秘密

解决了 ,序列化的使用SerializerFeature.DisableCircularReferenceDetect 这个参数.

返回顶部
顶部