web-dev-qa-db-fra.com

Utiliser GSON pour analyser un JSON avec dynamique "clé" et "valeur" dans Android

Je travaille actuellement sur un projet Android qui nécessite que j'appelle un service Web qui me renverra un fichier json. J'utilisais la bibliothèque GSON pour analyser tout le fichier json et obtenir un objet JSON. Cela a bien fonctionné jusqu'à ce que je rencontre ces données JSON dont les champs clés sont dynamiques. Un exemple de ce fichier est comme ci-dessous:

{ "0": { "count":"5"},
  "1": { "title":"...", "desc":"" },
  "2": { "title":"...", "desc":"" },
  "3": { "title":"...", "desc":"" },
  "4": { "title":"...", "desc":"" },
  "5": { "title":"...", "desc":"" },
  "routes": { "route1":"...", "route3":"" },
}

Je peux obtenir le nombre en fonction de l'ID clé "0", mais je ne sais pas comment utiliser cette valeur pour obtenir les autres objets clé (ID clé 1-5), qui sont constitués des données J'ai eu besoin. J'apprécierai vraiment si quelqu'un est capable de m'aider dans cette affaire. Merci.

28
Philip

L’approche la plus simple à laquelle je puisse penser consiste à traiter la structure comme une Map (de Map).

Avec Gson, cela est relativement facile à faire, tant que la structure Map est connue de manière statique, chaque branche de la racine a la même profondeur et tout est une String.

import Java.io.FileReader;
import Java.lang.reflect.Type;
import Java.util.Map;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class GsonFoo
{
  public static void main(String[] args) throws Exception
  {
    Gson gson = new Gson();
    Type mapType = new TypeToken<Map<String,Map<String, String>>>() {}.getType();
    Map<String,Map<String, String>> map = gson.fromJson(new FileReader("input.json"), mapType);
    System.out.println(map);

    // Get the count...
    int count = Integer.parseInt(map.get("0").get("count"));

    // Get each numbered entry...
    for (int i = 1; i <= count; i++)
    {
      System.out.println("Entry " + i + ":");
      Map<String, String> numberedEntry = map.get(String.valueOf(i));
      for (String key : numberedEntry.keySet())
        System.out.printf("key=%s, value=%s\n", key, numberedEntry.get(key));
    }

    // Get the routes...
    Map<String, String> routes = map.get("routes");

    // Get each route...
    System.out.println("Routes:");
    for (String key : routes.keySet())
      System.out.printf("key=%s, value=%s\n", key, routes.get(key));
  }
}

Pour un traitement plus dynamique de la structure Map, je suggère fortement de changer pour utiliser Jackson , au lieu de Gson, car Jackson désérialisera tout objet JSON de toute complexité arbitraire en une Map Java, avec une simple ligne de code, et conserver automatiquement les types de valeurs primitives.

import Java.io.File;
import Java.util.Map;

import org.codehaus.jackson.map.ObjectMapper;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    Map map = mapper.readValue(new File("input.json"), Map.class);
    System.out.println(map);
  }
}

La même chose peut être obtenue avec Gson, mais cela nécessite des dizaines de lignes de code. (De plus, Gson a d'autres inconvénients qui font que le passage à Jackson en vaut vraiment la peine.)

36
Programmer Bruce

Vous pouvez simplement obtenir les objets de clé individuels en utilisant le nombre. Ainsi, vous obtiendrez l'objet "1", puis ses objets "title" et "desc", puis "2", etc. 

0
Torid