使用Gson自定义反序列化到Map中

时间:2016-12-07 23:37:55

标签: java json parsing dictionary gson

我有以下JSON:

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

我需要将此JSON加载到Map<String, Holder>,其中包含密钥"abc""plmtq"
以下是我的Holder课程:

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>
有没有办法做到这一点?

下面是执行此操作的代码,但它看起来过于复杂,必须有一种更简单的方法来执行此操作...

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;
}

1 个答案:

答案 0 :(得分:2)

如果确实需要按原样保留Holder类,我能想到的唯一选择是为Holder类创建自定义反序列化器。

通过这样做,每当你告诉Gson将一些JSON解析为Holder对象时,它就会使用你的反序列化器,而不是正常的方式&#39;正常的方式&#39; (即,将JSON键映射到对象属性)。

这样的事情:

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 HolderDeserializer());
Gson gson = gsonBuilder.create();

最后,你像这样解析你的JSON:

Type responseType = new TypeToken<Map<String, Holder>>() {}.getType();
Map<String, Holder> response = gson.fromJson(jsonLine, responseType);

您可能希望查看Gson的自定义(de)serializationthis other answer的文档以获取更多信息...

注意:此评论已经过编辑,以便在评论/聊天中讨论后更清晰。