我正在尝试反序列化这种类型的json
{
"_embedded": {
"list": [
{
"000000": {
"date": "2015-07-10 14:29:15"
}
},
{
"111111": {
"date": "2015-07-11 14:29:15"
}
}
]
}
}
我设法在嵌入对象中获取列表,但列表条目为空。
My Embedded类看起来像这样
public class Embedded {
@SerializedName("list")
private List<ListEntry> entries;
}
但我无法反序列化列表的条目。我认为问题在于地图嵌套在没有名称的对象中。
public class ListEntry {
private Map<String, ListEntryInfo> map;
}
答案 0 :(得分:2)
最初的问题是您声明层次结构的方式。 ListEntry
是Map<String, ListEntryInfo>
,但没有Map<String, ListEntryInfo>
。为了使它工作,你有三个选择:
将ListEntry
类声明为class ListEntry extends HashMap<String, ListEntryInfo> {}
,这在我看来是个坏主意
摆脱ListEntry
课程并声明entries
列表@SerializedName("list") List<Map<String, ListEntryInfo>> entries;
<小时/> 如前所述,您可以做的是编写自定义反序列化器,以便您有更多类型的条目列表。
由于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;
}
}
现在,您需要编写反序列化器以在反序列化JSON时创建新的ListEntry
实例:
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
,依此类推),我们获取密钥并使用{{反序列化相应的ListEntryInfo
1}}实例。
最后一步是在解析器中注册它:
JsonDeserializationContext
在你的例子上运行它,你应该得到:
Gson gson = new GsonBuilder().registerTypeAdapter(ListEntry.class, new ListEntryDeserializer()).create();