使用Gson自定义反序列化成地图 [英] Custom deserialization into a Map using Gson

查看:146
本文介绍了使用Gson自定义反序列化成地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下JSON:

{
    "abc": {
        "linkedTo": "count",
        // possibly more data...
    },
    "plmtq": {
        "linkedTo": "title",
        "decode": "true",
        // possibly more data...
    }
}

我需要将这个JSON加载到一个 Map< String,Holder> 中,并带有abcplmtq

以下是我的持有人类:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