2015-07-19 104 views
1

我試圖反序列化這種類型的JSONGSON - 反序列化JSON嵌套地圖

{ 
    "_embedded": { 
    "list": [ 
     { 
     "000000": { 
      "date": "2015-07-10 14:29:15" 
     } 
     }, 
     { 
     "111111": { 
      "date": "2015-07-11 14:29:15" 
     } 
     } 
    ] 
    } 
} 

我設法讓我的嵌入對象的內部清單,但清單條目是空的。

我的嵌入式類看起來像這樣

public class Embedded { 

    @SerializedName("list") 
    private List<ListEntry> entries; 
} 

但我不能反序列化列表中的條目。我認爲問題在於地圖嵌套在沒有名稱的對象內。

public class ListEntry { 

    private Map<String, ListEntryInfo> map; 
} 
+0

我稍稍偏出你的問題的一個關鍵點。我編輯了我的答案。 –

回答

2

最初的問題是您聲明層次結構的方式。 A ListEntryMap<String, ListEntryInfo>,但沒有Map<String, ListEntryInfo>。爲了使它工作,你有三種選擇:

  • 聲明ListEntry類爲class ListEntry extends HashMap<String, ListEntryInfo> {},這是

  • 在我看來是一個壞主意擺脫ListEntry類,並宣佈這樣@SerializedName("list") List<Map<String, ListEntryInfo>> entries;entries列表

  • 使用I最初低於所描述的方法,通過實現自定義串並轉換器


如前所述,你可以做的是寫一個自定義的反序列化器,這樣你就可以得到更多類型的條目列表。

作爲ListEntry實例有映射到一個關鍵的只有一個ListEntryInfo價值,我會結構改成這樣:

class ListEntry { 
    private String key; 
    private ListEntryInfo value; 

    public ListEntry(String key, ListEntryInfo value) { 
     this.key = key; 
     this.value = value; 
    } 

    public String toString() { 
     return key + " -> " + value; 
    } 
} 

class ListEntryInfo { 
    //assuming we store the date as a String for simplicity 
    @SerializedName("date") 
    private String date; 

    public ListEntryInfo(String date) { 
     this.date = date; 
    } 

    public String toString() { 
     return date; 
    } 
} 

現在,你需要寫一個解串器,當你反序列化創建一個新的ListEntry實例JSON:

class ListEntryDeserializer implements JsonDeserializer<ListEntry> { 
    @Override 
    public ListEntry deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
     Iterator<Map.Entry<String, JsonElement>> ite = json.getAsJsonObject().entrySet().iterator(); 
     //you may want to throw a custom exception or return an "empty" instance there 
     Map.Entry<String, JsonElement> entry = ite.next(); 
     return new ListEntry(entry.getKey(), context.deserialize(entry.getValue(), ListEntryInfo.class)); 
    } 
} 

這解串器將讀取每個ListEntry。由於它由單個鍵值對組成(在第一種情況下,字符串「000000」映射到一個ListEntryInfo等),我們獲取密鑰並將對應的ListEntryInfoJsonDeserializationContext實例反序列化。

的最後一步,是將語法分析程序中進行註冊:

Gson gson = new GsonBuilder().registerTypeAdapter(ListEntry.class, new ListEntryDeserializer()).create(); 

運行它在你的榜樣,你應該得到:

[000000 -> 2015-07-10 14:29:15, 111111 -> 2015-07-11 14:29:15] 
+0

謝謝你的完整答案。我最終使用了第二種解決方案。我以前設法用自定義的反序列化器解決了這個問題,但是我使用了改進,這意味着我必須自己解析網絡響應 – andrei