2011-04-28 10 views
62

Había estado planeando usar SimpleXML para mis necesidades de serialización, pero pensé que probaría JSON, para aprender algo nuevo.Problema con Gson serializando un ArrayList de POJO's

Este es el código que estoy usando para tratar de serializar un ArrayList de prueba POJO usando Gson 1.7.1.

Nota: Eliminé el lector/escritor por una cadena "s" para simplificar el código.

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

Aquí está la salida me sale:

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

A mis ojos novato esto parece correcto. Solo que la lista de objetos Deserializados contiene Objetos básicos, en lugar de serializar el TestObject. ¿Alguien puede explicarme qué puedo hacer para hacer que esto funcione?

EDIT:

corregido a prueba: Gracias a 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 ---"); 
    } 
} 

de salida:

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

Sinceramente, no sé por qué , pero wh es Reemplacé el simple String [] incrustado en mi TestObject con una ArrayList, comenzó a serializarse correctamente.

--- 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

nota al margen: Deshágase de las llamadas Collections.synchronizedList(). Tiene un escenario de un solo subproceso, estas llamadas solo agregan sobrecarga, nada más –

+0

Tiene razón. Están ahí para asegurarse de que pueda hacerlo funcionar. Una vez que esté funcionando, los eliminaré. Esto es puramente por razones educativas. Una vez que tenga una buena idea de la serialización de Json, comenzaré a construir para el uso real. – RogueDeus

+0

Habiendo dicho eso, ¿alguien puede indicarme dónde puedo encontrar la forma de hacer que la matriz incrustada de Object se deserialice con un TypeToken? – RogueDeus

Respuesta

150

que necesita para dar información Gson del tipo específico genérica de List que está usando (o cualquier tipo genérico se utiliza con él). Particularmente cuando se deserializa JSON, necesita esa información para poder determinar a qué tipo de objeto debe deserializar cada elemento de la matriz.

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

Esto está documentado en Gson user guide.

+0

Tenía miedo de no ver algo obvio. Nunca antes había usado Type's, y estaba confundido por su uso. Lo has aclarado por mí. Muchas gracias. – RogueDeus

+1

¡Probablemente tenga otra pregunta con respecto a la serialización de una cola pronto! Espero que no te importe. – RogueDeus

+0

Fui un poco rápido allí. Parece que necesito encontrar una forma de aplicar un TypeToken a la Cadena TestObject []. – RogueDeus