我最终实现了一个自定义转换器和一个工厂,以正确地将其插入 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() }
}
为了确保这个转换器只应用于实际对象,我使用工厂注册它,它告诉 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()
使用链式转换器功能,代码可能会更好,但我还没有时间检查它。