我对Gson和Json很新。我有简单的事件,我希望在Gson的帮助下通过Json序列化。
注意:Kotlin中的代码。
public abstract class Event() {
}
public class Move : Event() {
var from: Point? = null
var to: Point? = null
}
public class Fire : Event() {
var damage: Int = 0
var area: ArrayList<Point> = ArrayList(0)
}
public class Build : Event() {
var to: Point? = null
var type: String = ""
var owner: String = ""
}
我通过这种方式坚持这些:
val list: ArrayList<Event>() = ArrayList()
list.add(move)
list.add(fire)
val str = gson.toJson(events)
并且没有说服力:
val type = object : TypeToken<ArrayList<Event>>(){}.getType()
val eventStr = obj.getString("events")
val events: ArrayList<Event> = gson.fromJson(eventStr, type)
我已经尝试过创建一个序列化器&amp;用于Event-class的反序列化器,并通过registerTypeAdapter注册它,我也尝试过RuntimeTypeAdapterFactory,但是它们都不会保留解析正确类型所需的信息。
例如,RuntimeTypeAdapterFactory说: “无法反序列化Event,因为它没有定义名为type
的字段编辑:这是“适配器”的代码,它很好地改编自另一个StackOverflow帖子:
public class Adapter :
JsonSerializer<Event>,
JsonDeserializer<Event> {
final val CLASSNAME = "CLASSNAME"
final val INSTANCE = "INSTANCE"
override fun serialize(src: Event?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement? {
val obj = JsonObject()
val className = (src as Event).javaClass.getCanonicalName()
obj.addProperty(CLASSNAME, className)
val elem = context!!.serialize(src)
obj.add(INSTANCE, elem)
return obj
}
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Event? {
val jsonObject = json!!.getAsJsonObject()
val prim = jsonObject.get(CLASSNAME)
val className = prim.getAsString()
val klass = Class.forName(className)
return context!!.deserialize(jsonObject.get(INSTANCE), klass)
}
}
此代码在行上的NullPointerException失败:
val className = prim.getAsString()
答案 0 :(得分:1)
你不能这样做。
您所指的示例并不针对您的案例。它只适用于一种情况:如果注册基类型(不是类型层次结构)并使用gson.toJson(obj, javaClass<Event>())
序列化。除了为事件容器对象编写自定义序列化程序之外,它永远不会用于数组
通常你需要另一种方法:使用TypeAdapterFactory和委托适配器:GSON: serialize/deserialize object of class, that have registered type hierarchy adapter, using ReflectiveTypeAdapterFactory.Adapter和https://code.google.com/p/google-gson/issues/detail?id=43#c15
我认为这种方法过于复杂,所以如果您的类型很少,最简单的解决方案是手动,通过自定义序列化器逐个字段序列化这些类型,并忘记尝试委托默认