2017-05-08 21 views
0

我有以下JSON:如何將JSON數據自定義類型與地圖<整數,對象>

{ 
    "custom": { 
     "1": { 
      "v": "3.0" 
     }, 
     "2": { 
      "NAME": "YYYYYYY", 
      "VALUE": "200" 
     }, 
     "3": { 
      "NAME": "YYYYYYY", 
      "VALUE": "200" 
     }, 
     "4": { 
      "NAME": "YYYYYYY", 
      "VALUE": "200" 
     }, 

     "7": { 
      "NAME": "XXXXXX", 
      "VALUE": "100" 
     }, 

     "26": { 
      "NAME": "YYYYYYY", 
      "VALUE": "200" 
     }, 
     "27": { 
      "NAME": "YYYYYYY", 
      "VALUE": "200" 
     }, 
     "28": { 
      "NAME": "YYYYYYY", 
      "VALUE": "200" 
     }, 
     "29": { 
      "NAME": "YYYYYYY", 
      "VALUE": "200" 
     } 
     } 
} 

我需要解析這個上面JSON和將數據存儲到HashMap<Integer,Object>。例如:

map.put(1,"3.0"); 
map.put(2, "abc"); 

當我試圖創建POJO在線翻譯工具生成說相當於我不希望創建50個POJO類的整數值計數50班。

請幫助。

+0

重構JSON如何?將其中的每個自定義元素的ID作爲一個屬性與NAME/VALUE一起使用,並將所有自定義元素都設置爲「自定義」下的數組,或者更好,而且是根數組下的數組?我認爲這個結構將更容易處理。 – jaolstad

+0

@jaolstad謝謝。實際上,我們的目標是獲取詳細信息。如果我按照你的要求移動,並且需要獲取與第27個ID相關的數據。那麼這將是一個問題,迭代將會更多。 –

回答

1

試試這個

