2010-09-21 10 views
50

Estoy tratando de utilizar Gson deserializar una cadena JSON devuelto de mi servicio webGson y deserializar un conjunto de objetos con matrices en ella

La estructura sería devuelto como TypeDTO[].

donde TypeDTO es como

int id; 
String name; 
ArrayList<ItemDTO> items[] 

y ItemDTO es como

int id; 
String name; 
Boolean valid; 

Cuando llamo el código de la siguiente manera

Gson gson = new Gson(); 
TypeDTO[] mytypes = (TypeDTO[]) gson.fromJson(reply, TypeDTO[].class); 

Todo dentro de los objetos es nulo

Sin embargo, Si utilizo el

JSONArray y JSONObject para sacarlos parte por parte de los frascos org.json, funciona muy bien y los campos están poblados en consecuencia.

¿Alguna idea de lo que estoy haciendo mal? ¿Gson es extremadamente rápido? ¿O es mejor seguir con lo que ya tengo trabajando?

Gracias, David

+0

Necesita más información. ¿Cuál es el formato del JSON que está recibiendo? ¿Por qué tienes una matriz de 'ArrayList' en tu' TypeDTO'? Gson maneja bien este tipo de cosas. – ColinD

+0

Pensé que había dado una imagen clara del JSON. El nivel superior es una lista de objetos. Cada objeto tiene múltiples pares de kv, uno de ellos es otra lista de objetos con más pares de kv. – DavieDave

+0

¿Alguien tiene alguna sugerencia? – DavieDave

Respuesta

98

El ejemplo de estructura de datos de Java en la pregunta original no coincide con la descripción de la estructura JSON en el comentario.

El JSON se describe como

"un conjunto de {objeto con una gran variedad de {objeto}}".

En cuanto a los tipos descritos en la pregunta, el JSON traduce en una estructura de datos de Java que se correspondería con la estructura JSON para una fácil deserialización con Gson es

"un conjunto de {objeto TypeDTO con una serie de { Objeto ItemDTO}} ".

Pero la estructura de datos de Java proporcionada en la pregunta no es esta. En su lugar, es

"una matriz de {objeto TypeDTO con una matriz de una matriz de {objeto ItemDTO}}".

Una matriz bidimensional! = Una matriz unidimensional.

Este primer ejemplo demuestra el uso de Gson para simplemente deserializar y serializar una estructura JSON que es "una matriz de {objeto con una matriz de {objeto}}".

input.json Contenido:

[ 
    { 
    "id":1, 
    "name":"name1", 
    "items": 
    [ 
     {"id":2,"name":"name2","valid":true}, 
     {"id":3,"name":"name3","valid":false}, 
     {"id":4,"name":"name4","valid":true} 
    ] 
    }, 
    { 
    "id":5, 
    "name":"name5", 
    "items": 
    [ 
     {"id":6,"name":"name6","valid":true}, 
     {"id":7,"name":"name7","valid":false} 
    ] 
    }, 
    { 
    "id":8, 
    "name":"name8", 
    "items": 
    [ 
     {"id":9,"name":"name9","valid":true}, 
     {"id":10,"name":"name10","valid":false}, 
     {"id":11,"name":"name11","valid":false}, 
     {"id":12,"name":"name12","valid":true} 
    ] 
    } 
] 

Foo.java:

import java.io.FileReader; 
import java.util.ArrayList; 

import com.google.gson.Gson; 

public class Foo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    Gson gson = new Gson(); 
    TypeDTO[] myTypes = gson.fromJson(new FileReader("input.json"), TypeDTO[].class); 
    System.out.println(gson.toJson(myTypes)); 
    } 
} 

class TypeDTO 
{ 
    int id; 
    String name; 
    ArrayList<ItemDTO> items; 
} 

class ItemDTO 
{ 
    int id; 
    String name; 
    Boolean valid; 
} 

Este segundo ejemplo se utiliza en lugar de una estructura JSON que es en realidad "un conjunto de {objeto TypeDTO con una matriz de una matriz de {ItemDTO object}} "para que coincida con la estructura de datos Java proporcionada originalmente.

input.json Contenido:

[ 
    { 
    "id":1, 
    "name":"name1", 
    "items": 
    [ 
     [ 
     {"id":2,"name":"name2","valid":true}, 
     {"id":3,"name":"name3","valid":false} 
     ], 
     [ 
     {"id":4,"name":"name4","valid":true} 
     ] 
    ] 
    }, 
    { 
    "id":5, 
    "name":"name5", 
    "items": 
    [ 
     [ 
     {"id":6,"name":"name6","valid":true} 
     ], 
     [ 
     {"id":7,"name":"name7","valid":false} 
     ] 
    ] 
    }, 
    { 
    "id":8, 
    "name":"name8", 
    "items": 
    [ 
     [ 
     {"id":9,"name":"name9","valid":true}, 
     {"id":10,"name":"name10","valid":false} 
     ], 
     [ 
     {"id":11,"name":"name11","valid":false}, 
     {"id":12,"name":"name12","valid":true} 
     ] 
    ] 
    } 
] 

Foo.java:

import java.io.FileReader; 
import java.util.ArrayList; 

import com.google.gson.Gson; 

public class Foo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    Gson gson = new Gson(); 
    TypeDTO[] myTypes = gson.fromJson(new FileReader("input.json"), TypeDTO[].class); 
    System.out.println(gson.toJson(myTypes)); 
    } 
} 

class TypeDTO 
{ 
    int id; 
    String name; 
    ArrayList<ItemDTO> items[]; 
} 

class ItemDTO 
{ 
    int id; 
    String name; 
    Boolean valid; 
} 

En cuanto a las otras dos preguntas:

es Gson extremadamente rápido?

No se compara con otras API de deserialización/serialización. Gson ha sido tradicionalmente amongst el slowest. Se informa que las versiones actual y siguiente de Gson incluyen mejoras significativas en el rendimiento, aunque no he buscado los últimos datos de pruebas de rendimiento para respaldar esas afirmaciones.

Dicho esto, si Gson es lo suficientemente rápido para sus necesidades, entonces debido a que hace que la deserialización JSON sea tan fácil, probablemente tenga sentido usarla. Si se requiere un mejor rendimiento, entonces Jackson podría ser una mejor opción de usar. Ofrece muchas (tal vez incluso todas) las comodidades de Gson.

¿O es mejor seguir con lo que ya estoy trabajando?

No lo haría. Yo casi siempre prefiere tener una simple línea de código como

TypeDTO[] myTypes = gson.fromJson(new FileReader("input.json"), TypeDTO[].class); 

... deserializar fácilmente en una estructura de datos compleja, de las treinta líneas de código que de otro modo serían necesarios para mapear las piezas juntas en un componente un momento.

+0

Gracias por su solución, después de tres horas de intentar en vano, su método fue el mejor que encontré. – Awemo

+7

@Programmer Bruce +1 por decir "más bien tener una línea de código simple". El poder de GSON no es lo rápido que analiza, sino lo rápido que es escribir y mantener el código requerido para una gran cantidad de casos de producción. Y cuando necesita optimizar, el modelo de transmisión de GSON proporciona incrementos de gran rendimiento. –

0

Usa tu clase de bean de esta manera, si tus datos JSON comienzan con un objeto de matriz. esto te ayuda.

Users[] bean = gson.fromJson(response,Users[].class); 

Los usuarios son mi clase de bean.

La respuesta es mis datos JSON.

Cuestiones relacionadas