当前位置: 首页 > 面试题库 >

Gson多态序列化

胡景焕
2023-03-14
问题内容

使用Gson 2.2.2,我正在尝试序列化POJO(行为)的数组列表。

我有一个适配器,几乎是我在网上看到的一个副本:

public class BehaviorAdapter implements JsonSerializer<Behavior> {

    private static final String CLASSNAME = "CLASSNAME";
    private static final String INSTANCE = "INSTANCE";

    @Override
    public JsonElement serialize(Behavior src, Type typeOfSrc,
            JsonSerializationContext context) {

        JsonObject retValue = new JsonObject();
        String className = src.getClass().getCanonicalName();
        retValue.addProperty(CLASSNAME, className);
        JsonElement elem = context.serialize(src);
        retValue.add(INSTANCE, elem);
        return retValue;
    }
}

我这样注册:

GsonBuilder builder = new GsonBuilder();        
builder.registerTypeHierarchyAdapter(Behavior.class, new BehaviorAdapter());
gson = builder.create();

然后,当我尝试序列化我的ArrayList时:

String json2 = gson.toJson(behaviors);

我出现堆栈溢出。

似乎在线上:

JsonElement elem = context.serialize(src);

它开始递归循环,一次又一次地通过我的序列化器。那么,我该如何注册它以免发生这种情况?我需要序列化列表并保持多态性。


问题答案:

看起来您发现了JsonSerializer文档警告的无限循环:

但是,永远不要在src对象本身上调用它,因为这将导致无限循环(Gson将再次调用您的回调方法)。

我想到的最简单的方法是创建一个 安装处理程序的新Gson实例,然后通过该实例运行您的实例。

最后,您可以序列化List<Behavior>代替代码:

public class BehaviorListAdapter implements JsonSerializer<List<Behavior>> {

    private static final String CLASSNAME = "CLASSNAME";
    private static final String INSTANCE = "INSTANCE";

    @Override
    public JsonElement serialize(List<Behavior> src, Type typeOfSrc,
            JsonSerializationContext context) {
        JsonArray array = new JsonArray();
        for (Behavior behavior : src) {
            JsonObject behaviorJson = new JsonObject();
            String className = behavior.getClass().getCanonicalName();
            behaviorJson.addProperty(CLASSNAME, className);
            JsonElement elem = context.serialize(behavior);
            behaviorJson.add(INSTANCE, elem);
            array.add(behaviorJson);
        }
        return array;
    }
}

GsonBuilder builder = new GsonBuilder();
// use a TypeToken to make a Type instance for a parameterized type
builder.registerTypeAdapter(
    (new TypeToken<List<Behavior>>() {}).getType(),
    new BehaviorListAdapter());
gson = builder.create();


 类似资料:
  • 我有一个接口,其中和实现。服务器会返回这样的响应- 相应的类来建模它是 中的声明它是哪种车辆。我需要反序列化的成一个对象取决于。如果是,我需要在反序列化和期间使用反序列化。 如何使用gson实现这一点? 编辑-这篇文章的不同之处在于类类型()包含在需要反序列化的中。这里不是。如果在内,我可以为编写自定义反序列化程序,检查,并进行相应的反序列化。但是我想我需要为编写一个自定义反序列化程序,在这里我创

  • 问题内容: 我正在尝试使用Gson将涉及多态的对象序列化/反序列化为JSON。 这是我的序列化代码: 结果如下: 序列化大多的作品,除了它缺少继承成员的内容(尤其是和字符串丢失)。这是我的基类: 这是我的继承类(ObixOp)的样子: 我意识到我可以为此使用适配器,但是问题是我正在序列化基类type的集合。从中继承大约25个类。我该如何优雅地进行这项工作? 问题答案: 我认为自定义序列化器/反序列

  • 我正在尝试使用Gson将一个涉及多态性的对象序列化/反序列化为JSON。 这是我的序列化代码: 结果是这样的: 序列化主要工作,除了它缺少继承成员的内容(特别是和字符串丢失)。这是我的基类: 下面是我继承的类(ObixOp)的样子: 我意识到我可以使用适配器来实现这一点,但问题是我正在序列化一个基类类型的集合。大约有25个类继承自此。我怎样才能优雅地完成这项工作?

  • 问题内容: 我如何反序列化此json: 使用Google GSON? 问题答案: 要反序列化JSON,您需要为递归接口使用自定义反序列化器。在这种类中,您需要检查JSON并确定要实例化为JSON本身的type字段的类。在这里,您有一个我为您编写的示例基本解串器。 当然,管理边界事件可以得到改善(例如,如果没有类型字段,会发生什么情况?)。 这是我的代码的结果:

  • 是否有方法序列化类的瞬态字段?文档中提到默认情况下不支持它,但是否有办法打开它? 非常感谢

  • 我正在开发一个应用程序,它使用Gson作为JSON反序列化器,需要从REST API反序列化多态JSON。在解释mi问题之前,请注意,我已经用Gson研究了多态反序列化,并在几个案例中成功地实现了它。这是我面临的一个具体问题。在问这个问题之前,我也读过这篇很棒的帖子和关于堆栈溢出的讨论。顺便说一下,我正在使用RuntimeTypeAdapterFactory来反序列化多态对象。 我遇到的问题是,G