我最终实现了一个定制的转换器和一个工厂,以便将其正确地插入Genson.
它使用Genson的元数据约定将对象表示为:
{
"@class": "com.example.ViewModel.Loading"
}
转换器假设设置了useClassMetadata个标志,所以序列化只需要标记一个空对象.对于反序列化,它从元数据解析类名,加载它并获得objectInstance.
object KotlinObjectConverter : Converter<Any> {
override fun serialize(objectData: Any, writer: ObjectWriter, ctx: Context) {
with(writer) {
// just empty JSON object, class name will be automatically added as metadata
beginObject()
endObject()
}
}
override fun deserialize(reader: ObjectReader, ctx: Context): Any? =
Class.forName(reader.nextObjectMetadata().metadata("class"))
.kotlin.objectInstance
.also { reader.endObject() }
}
为了确保此转换器仅应用于实际的objects,我使用工厂注册它,该工厂告诉Genson何时使用它,何时退回到默认实现.
object KotlinConverterFactory : Factory<Converter<Any>> {
override fun create(type: Type, genson: Genson): Converter<Any>? =
if (TypeUtil.getRawClass(type).kotlin.objectInstance != null) KotlinObjectConverter
else null
}
工厂可通过builder配置Genson:
GensonBuilder()
.withConverterFactory(KotlinConverterFactory)
.useClassMetadata(true) // required to add metadata during serialization
// some other properties
.create()
使用链式转换器功能,代码可能会更好,但我还没有时间判断它.