public class PropertyBasedInterfaceMarshal implements
JsonSerializer<Object>, JsonDeserializer<Object> {
private static final String CLASS_META_KEY = "CLASS_META_KEY";
@Override
public Object deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext)
throws JsonParseException {
JsonObject jsonObj = jsonElement.getAsJsonObject();
String className = jsonObj.get(CLASS_META_KEY).getAsString();
try {
Class<?> clz = Class.forName(className);
return jsonDeserializationContext.deserialize(jsonElement, clz);
} catch (ClassNotFoundException e) {
throw new JsonParseException(e);
}
}
@Override
public JsonElement serialize(Object object, Type type,
JsonSerializationContext jsonSerializationContext) {
JsonElement jsonEle = jsonSerializationContext.serialize(object, object.getClass());
jsonEle.getAsJsonObject().addProperty(CLASS_META_KEY,
object.getClass().getCanonicalName());
return jsonEle;
}
}
然后,您可以为所有接口注册此适配器,如下所示
Gson gson = new GsonBuilder()
.registerTypeAdapter(IInterfaceOne.class,
new PropertyBasedInterfaceMarshal())
.registerTypeAdapter(IInterfaceTwo.class,
new PropertyBasedInterfaceMarshal()).create();
public class PropertyMarshallerAbstractTask implements JsonSerializer<Object>, JsonDeserializer<Object> {
private static final String CLASS_TYPE = "CLASS_TYPE";
@Override
public Object deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jsonObj = jsonElement.getAsJsonObject();
String className = jsonObj.get(CLASS_TYPE).getAsString();
try {
Class<?> clz = Class.forName(className);
return jsonDeserializationContext.deserialize(jsonElement, clz);
} catch (ClassNotFoundException e) {
throw new JsonParseException(e);
}
}
@Override
public JsonElement serialize(Object object, Type type, JsonSerializationContext jsonSerializationContext) {
Gson gson = new Gson(); //without this line it will not work
gson.toJson(object, object.getClass()); //and this one
JsonElement jsonElement = gson.toJsonTree(object); //it needs to replace to another method...toJsonTree
jsonElement.getAsJsonObject().addProperty(CLASS_TYPE, object.getClass().getCanonicalName());
return jsonElement;
}
}
然后我用它:
Gson gson = new GsonBuilder()
.registerTypeAdapter(AbstractTask.class, new PropertyMarshallerOfAbstractTask())
.create();
5条答案
按热度按时间wfsdck301#
我建议为
Node
添加一个定制的JsonDeserializer:您将能够访问表示反序列化程序方法中的节点的
JsonElement
,将其转换为JsonObject
,并检索指定该类型的字段。然后,您可以基于此创建Node
的正确类型的示例。lf3rwulv2#
您将需要注册JSONSerializer和JSONDeserializer。您也可以使用以下方式为所有接口实现通用适配器:
下面是我自己使用过的实现,运行良好。
然后,您可以为所有接口注册此适配器,如下所示
lrpiutwd3#
就我所知,这不适用于非集合类型,或者更具体地说,不适用于具体类型用于序列化,而接口类型用于反序列化的情况。也就是说,如果您有一个实现接口的简单类,并且您序列化了具体类,然后指定要反序列化的接口,那么您将最终处于不可恢复的情况。
在上面的示例中,类型适配器是针对接口注册的,但是当您使用具体类进行序列化时,它将不会被使用,这意味着将永远不会设置CLASS_ meta_KEY数据。
如果您将适配器指定为层次适配器(从而告诉gson将其用于层次结构中的所有类型),那么您将陷入无限循环,因为序列化程序将一直调用它自己。
有人知道如何从接口的具体实现进行序列化,然后只使用接口和InstanceCreator进行反序列化吗?
默认情况下,gson似乎会创建具体的示例,但不会设置它的字段。
问题记录在此处:
http://code.google.com/p/google-gson/issues/detail?id=411&q=interface
ego6inou4#
我想更正一下上面的一点
然后我用它:
然后,我可以将List(我在其中保存了一些非抽象类,它们继承自Abstract Task)解析为Json;
它的作用方向相反
fxnxkyjh5#
你必须使用来自Google Gson的
TypeToken
类。你当然需要有一个泛型类T来使它工作(foo,fooType)的一个示例;