Gson多态序列化

2023-11-25

使用 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 实例not安装处理程序,并通过它运行您的实例。

作为最终运行,您可以序列化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();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Gson多态序列化 的相关文章

随机推荐