2010-05-19 7 views
19

En resumen, este es un esquema del objeto JSON quiero analizar en JAVA:¿Cómo uso la API Gson de Google para deserializar JSON correctamente?

{ 
    object1: { 
      item1: //[String | Array | Object] , 
      item2: // ... 
      //<> more items 
    object2: { /* .. */ } 
    //<> more objects 
} 

Estos son los POJO s he creado para el análisis (Voy a dejar de lado el import declaraciones para abreviar):

(1) la representación del objeto completo JSON

public class JObjectContainer { 

    private List<JObject> jObjects ; 

    public JObjectContainer() { } 

    //get & set methods 

} 

(2) la representación de los objetos anidados:

public class JObject { 

    private String id ; 
    private List<JNode> jObjects ; 

    public JObject() { } 

    //get & set methods 

} 

(3) La representación de los artículos:

public class JNode { 

    private JsonElement item1 ; 
    private JsonElement item2 ; 
    //<> more item fields 

    public JNode() { } 

    //get & set methods 

} 

Ahora, la creación de una instancia Gson (FileReader para importar el jsonFile),

Gson gson = new Gson() ; 
JObjectContainer joc = gson.fromJson(jsonFile,JObjectContainer.class) ; 

me siento un NullPointerException cada vez que intento para acceder al objeto analizable (p. ej. a través de ListIterator). Gson hace sin embargo crea un objeto de la clase I especificada y no arroja ningún error posterior.

Sé que esto se ha hecho antes. Entonces, ¿qué me estoy perdiendo?

TIA

Respuesta

33

Eso no es posible. Necesita modificar su estructura JSON para representar object1, object2, etc. como elementos de una matriz . En este momento son propiedades de un objeto del cual aparentemente no se sabe cuántos de ellos serán (de lo contrario, no intentó asignarlo como List). Gson es inteligente, pero no que inteligente :)

Por lo tanto, como un ejemplo básico, esta estructura JSON con una matriz:

{ nodes: 
    [ 
    { item1: 'value1a', item2: 'value2a' }, 
    { item1: 'value1b', item2: 'value2b' }, 
    { item1: 'value1c', item2: 'value2c' } 
    ] 
} 

en combinación con la representación de Java (que no es necesariamente estar llamado POJO, pero solo javabean o objeto de modelo u objeto de valor).

public class Container { 
    private List<Node> nodes; 
    // +getter. 
} 

public class Node { 
    private String item1; 
    private String item2; 
    // +getters. 
} 

y esta llamada Gson

Container container = new Gson().fromJson(json, Container.class); 

debería funcionar.

Actualización: para que quede claro, su estructura JSON es el problema, no su estructura de objetos Java. Suponiendo que la estructura de su objeto Java es exactamente lo que le gustaría terminar con, a continuación, su estructura JSON debe ser similar a la siguiente para obtener Gson para hacer su trabajo:

{ jObjects: 
    [ 
    { id: 123, jObjects: 
     [ 
     { item1: 'value1a', item2: 'value2a' }, 
     { item1: 'value1b', item2: 'value2b' }, 
     { item1: 'value1c', item2: 'value2c' } 
     /* etc... commaseparated */ 
     ] 
    }, 
    { id: 456, jObjects: 
     [ 
     { item1: 'value1d', item2: 'value2d' }, 
     { item1: 'value1e', item2: 'value2e' }, 
     { item1: 'value1f', item2: 'value2f' } 
     /* etc... commaseparated */ 
     ] 
    } 
    /* etc... commaseparated */ 
    ] 
} 

Sólo la propiedad JsonElement debe sustituirse por String, ya que no es válido

+1

Hola, gracias por tu respuesta! Tenía la intención de mantener las cadenas de identificador (por ejemplo, 'Object1'), para poder analizar correctamente la clase Container para su contenido, al igual que lo haría en JavaScript. ¿Sabes cómo hacerlo? – FK82

+0

Si esas cadenas de identificador están vinculadas a cada elemento ('Node'), no al contenedor (' nodes'), entonces necesita convertirlo en una propiedad del 'Node'. Los objetos JS con una cantidad desconocida de propiedades y nombres de propiedad desconocidos simplemente no son una buena idea/práctica. Debe ponerlos en una matriz y darle un nombre fijo a la matriz. – BalusC

+0

Eso supera el propósito de usar JSON por completo. Si no puedo reflejar el estilo de mapeo de objetos de JSON en JAVA, también podría escribir mi propia API. ;-) Básicamente estoy tratando de hacer lo mismo que en este example while somehow retaining the identifier strings. – FK82

0

Creo que BalusC dio buenos consejos para la pregunta específica de GSon (y en general, enlace de datos uno a uno); pero por si crees que debería haber un manejo más dinámico, también podrías considerar otros paquetes de procesamiento JSON. Muchos paquetes tienen formas adicionales o alternativas para mapear cosas: Json-lib, flexjson y Jackson al menos tienen adiciones en comparación con Gson. Algunos ofrecen mapeo más flexible (se definen los nombres de las cosas para los tipos), otros soporte real para los tipos polimórficos (declarando un Objeto, pero en realidad se puede mapear al subtipo que se serializó).

+0

Hola, gracias por tu respuesta. En realidad, no estaba tan seguro de cómo funciona GSON internamente y, en consecuencia, no entendía muy bien cómo usarlo. Ahora estoy usando un análisis personalizado con Rhino, que es mucho más útil en mi opinión. Java no admite objetos de datos anidados de la misma manera que lo hace JavaScript, por lo que no existe un motivo real para no usar Rhino para ese tipo de cosas. – FK82

Cuestiones relacionadas