我有一些有关数据库对象的元数据,我想通过网络发送,包括某些行的ID。由于kotlin开箱即用地提供了Json序列化,我非常愿意使用它。 现在的问题是ID的类型可以是任何类型,实际上目前仅是Int,Long或UUID。现在,我有了描述密钥类型的元数据,因此在两面都可以提供一个(反序列化器)。 所以我有:
@file:ContextualSerialization(MetaData::class, Any::class)
package com.example
sealed class MetaProperty(val name:String, val type: KClass<*>) {
abstract fun serializer() : KSerializer<Any>
}
class IntProperty(name:String) : MetaProperty(name, Int::class) {
override fun serializer(): KSerializer<Any> = IntSerializer as KSerializer<Any>
}
class MetaData(val type:String, val idType:MetaProperty)
@Serializable
data class DBRelation(
val from:MetaData,
val fromId: Any,
val to:MetaData,
val toId:Any)
现在,我只想序列化Relation,实际上,在我的情况下,仅关系的另一端(不需要from),我只是包含了它以使序列化成为可能。 我写了一个自定义序列化程序的幼稚实现:
@Serializer(forClass = DBRelation::class)
object RelationToSerializer : KSerializer<DBRelation> {
lateinit var meta : (String) -> MetaData
override val descriptor: SerialDescriptor = object : SerialClassDescImpl("relation") {
init {
addElement("from")
addElement("to")
addElement("fromId")
addElement("toId")
}
}
@ImplicitReflectionSerializer
override fun serialize(encoder: Encoder, obj: DBRelation) {
val comp = encoder.beginStructure(descriptor)
comp.encodeStringElement(descriptor, 0, obj.from.type)
comp.encodeSerializableElement(descriptor, 2, obj.from.idType.type.serializer() as KSerializer<Any>, obj.fromId)
}
override fun deserialize(decoder: Decoder): DBRelation = run {
var from : String? = null
var to : String? = null
var fromId : Any? = null
var toId : Any? = null
val dec = decoder.beginStructure(descriptor)
loop@ while (true) {
when(val idx = dec.decodeElementIndex(descriptor)) {
CompositeDecoder.READ_DONE -> break@loop
0 -> from = dec.decodeStringElement(descriptor, idx)
1 -> to = dec.decodeStringElement(descriptor, idx)
2 -> fromId = dec.decodeSerializableElement(descriptor, idx, meta(from?:throw IllegalStateException()).idType.serializer())
}
}
DBRelation(meta(from!!), fromId!!, meta(to!!), toId!!)
}
}
现在,根据字段反序列化的顺序,此实现可能会起作用,也可能不会起作用。
所以我有两个问题:
A。有人知道我的问题的另一种解决方案吗?哪个不需要我为每种可能的Key类型组合编写特殊的Relation类?
B。更好的是,有没有办法告诉串行器保留ID值,直到from
被反序列化为止?还是给我一些ID的序列化版本,以便以后可以对它进行序列化(一旦我有了from
值)就可以反序列化?