2015-11-17 10 views
13

Sto tentando di analizzare la seguente chiave dinamica JSON String.Parse Dynamic Key Json String utilizzando Retrofit

"report":{ 
    "data":{ 
     "results":{ 
      "558952cca6d73d7d81c2eb9d":{ 
       "Max":-1, 
       "Min":-1, 
       "Slope":-1, 
      }, 

      "558ce148a6d73d7d81c2fa8a":{ 
       "Max":-2, 
       "Min":-1, 
       "Slope":-2, 
      } 
     } 
    } 
} 

Di seguito sto cercando di ottenere dati, ma ricevo errore mentre analizzo l'ultima stringa json dinamica.

public class Report { 
     @SerializedName("data") 
     @Expose 
     private Data data; 

     public Data getData() { 
      return data; 
     } 

     public void setData(Data data) { 
      this.data = data; 
     } 

     @Override 
     public String toString() { 
      return "Report{" + 
        "data=" + data + 
        '}'; 
     } 
    } 

    public class Data { 
     @SerializedName("results") 
     @Expose 
     private ResultInside result; 

     public ResultInside getResult() { 
      return result; 
     } 

     public void setResult(ResultInside result) { 
      this.result = result; 
     } 
    } 

    public class ResultInside { 
     /*@SerializedName("results") 
     @Expose*/ 
     private Map<String, Vitals> elemDetails = new HashMap<>(); 

     public Map<String, Vitals> getElemDetails() { 
      return elemDetails; 
     } 

     public void setElemDetails(Map<String, Vitals> elemDetails) { 
      this.elemDetails = elemDetails; 
     } 
    } 

Qualsiasi suggerimento su come analizzare in questo caso!

+0

Ciao! Hai trovato una soluzione? Ho avuto lo stesso problema. – GensaGames

+0

@GenkaKasyan Controlla la risposta accettata qui sotto. – CoDe

+0

@Shubh Hai, sto avendo lo stesso problema, non so come aggiungere la classe Pojo per la chiave dinamica, puoi dire cosa hai usato nella classe di vitali? – MathaN

risposta

29

La classe resultInside sta aggiungendo un livello oggetto aggiuntivo che non esiste nel JSON. Prova a spostare la mappa nel campo results della classe .

public class Data { 
    @SerializedName("results") 
    @Expose 
    private Map<String, Vitals> result; 

    //.... 
} 
+1

genio :) Grazie. – CoDe

+0

In retrofit se si desidera analizzare JSON con chiavi dinamiche (con nomi dinamici) è necessario utilizzare HashMap di sicuro. Quindi questa risposta è quella giusta +1 da me. Assicurati di mettere HashMap a livello di oggetto con nome statico (non nome dinamico) – Sniper

+0

Grazie mille. Hai salvato i miei tempi :) –

1

Un modo migliore per fare questo, sarebbe:

---------------------- 

public class Report { 
     @SerializedName("data") 
     @Expose 
     private Data data; 

---------------------- 

public class Data { 


    public HashMap<String, DataValues> dataValues; 


    public Data() { 
     this.dataVaues = new HashMap<>(); 
    } 
} 

----------------------------- 

quindi, creare una classe Parser come questo:

public class DataParser implements JsonDeserializer<Data> { 


    @Override 
    public Data deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 

     Data result = new Data(); 


     try { 
      final HashMap<String, DataValues> map = readServiceUrlMap(json.getAsJsonObject()); 

      if(map != null) { 
       result.dataValues = map; 
      } 

     }catch (JsonSyntaxException ex){ 
      return null; 
     } 

     return result; 
    } 


    private HashMap<String, DataValues> readServiceUrlMap(final JsonObject jsonObject) throws JsonSyntaxException { 

     if(jsonObject == null) { 
      return null; 
     } 
     Gson gson = new Gson(); 

     HashMap<String, DataValues> products = new HashMap<>(); 

     for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { 

      String key = entry.getKey(); 
      DataValues value = gson.fromJson(entry.getValue(), DataValues.class); 
      products.put(key, value); 
     } 
     return products; 
    } 


---------------------------------------------- 

dopo che, digitare questo nella tua classe ApiClient

public class ApiClient { 


    private static Retrofit retrofit = null; 

    public static Retrofit getClient(String baseUrl) { 

     if(retrofit == null) { 

      GsonBuilder gsonBuilder = new GsonBuilder(); 
      gsonBuilder.registerTypeAdapter(Data.class, new DataParser()); 

      retrofit = new Retrofit.Builder() 
        .baseUrl(baseUrl) 
        .addConverterFactory(GsonConverterFactory.create(gsonBuilder.create())) 
        .build(); 

Spero che questo aiuti alcuni uno