web-dev-qa-db-fra.com

Gson et désérialisation d'un tableau d'objets contenant des tableaux

J'essaie d'utiliser Gson pour désérialiser une chaîne JSON renvoyée par mon service Web. 

La structure serait retournée sous la forme TypeDTO[].

TypeDTO est comme

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

et ItemDTO est comme

int id;
String name;
Boolean valid;

Quand j'appelle le code comme suit

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

Tout ce qui est à l'intérieur des objets est nul

Cependant, si j'utilise le 

JSONArray et JSONObject pour les extraire pièce par pièce des bocaux org.json, cela fonctionne bien et les champs sont remplis en conséquence.

Des idées sur ce que je fais mal? Est-ce que Gson est extrêmement rapide? Ou est-ce que je préfère rester avec ce que j'ai déjà travaillé?

Merci, David. 

59
DavieDave

L'exemple de structure de données Java de la question d'origine ne correspond pas à la description de la structure JSON dans le commentaire.

Le JSON est décrit comme 

"un tableau de {objet avec un tableau de {objet}}".

En termes de types décrits dans la question, le JSON traduit en une structure de données Java qui correspond à la structure JSON pour une désérialisation aisée avec Gson est 

"un tableau de {objet TypeDTO avec un tableau de {objet ItemDTO}}".

Mais la structure de données Java fournie dans la question n’est pas la suivante. Au lieu de cela c'est 

"un tableau de {objet TypeDTO avec un tableau d 'un tableau de {objet ItemDTO}}".

Un tableau à deux dimensions! = Un tableau à une dimension.

Ce premier exemple montre comment utiliser Gson pour désérialiser et sérialiser simplement une structure JSON qui est "un tableau de {objet avec un tableau de {objet}}".

input.json Contenu:

[
  {
    "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;
}

Ce deuxième exemple utilise à la place une structure JSON qui est en réalité "un tableau d'objet {TypeDTO avec un tableau d'un tableau d'objet {ItemDTO}}" pour correspondre à la structure de données Java fournie à l'origine.

input.json Contenu:

[
  {
    "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 ce qui concerne les deux questions restantes:

gson est-il extrêmement rapide? 

Non comparé à d'autres API de désérialisation/sérialisation. Gson a traditionnellement été parmi les les plus lents . Les versions actuelles et futures de Gson apporteraient des améliorations significatives en termes de performances, bien que je n’aie pas cherché les dernières données de test de performances permettant de prendre en charge ces revendications.

Cela dit, si Gson répond assez rapidement à vos besoins, son utilisation facilitant la désérialisation JSON, il est probablement judicieux de l’utiliser. Si de meilleures performances sont requises, alors Jackson pourrait être un meilleur choix à utiliser. Il offre beaucoup (peut-être même tout) des commodités de Gson.

Ou est-ce que je préfère rester avec ce que j'ai déjà travaillé?

Je ne voudrais pas Je préférerais le plus souvent toujours avoir une simple ligne de code comme 

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

... pour désérialiser facilement dans une structure de données complexe, que les trente lignes de code qui seraient autrement nécessaires pour mapper les éléments ensemble, un composant à la fois.

113
Programmer Bruce

Utilisez votre classe de bean comme ceci, si vos données JSON commencent par un objet tableau. ça vous aide.

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

Les utilisateurs est ma classe de haricots. 

La réponse est mes données JSON.

0
nagabrahmam