kotlinx.serialization.cbor.CborDecodingException:映射的预期开始,但找到



我试图将 Kotlin 的序列化包之一与以下自定义示例类一起使用。我将通过添加真实类的List来扩展与实际用例匹配的类(该类也需要序列化(,但现在问题仅在于反序列化。 我已经设法使序列化工作(在第二段代码中,既有要序列化的对象,也有生成的String(,并且似乎反序列化过程需要以相同的方式完成(即,通过使用NullableSerializer的实例((事实上,我现在还没有找到一种简单正确的方法来反序列化编码对象。 这是课程,简单但想要复杂。

@Serializable(with = EhEH.Companion::class)
data class EhEH(
val i: Int
, val txt: String
//, val list: Array<String> // next feature, also with complex data, not only "simple" Strings
) {
@Serializer(forClass = EhEH::class)
companion object : KSerializer<EhEH> {
public var deserialEhEH: DeserializationStrategy<EhEH> = EhEH

override val descriptor: SerialDescriptor =
SerialDescriptor("EhEHSerializer", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, obj: EhEH) =
encoder.encodeString(obj::class.qualifiedName!!)
override fun deserialize(decoder: Decoder): EhEH {
val dec = decoder.beginStructure(descriptor)
var txt: String? = null
var x: Int? = null
var i = -1
var notFinished = true
do {
i = dec.decodeElementIndex(descriptor)
when (i) {
CompositeDecoder.READ_DONE -> notFinished = false
0 -> x = dec.decodeStringElement(descriptor, i).toIntOrNull()
1 -> txt = dec.decodeStringElement(descriptor, i)
else -> throw SerializationException("Unknown index $i")
}
} while (notFinished)
dec.endStructure(descriptor)
return EhEH(
x ?: throw MissingFieldException("x"),
txt ?: throw MissingFieldException("txt")
)
}
}
override fun toString(): String {
return "EhEH(i=$i, s='$txt')"
}
}

手动测试功能(其值只是打印(是:

@InternalSerializationApi
fun testCborString(): String {
var e: EhEH = EhEH(
7,
"poreccio"
//, listOf("just", "another", "vacuum", "test")
)
return Cbor.dumps(
NullableSerializer(
EhEH.Companion
), e
) + " <-> " + (
{
(Cbor.load(
NullableSerializer(
EhEH.Companion
),
Cbor.dump(
NullableSerializer(EhEH.Companion), e
)
//the dumped value should be "781d62632e7472797669756d2e6170692e726573706f6e7365732e45684548"
)
as EhEH).toString()
} as () -> String)()
}

当我尝试运行它时,异常存在于Cbor.load调用中,并且是:

kotlinx.serialization.cbor.CborDecodingException: Expected start of map, but found 78

我是整个互联网中唯一一个有这个问题的人吗?

我自己找到了一种方法,错误基本上有两个:

  1. override val descriptor: SerialDescriptor变量被设置为识别String但这显然不是想要的变量,因为它是一个类:

    // val stringArraySerializer= ArraySerializer(String.serializer())
    SerialDescriptor("EhEHSerializer", StructureKind.CLASS) {
    element<Int>("i")
    element<String>("txt")
    // element<Array<String>>("list") // kept here for future references for Array of primitive stuffs
    // element("arrComplexClass", AComplexClassTaggedSerializable.descriptor) // in case of Array of complex objects, a tag @Serializable and a companion object implementing Kserializable<AComplexClassTaggedSerializable> is needed
    }
    
  2. 类似地,实现方法override fun serialize(encoder: Encoder, obj: EhEH)以生成String(特别是保存类名称的字符串(。所需的实现是:

    override fun serialize(encoder: Encoder, obj: EhEH){
    var ce = encoder.beginStructure(
    descriptor,
    Int.serializer(),
    String.serializer(),
    //stringArraySerializer, // kept here for future references for
    // serializerArray_AComplexClassTaggedSerializable
    )
    ce.encodeIntElement(descriptor, 0, obj.i)
    ce.encodeStringElement(descriptor, 1, obj.txt)
    /*ce.encodeSerializableElement(
    descriptor, 2,
    stringArraySerializer, obj.arrOfStrings
    )*/
    /*ce.encodeSerializableElement(
    descriptor, 3,
    serializerArray_AComplexClassTaggedSerializable,
    obj.arrComplexClass
    )*/
    ce.endStructure(descriptor)
    }
    

    此外,其他基本注意事项:

  3. 需要将复杂对象包装在NullableSerializer上,也Array的情况下:

    val serializerArray_AComplexClassTaggedSerializable =
    ArraySerializer<AComplexClassTaggedSerializable, AComplexClassTaggedSerializable?>(
    NullableSerializer(
    AComplexClassTaggedSerializable.Companion
    )
    ) // it's a variable used on the code above
    
  4. 序列化反序列化(即:分别为Cbor.dumpCbor.load(时,第一个参数需要NullableSerializer

    var nse = NullableSerializer(AComplexClassTaggedSerializable)
    println( Cbor.dump(nse, someInstanceOfThatComplexClass ).toString())
    //and....
    var o = (Cbor.load(nse, "...here go something..") as EhEH
    // use "o"
    

最新更新