Gson多态序列化 [英] Gson Polymorphic Serialization
问题描述
使用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屋!