使用Gson自定义反序列化成地图 [英] Custom deserialization into a Map using Gson
问题描述
我有以下JSON:
{
"abc": {
"linkedTo": "count",
// possibly more data...
},
"plmtq": {
"linkedTo": "title",
"decode": "true",
// possibly more data...
}
}
我需要将这个JSON加载到一个 Map< String,Holder>
中,并带有abc
和plmtq
。
以下是我的持有人
类:
I need to load this JSON into a Map<String, Holder>
, with keys "abc"
and "plmtq"
.
Below is my Holder
class:
public class Holder {
private final Map<String, String> data;
public Holder(Map<String, String> data) {
this.data = data;
}
// More methods in this class...
}
JSON不符合我的类结构,但我不能更改JSON或类。
我需要的是一种自定义反序列化的方法所以我可以将JSON解析成一个 Map< String,Holder>
。
有没有办法这样做?
The JSON does not match my class structure, but I cannot change the JSON or the classes.
What I need is a way to customize the deserialization so I can parse the JSON into a Map<String, Holder>
.
Is there any way to do this?
下面是代码,但它看起来太复杂,必须有一个更简单的方法来实现...
Below is the code which does that, but it looks too complex and there must be a simpler way to do it...
private static Map<String, Holder> getMap(String jsonLine)
{
Map<String, Holder> holder = new HashMap<>();
JsonElement jelement = new JsonParser().parse(jsonLine);
JsonObject jobject = jelement.getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : jobject.entrySet())
{
Map<String, String> metadata = new HashMap<>();
JsonObject element = entry.getValue().getAsJsonObject();
for (Map.Entry<String, JsonElement> entry2 : element.entrySet())
{
metadata.put(entry2.getKey(), entry2.getValue().getAsString());
}
holder.put(entry.getKey(), new Holder(metadata));
}
return holder;
}
推荐答案
如果你真的需要保持您的持有者类,我唯一可以想到的是为您的
持有者创建一个自定义解串器
class。
If you really need to keep your Holder
class as is, the only option I can think of is to create a custom deserializer for your Holder
class.
通过这样做,每当你告诉Gson将一些JSON解析成一个 Holder
对象,它将使用您的解串器,而不是通常的方式(即将JSON键映射到对象属性)。
By doing this, whenever you tell Gson to parse some JSON into a Holder
object, it will use your deserializer, instead of doing it 'the normal way' (i.e., mapping JSON keys to object properties).
这样的东西:
private class HolderDeserializer implements JsonDeserializer<Holder> {
@Override
public Holder deserialize(JsonElement json, Type type, JsonDeserializationContext context)
throws JsonParseException {
Type mapType = new TypeToken<Map<String, String>>() {}.getType();
Map<String, String> data = context.deserialize(json, mapType);
return new Holder(data);
}
}
然后在创建 Gson
对象:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Holder.class, new HodlerDeserializer());
Gson gson = gsonBuilder.create();
最后,你解析你的JSON,如下所示:
And finally, you parse your JSON like this:
Type responseType = new TypeToken<Map<String, Holder>>() {}.getType();
Map<String, Holder> response = gson.fromJson(jsonLine, responseType);
您可能需要查看Gson的文档以进行自定义(de)serialization 和我的另一个答案获得更多信息...
You may want to look at Gson's docs for custom (de)serialization and this other answer of mine to get more info...
注意:这个答案已经编辑,以便在评论/聊天中讨论后更清晰。
这篇关于使用Gson自定义反序列化成地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!