KMongo 自定义序列化程序:readEndDocument 只能在 State 为 END_OF_DOCUMENT 时调用,不能在 State 为 VALUE 时调用

KMongo custom serializer: readEndDocument can only be called when State is END_OF_DOCUMENT, not when State is VALUE

我正在尝试使用 kmongo-coroutine-serialization 依赖项为 Color class 创建自定义序列化程序。 这样做时出现异常:

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 class:

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

ColorHexSerializer对象: 出于测试目的我总是return蓝色

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 就可以了。 有人可以帮我吗?

提前致谢

来自documentation of Decoder

Deserialization process takes a decoder and asks him for a sequence of primitive elements, defined by a deserializer serial form, while decoder knows how to retrieve these primitive elements from an actual format representations.

To be more specific, serialization asks a decoder for a sequence of "give me an int, give me a double, give me a list of strings and give me another object that is a nested int"

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

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

由于还有一个 String,当您尝试完成文档的读取时,对象的状态为 VALUE(还有一个值需要读取)。

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