2011-04-28 51 views
62

我一直在计划使用simpleXML来处理序列化需求,但是我想我会尝试使用JSON来学习新的东西。Gson序列化POJO ArrayList的问题

这是我用来尝试使用Gson 1.7.1序列化测试POJO的ArrayList的代码。

注意:为了简化代码,我删除了字符串“s”的Reader/Writers。

package test; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

import com.google.gson.Gson; 

public class TestGsonSerialDeserialList { 
    public static void main(String[] args) throws IOException{ 
     Gson gson = new Gson(); 

     //Make Serial 
     String s; 
     List<TestObject> list = Collections.synchronizedList(new ArrayList<TestObject>()); 
     list.add(new TestObject()); 
     list.add(new TestObject()); 

     s = gson.toJson(list, ArrayList.class); 
     System.out.println(s); 

     //Eat Serial 
     List<TestObject> list2 = Collections.synchronizedList(gson.fromJson(s, ArrayList.class)); 
     System.out.println(list2.get(0)); 
     System.out.println(list2.get(1)); 
    } 
} 

这里是输出我得到:

[{"objectID":1,"i1":12345,"name":"abcdefg","s":["a","b","c"]},{"objectID":2,"i1":12345,"name":"abcdefg","s":["a","b","c"]}] 
[email protected] 
[email protected] 

为了我的新手眼里这看起来是正确的。只有DeSerialized对象列表包含基本对象,而不是TestObject的I序列化。任何人都可以向我解释什么,如果有的话,我可以做什么,使这项工作?

编辑:

修正测试:由于ColinD

package test; 

import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.Reader; 
import java.io.Writer; 
import java.lang.reflect.Type; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

import com.google.gson.Gson; 
import com.google.gson.reflect.TypeToken; 

public class TestGsonSerialDeserialList { 
    public static void main(String[] args) throws IOException{ 
     System.out.println("--- Serialize/Deserialize Started ---"); 
     String fileName = "json\\testList.json"; 

     Gson gson = new Gson(); 
     Type listOfTestObject = new TypeToken<List<TestObject>>(){}.getType(); 

     //Make Serial 
     Writer osWriter = new OutputStreamWriter(new FileOutputStream(fileName)); 
     List<TestObject> list = Collections.synchronizedList(new ArrayList<TestObject>()); 
     list.add(new TestObject()); 
     list.add(new TestObject()); 
     list.add(new TestObject()); 
     list.add(new TestObject()); 
     gson.toJson(list, osWriter); 
     osWriter.close(); 


     //Eat Serial 
     Reader isReader = new InputStreamReader(new FileInputStream((fileName))); 
     List<TestObject> list2 = Collections.synchronizedList(
      (List<TestObject>)gson.fromJson(isReader, listOfTestObject) 
     ); 
     isReader.close(); 
     System.out.println(list2.get(0)); 
     System.out.println(list2.get(1)); 
     System.out.println(list2.get(2)); 
     System.out.println(list2.get(3)); 
     System.out.println("--- Serialize/Deserialize Ended ---"); 
    } 
} 

输出:

--- Serialize/Deserialize Started --- 
ID#: 1, i1: 12345, name: abcdefg, s[]: [Ljava.lang.String;@95c083 
ID#: 2, i1: 12345, name: abcdefg, s[]: [Ljava.lang.String;@6791d8c1 
ID#: 3, i1: 12345, name: abcdefg, s[]: [Ljava.lang.String;@182d9c06 
ID#: 4, i1: 12345, name: abcdefg, s[]: [Ljava.lang.String;@5a5e5a50 
--- Serialize/Deserialize Ended --- 

EDIT2:

老实说,我不知道是什么原因,但是wh我用一个ArrayList替换了我的TestObject中嵌入的简单String [],它开始正确地序列化。

--- Serialize/Deserialize Started --- 
ID#: 1, i1: 12345, name: abcdefg, s[]: [a, b, c] 
ID#: 2, i1: 12345, name: abcdefg, s[]: [a, b, c] 
ID#: 3, i1: 12345, name: abcdefg, s[]: [a, b, c] 
ID#: 4, i1: 12345, name: abcdefg, s[]: [a, b, c] 
--- Serialize/Deserialize Ended --- 
+0

附注:摆脱Collections.synchronizedList()调用。你有一个单线程场景,这些调用只会增加开销,没有别的 – 2011-04-28 04:55:34

+0

你是对的。他们在那里确保我可以正常工作。一旦它的工作,我会删除它们。这完全是出于教育原因。一旦我对Json序列化有了一个好的想法,我将开始构建实际的应用。 – RogueDeus 2011-04-28 17:42:50

+0

话虽如此,任何人都可以指出我在哪里可以找出如何获得对象嵌入数组反序列化与TypeToken? – RogueDeus 2011-04-28 17:43:49

回答

150

你需要给上的List具体的泛型类型,你正在使用(或者你用它使用任何通用型)GSON信息。特别是在反序列化JSON时,它需要这些信息能够确定它应该反序列化每个数组元素的类型。

Type listOfTestObject = new TypeToken<List<TestObject>>(){}.getType(); 
String s = gson.toJson(list, listOfTestObject); 
List<TestObject> list2 = gson.fromJson(s, listOfTestObject); 

这记录在Gson user guide中。

+0

我担心我没有看到明显的东西。我之前从未使用过Type,并且在使用时感到困惑。你只是为我清理它。非常感谢你。 – RogueDeus 2011-04-28 04:10:23

+1

我可能很快就会遇到关于队列序列化的其他问题!希望你不介意。 – RogueDeus 2011-04-28 04:11:50

+0

那里我有点快。看来我需要找到一种方法将TypeToken应用于TestObject的String []。 – RogueDeus 2011-04-28 04:47:23