【问题标题】:Gson and abstract superclasses: deserialization issueGson 和抽象超类:反序列化问题
【发布时间】:2013-06-01 12:02:38
【问题描述】:

假设有一个抽象类,比如A,和两个非抽象子类,比如A1A2。我想通过使用 GSON library 将它们从 json 格式“反序列化”。

例如我得到了一个 A 对象数组。

int n = ...;
A[] list = new A[n];
A[0] = new A1(....);
A[1] = new A2(....);
...

其中有人转换为JSON字符串如下:

String json = (new Gson()).toJson(list);

最后,如果我尝试反序列化如下

A[] deserializedList =  (new Gson()).fromJson(json, A[].class);

然后我得到一个错误,因为 GSON 默认反序列化器找到了一个抽象类(即A)并且它无法猜测子类类型。

我该如何解决这个问题?

PS:我阅读了自定义反序列化程序,但我不明白在这种情况下如何使用它们。

【问题讨论】:

  • @Axxiss 哦!好的,所以我不能使用简单的列表,我必须将对象类类型保存在序列化字符串中。嗯!如果 GSON 的人能添加一个方法来启用类类型属性的自动保存就更好了!
  • 好吧,请发布与此问题相关的答案,以便我接受!
  • 好吧,目前我没有时间给出更好的答案。可能您应该以链接为起点自己创建一个答案;)
  • @Axxiss 当然,我会这样做。我的目的是接受你的回答,以便给你加分!

标签: java gson


【解决方案1】:

Axxiss 链接之后,这里有答案。必须提供自定义序列化器/反序列化器。

public class AClassAdapter  implements JsonSerializer<A>, JsonDeserializer<A> {
  @Override
  public JsonElement serialize(A src, Type typeOfSrc, JsonSerializationContext context) {
      JsonObject result = new JsonObject();
      result.add("type", new JsonPrimitive(src.getClass().getSimpleName()));
      result.add("properties", context.serialize(src, src.getClass())); 
      return result;
  }


  @Override
  public A deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
        throws JsonParseException {
    JsonObject jsonObject = json.getAsJsonObject();
    String type = jsonObject.get("type").getAsString();
    JsonElement element = jsonObject.get("properties");

    try {            
        String fullName = typeOfT.getTypeName();
        String packageText = fullName.substring(0, fullName.lastIndexOf(".") + 1);

        return context.deserialize(element, Class.forName(packageText + type));
    } catch (ClassNotFoundException cnfe) {
        throw new JsonParseException("Unknown element type: " + type, cnfe);
    }
  }
}

然后序列化如下:

GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(A.class, new ATypeAdapter());
String json = gson.create().toJson(list);

给定json字符串,反序列化为:

GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(A.class, new ATypeAdapter());

return gson.create().fromJson(json, A[].class);

【讨论】:

  • 非常适合客户。不错。
猜你喜欢
  • 2011-04-07
  • 1970-01-01
  • 2015-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-03
相关资源
最近更新 更多