2016-07-19 1 views
0

Je veux analyser la réponse JSON suivante avec un objet JSON dynamique,Parse manuellement une partie de l'objet JSON dynamique aux côtés Gson désérialiseur

{ 
    "id": 1, 
    "last_login": "2016-07-16T12:46:29.621996Z", 
    "point_of_sales": [ 
    { 
     "Counter 4": { 
     "type": "retail", 
     "id": 6 
     } 
    }, 
    { 
     "Counter 5": { 
     "type": "retail", 
     "id": 7 
     } 
    }, 
    { 
     "Counter 6": { 
     "type": "retail", 
     "id": 8 
     } 
    } 
    ] 
} 

Ici, les objets nom à l'intérieur « point_of_sales » tableau sont dynamiques qui fait il est difficile d'analyser en utilisant Gson. Voici ce que j'ai essayé jusqu'à présent,

@SerializedName("id") 
@Expose 
private Integer id; 
@SerializedName("last_login") 
@Expose 
private String lastLogin; 
@SerializedName("point_of_sales") 
@Expose 
private List<Map<String, Counter>> pointOfSales = new ArrayList<Map<String, Counter>>(); 

....... 

getter & setters 

classe contre,

@SerializedName("type") 
@Expose 
private String type; 
@SerializedName("id") 
@Expose 
private Integer id; 

....... 

getter & setters 

En suivant cette procédure, je peux convertir les objets mais ne peut pas les extraire de la carte aux classes POJO.

for (Map<String, Counter> objectMap : response.getPointOfSales()) 
{ 
// How to extract the Counter pojo data from map list? 
} 

J'ai essayé aussi de cette façon, mais rien ne fonctionne,

ArrayList<Counter> pojos = new ArrayList<Counter>(); 
        try { 
         for (Map<String, Counter> objectMap : result.getPointOfSales()) { 
          Counter pojo = new Counter(); 
          for (Map.Entry<String, Counter> property : objectMap.entrySet()) { 
           Method setter = Counter.class.getMethod("set" + property.getKey().substring(0, 1).toUpperCase() + property.getKey().substring(1), property.getValue().getClass()); 
           setter.invoke(pojo, property.getValue()); 
          } 
          pojos.add(pojo); 
         } 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 

        for (Counter pojo : pojos) { 
         Log.e("result", "" + pojo.getId() + " " + pojo.getType()); 
        } 

Est-il possible d'analyser le tableau spécifique en utilisant,

  1. Gson

  2. L'utilisation d'un Duel technique d'analyse pour analyser la partie spécifique manuellement et le reste de la réponse dans Gson?

Je souhaite placer les objets dynamiques enveloppés dans une classe pojo.

+1

vous avez besoin d'un JsonDeserializer pour cela. Si je comprends bien ce que vous voulez faire – Blackbelt

+0

je veux juste faire les objets dynamiques enveloppés dans une classe pojo afin que les données du champ "id", "type" puissent être reçues facilement. –

+0

alors je suppose qu'un custom [JsonDeserializer] (https://google.github.io/gson/apidocs/com/google/gson/JsonDeserializer.html) est ce dont vous avez besoin. – Blackbelt

Répondre

1

Vous avez besoin de deux choses.

  1. Vous devez faire un peu de refactoring sur vos classes de modèle.
  2. Vous devez ajouter un JsonDeserializer pour gérer cette analyse dynamique.

Voilà comment je le ferais:

MainObject.java

..... 
@SerializedName("point_of_sales") 
SalesPoints mSales Points 
..... 

SalesPoints.java

private List<Counter>mCounters; 
//getter & setters. 

Counter.java

SerializedName("type") 
private String type; 
@SerializedName("id") 
private int id; // use primitives instead of boxed primitives 
private String mCounterString; // maybe you need it. 

Maintenant, quand vous courrez le vous analyse aurez à faire quelque chose comme ceci:

MainObject object = new GsonBuilder().registerTypeAdapter(SalesPoints.class, new JsonDeserializer<SalesPoints>() { 
     @Override 
     public SalesPoints deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
      SalesPoints sales = new SalesPoints(); 
      ArrayList<Counter>counters = new ArrayList<Counter>(); 
      JsonArray salesJson = json.getAsJsonArray(); 
      for(JsonElement object : json.getAsJsonArray()) { 
        Iterator<Map.Entry<String,JsonElement>> iterator = object.getAsJsonObject().entrySet().iterator(); 
        while (iterator.hasNext())){ 
          Map.Entry<String,JsonElement> entry = iterator.next(); 
          String counterString = entry.getKey(); 
          JsonElement counterObject = 
                entry.getValue(); 
          Counter counter = context.deserialize(counterObject, Counter.class); 
          counter.setCounterString(counterString); 
          counters.add(counter); 
         }   
      } 
      sales.setCounters(counters); 
      return sales; 
     } 
    }).create().fromJson(theJson); 

Maintenant, lorsque le MainObject est analysé, il contiendra le SalesPoints qui contient tous les compteurs.

NOTE: J'ai peut-être mal orthographié certains mots, ou j'ai peut-être oublié d'ajouter quelques méthodes getAs.. parce que je n'avais pas la possibilité de tester le code, mais c'est le chemin à parcourir.

EDIT

Pour retrofit, vous aurez besoin de faire quelque chose comme ceci:

Gson gson = new GsonBuilder().registerTypeAdapter(SalesPoints.class, new JsonDeserializer<SalesPoints>() { 
     @Override 
     public SalesPoints deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
      SalesPoints sales = new SalesPoints(); 
      ArrayList<Counter>counters = new ArrayList<Counter>(); 
      JsonArray salesJson = json.getAsJsonArray(); 
      for(JsonElement object : json.getAsJsonArray()) { 
        Iterator<Map.Entry<String,JsonElement>> iterator = object.getAsJsonObject().entrySet().iterator(); 
        while (iterator.hasNext())){ 
          Map.Entry<String,JsonElement> entry = iterator.next(); 
          String counterString = entry.getKey(); 
          JsonElement counterObject = 
                entry.getValue(); 
          Counter counter = context.deserialize(counterObject, Counter.class); 
          counter.setCounterString(counterString); 
          counters.add(counter); 
         }   
      } 
      sales.setCounters(counters); 
      return sales; 
     } 
    }).create(); 


new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create(gson))//set remaining things fro your retrofit builder. 
+0

Qu'est-ce que "theJson" & "entry"? En fait, j'utilise Retrofit 2 pour faire le processus d'analyse et d'api callback. Je suis un peu confus sur où et comment utiliser JsonDeserializer avec Retrofit. –

+0

@FallingIntoInfinity Veuillez vérifier ma réponse éditée. – danypata