2015-07-19 160 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