Gson多态序列化 [英] Gson Polymorphic Serialization

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

问题描述

使用Gson 2.2.2我试图序列化POJO(行为)的数组列表。



我有一个适配器,它几乎是我的副本'在线看到:

  public class BehaviorAdapter实现了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);
返回retValue;


$ / code $ / pre
$ b $ p我注册它像这样:

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

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

 字符串json2 = gson.toJson(行为); 

我得到一个堆栈溢出。

看起来在线上:

  JsonElement elem = context.serialize(src); 

它启动一个递归循环,一次又一次地通过我的序列化程序。那么,我如何注册它,以避免这种情况发生?我需要序列化列表并维护多态。

解决方案

看起来像是发现了无限循环


然而,你不应该在src对象上调用它本身,因为这将导致无限循环(Gson将再次调用您的回调方法)。

我能想到的最简单的方法是是创建一个新的Gson实例,它不会 安装处理程序,并通过它运行实例。



作为最终运行,您可以序列化 List< Behavior> 来代替:

  public class BehaviorListAdapter实现JsonSerializer< List< Behavior>> {

private static final String CLASSNAME =CLASSNAME;
private static final String INSTANCE =INSTANCE;
$ b $ @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);
}
返回数组;
}
}

GsonBuilder builder = new GsonBuilder();
//使用TypeToken为参数化类型创建一个Type实例
builder.registerTypeAdapter(
(new TypeToken< List< Behavior>>(){}).getType(),
new BehaviorListAdapter());
gson = builder.create();


using Gson 2.2.2 I'm trying to serialize an array list of POJOs (Behaviors).

i have an adapter that's pretty much a copy of what i've seen online:

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

The i register it like this:

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

Then when i try to serialize my ArrayList:

String json2 = gson.toJson(behaviors);

I get a stack overflow.

It appears that on line:

JsonElement elem = context.serialize(src);

It starts a recursive loop, going again and again through my serializer. So How do i register it so that this won't happen? I need to serialize the list and maintain polymorphism.

解决方案

Looks like you found the infinite loop the JsonSerializer docs warn about:

However, you should never invoke it on the src object itself since that will cause an infinite loop (Gson will call your call-back method again).

The easiest way I can think of is to create a new Gson instance that does not have the handler installed, and run your instances through that.

As an end run, you could just serialize the List<Behavior> instead:

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多态序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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