2011-04-28 3 views
62

serialization 요구에 simpleXML을 사용할 계획 이었지만 새로운 것을 배우기 위해 JSON을 사용해 보려고했습니다.Gson이 POJO의 ArrayList를 직렬화 할 때 문제가 발생했습니다

이것은 Gson 1.7.1을 사용하여 테스트 POJO의 ArrayList를 시도하고 직렬화하기 위해 사용하는 코드입니다.

참고 : 코드를 단순화하기 위해 Reader/Writers에서 문자열 "s"을 제거했습니다. 내 초보자의 눈에

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

이 제대로 표시 : 여기

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)); 
    } 
} 

내가 얻을 출력됩니다. 오직 객체의 DeSerialized리스트는 TestObject의 직렬화가 아닌 기본 객체를 포함합니다. 아무도 나에게 설명해 주시겠습니까? 만약이 작품을 만들 수 있다면?

편집 : 테스트를 수정

: 감사 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 :

솔직히 이유를 알고하지 않습니다 ,하지만 ㅁ 저는 TestObject에 포함 된 간단한 String []을 ArrayList로 대체했습니다. 올바르게 직렬화되기 시작했습니다.

--- 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() 호출을 제거하십시오. 단일 스레드 시나리오가 있습니다.이 호출은 오버 헤드 만 추가합니다. 다른 것은 –

+0

입니다. 그들은 내가 그것을 얻을 수 있는지 확인하기 위해 거기에있다. 일단 작동하면, 나는 그들을 제거 할 것입니다. 이것은 교육적인 이유 때문입니다. Json 직렬화에 대한 좋은 아이디어를 얻으면 실제 사용을 위해 건물을 시작할 것입니다. – RogueDeus

+0

그런데, TypeToken으로 deserialize하기 위해 Object 임베디드 배열을 얻는 방법을 알 수있는 곳을 누군가가 알려줄 수 있습니까? – RogueDeus

답변

150

당신은 당신이 사용하고 List의 특정 제네릭 형식 (또는 함께 사용하는 일반적인 유형)에 GSON 정보를 제공해야합니다. 특히 JSON을 비 직렬화 할 때 각 배열 요소를 deserialize해야하는 객체의 유형을 결정할 수있는 정보가 필요합니다.

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

+1

Queue의 serialization에 관한 또 다른 질문이있을 수 있습니다. 당신이 꺼리지 않기를 바랍니다. – RogueDeus

+0

나는 거기에서 약간 빨랐다. TestObject의 String []에 TypeToken을 적용하는 방법을 찾아야 할 것 같습니다. – RogueDeus

관련 문제