Gson和抽象超类:反序列化问题 [英] Gson and abstract superclasses: deserialization issue

查看:118
本文介绍了Gson和抽象超类:反序列化问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



例如我得到 A 对象的数组。 。
A [] list = new A [n];
A [0] =新的A1(....);
A [1] =新A2(....);
...

某人转换为JSON字符串,如下所示:

 字符串json =(new Gson())。toJson(list); 

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

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

然后我得到一个错误,因为GSON默认的反序列化器找到了一个抽象类(即<$ c

如何解决这个问题?





>
)它不能猜测子类的类型。
$ b

PS:我读过关于自定义反序列化器的内容,但我不明白在这种情况下如何使用它们。

解决方案

遵循 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()));
返回结果;


$ b @Override
public反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext上下文)
抛出JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
String type = jsonObject.get(type)。getAsString();
JsonElement element = jsonObject.get(properties);

尝试{
String thepackage =my.package.name。;
return context.deserialize(element,Class.forName(thepackage + 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);


Suppose to have an abstract class, say A, and two non-abstract subclasses, say A1 and A2. I want to "deserialize" them from a json format by using the GSON library.

E.g. I get an array of A objects.

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

which someone converted to a JSON string as follows:

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

Finally, if I try to deserialize as follows

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

then I has got an error, since the GSON default deserializer finds an abstract class (i.e. A) and it is not capable of guessing the subclass type.

How can I solve this?

PS: I read about custom deserializer, but I don't understand how to use them in this case.

解决方案

Following the Axxiss link, here follows the answer. A custom serializer/deserializer must be provided.

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 thepackage = "my.package.name.";         
        return context.deserialize(element, Class.forName(thepackage + type));
    } catch (ClassNotFoundException cnfe) {
        throw new JsonParseException("Unknown element type: " + type, cnfe);
    }
  }
}

Then the serialization is done like follows:

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

and given the json string, the deserialization is:

GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(A.class, new ATypeAdapter());
        return gson.create().fromJson(json,
                A[].class);

这篇关于Gson和抽象超类:反序列化问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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