JSONObject jsonObject = null; 
     try { 
      jsonObject = new JSONObject(jsonString); 

      jsonObject = jsonObject.getJSONObject("custom"); 
      Iterator<String> iter = jsonObject.keys(); 
      while (iter.hasNext()){ 
       String key = iter.next(); 
       JSONObject jsonObject1 = jsonObject.getJSONObject(key); 
       ModelClass model = new ModelClass(); 
       if(jsonObject1.has("name")) 
       model.setName(jsonObject1.getString("name")); 
       if(jsonObject1.has("value")) 
       model.setValue(jsonObject1.getString("value")); 
       map.put(Integer.parseInt(key),model); 

      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
+0

我想你應該首先檢查對象是否有名字,值,他發佈的第一個對象中缺少這些屬性。 –

+0

是的,請檢查我的最新答案 –

0

你爲了使動態考慮簡單Map<K,V>?例如,你映射可能是這樣的:

final class Response { 

    @JsonAdapter(SpecialMapTypeAdapterFactory.class) 
    final Map<Integer, Object> custom = null; 

} 

注意在回家的路上了custom字段聲明,尤其是它與註解。前者使你的映射完全動態擺脫無數無用的映射;後者定義了一個特殊類型的適配器+工廠將負責反序列化戰略:

以下類型的適配器工廠是完全動態的,但它是使其成爲工作的好報酬。我假設你只有對(由兩場映射支持)和字符串(由單字段映射支持,其中值在解序列化期間應該「展開」並且在序列化期間應該「回捲」)

final class SpecialMapTypeAdapterFactory 
     implements TypeAdapterFactory { 

    // This is a holder for "wrapped" strings 
    private static final class Single { 

     @SuppressWarnings("unused") 
     final String v; 

     private Single(final String v) { 
      this.v = v; 
     } 

    } 

    private SpecialMapTypeAdapterFactory() { 
    } 

    @Override 
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) { 
     // Returning the custom type adapter that's now aware of the current Gson instance type adapters 
     // (no need to lookup for a type adapter using gson.fromJson over and over) 
     @SuppressWarnings("unchecked") 
     final TypeAdapter<T> typeAdapter = (TypeAdapter<T>) new SpecialMapTypeAdapter(
       gson.getAdapter(JsonElement.class), 
       gson.getAdapter(Single.class), 
       gson.getAdapter(Pair.class) 
     ); 
     return typeAdapter.nullSafe(); 
    } 

    private static final class SpecialMapTypeAdapter 
      extends TypeAdapter<Map<Integer, Object>> { 

     private final TypeAdapter<JsonElement> jsonElementTypeAdapter; 
     private final TypeAdapter<Single> singleTypeAdapter; 
     private final TypeAdapter<Pair> entryTypeAdapter; 

     private SpecialMapTypeAdapter(final TypeAdapter<JsonElement> jsonElementTypeAdapter, final TypeAdapter<Single> singleTypeAdapter, 
       final TypeAdapter<Pair> entryTypeAdapter) { 
      this.jsonElementTypeAdapter = jsonElementTypeAdapter; 
      this.singleTypeAdapter = singleTypeAdapter; 
      this.entryTypeAdapter = entryTypeAdapter; 
     } 

     // write will work too 
     @Override 
     @SuppressWarnings("resource") 
     public void write(final JsonWriter out, final Map<Integer, Object> map) 
       throws IOException { 
      out.beginObject(); 
      for (final Entry<Integer, Object> e : map.entrySet()) { 
       out.name(String.valueOf(e.getKey())); 
       final Object value = e.getValue(); 
       if (value == null) { 
        out.nullValue(); 
       } else if (value instanceof String) { 
        singleTypeAdapter.write(out, new Single((String) value)); 
       } else if (value instanceof Pair) { 
        entryTypeAdapter.write(out, (Pair) value); 
       } else { 
        throw new IllegalArgumentException("Cannot write " + value); 
       } 
      } 
      out.endObject(); 
     } 

     @Override 
     public Map<Integer, Object> read(final JsonReader in) 
       throws IOException { 
      final Map<Integer, Object> map = new LinkedHashMap<>(); 
      in.beginObject(); 
      while (in.hasNext()) { 
       final int key = parseInt(in.nextName()); 
       final Object value = parseValue((JsonObject) jsonElementTypeAdapter.read(in)); 
       map.put(key, value); 
      } 
      in.endObject(); 
      return map; 
     } 

     // This method attempts to analyze weakly the content of the given JsonObject respecting its properties 
     // Thus either a String is returned or a Pair 
     private Object parseValue(final JsonObject jsonObject) 
       throws MalformedJsonException { 
      if (jsonObject.has("v")) { 
       return singleTypeAdapter.fromJsonTree(jsonObject).v; 
      } 
      if (jsonObject.has("NAME") && jsonObject.has("VALUE")) { 
       return entryTypeAdapter.fromJsonTree(jsonObject); 
      } 
      throw new MalformedJsonException("Cannot parse " + jsonObject); 
     } 

    } 

} 
final class Pair { 

    @SerializedName("NAME") 
    final String name = null; 

    @SerializedName("VALUE") 
    final String value = null; 

    @Override 
    public String toString() { 
     return name + "=>" + value; 
    } 

} 

全部放在一起:

private static final Gson gson = new Gson(); 

public static void main(final String... args) 
     throws IOException { 
    try (final JsonReader jsonReader = getPackageResourceJsonReader(Q43846710.class, "dynamic.json")) { 
     final Response response = gson.fromJson(jsonReader, Response.class); 
     for (final Map.Entry<Integer, Object> e : response.custom.entrySet()) { 
      final Integer key = e.getKey(); 
      final Object value = e.getValue(); 
      System.out.println(key + " is " + value.getClass().getSimpleName() + ": " + value); 
     } 
     System.out.println(gson.toJson(response)); 
    } 
} 

輸出:

1是字符串:3.0
2是對:YYYYYYY = 3是對:YYYYYYY = 4是對:YYYYYYY = 7是對:XXXXXX = 26是對:YYYYYYY = 27是對:YYYYYYY = 28是對:YYYYYYY = 29是對:YYYYYYY = { 「自定義」:{ 「1」:{ 「v」: 「3.0」} , 「2」:{ 「NAME」: 「YYYYYYY」, 「VALUE」: 「200」},「3 「:{」 NAME 「:」 YYYYYYY」, 「VALUE」: 「200」}, 「4」:{ 「NAME」: 「YYYYYYY」, 「VALUE」: 「200」}, 「7」:{ 「NAME」 : 「XXXXXX」, 「VALUE」: 「100」}, 「26」:{ 「NAME」: 「YYYYYYY」, 「VALUE」: 「200」}, 「27」:{ 「NAME」: 「YYYYYYY」,」 VALUE 「:」 200 「},」 28 「:{」 NAME 「:」 YYYYYYY」, 「VALUE」: 「200」}, 「29」:{ 「NAME」: 「YYYYYYY」, 「VALUE」: 「200」 }}}

只是不相信自動映射生成器,因爲他們不能總是工作,由於幾個原因。

相關問題