1

我正在尝试使用依赖项为Color类制作自定义序列化程序。kmongo-coroutine-serialization这样做时我遇到了一个例外:

Exception in thread "main" org.bson.BsonInvalidOperationException: readEndDocument can only be called when State is END_OF_DOCUMENT, not when State is VALUE.


我将其作为 json 测试的文档

{
    "_id": {
        "$oid": "61fe4f745064370bd1473c41"
    },
    "id": 1,
    "color": "#9ac0db"
}

ExampleDocument班级:

@Serializable
data class ExampleDocument(
    @Serializable(with = ColorHexSerializer::class) val color: Color
)

ColorHexSerializer对象: 出于测试目的,我总是返回蓝色

internal object ColorHexSerializer : KSerializer<Color> {
    override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("color_hex", PrimitiveKind.STRING)

    override fun serialize(encoder: Encoder, value: Color) {
        val hex = String.format("#%06x", value.rgb and 0xFFFFFF)
        encoder.encodeString(hex)
    }

    override fun deserialize(decoder: Decoder): Color {
        return Color.BLUE
    }
}

主功能:

suspend fun main() {
    registerSerializer(ColorHexSerializer)
    val document =
        KMongo.createClient("connectionString")
            .getDatabase("database")
            .getCollectionOfName<ExampleDocument>("testing")
            .find(eq("id", 1))
            .awaitFirst()
}


将 bson 文档转换为 json 并对其进行反序列化,然后使用 kotlinxserialization 就可以了。有人能帮我一下吗?

提前致谢

4

1 回答 1

0

从以下文档Decoder

反序列化过程需要解码器并向他询问由反序列化器串行形式定义的原始元素序列,而解码器知道如何从实际格式表示中检索这些原始元素。

更具体地说,序列化要求解码器提供“给我一个 int,给我一个 double,给我一个字符串列表并给我另一个嵌套 int 对象”的序列

您需要按顺序指定从解码器读取的所有值。所有写入的值也需要被读取。似乎(至少在您的情况下)kotlinx.serialization忽略了要读取的剩余内容的错误,而 kmongo 引发了异常。

通过默认返回蓝色,您跳过了读取字符串的步骤,从而导致字符串被留下。

由于还剩下一个字符串,因此当您尝试完成对文档的读取时,对象的状态是VALUE(还有一个值要读取)。

override fun deserialize(decoder: Decoder): Color {
    decoder.decodeString()
    return Color.BLUE
}
于 2022-02-09T15:54:13.473 回答