You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Kotlinx.serialization通过WebSocket序列化Kayak类仅保留id字段问题

问题解决:Ktor WebSocket发送Kayak数据类仅序列化id字段

可能原因及解决方案

1. 枚举类未标记序列化

先检查TypeOfKayak枚举是否添加了@Serializable注解——如果枚举没有序列化能力,Kotlinx.serialization在处理整个Kayak类时可能静默失败,只输出已成功序列化的id字段。

修正示例:

@Serializable
enum class TypeOfKayak {
    Single, Double // 根据你的实际枚举值调整
}

2. WebSocket未使用正确的Json配置

HTTP接口的call.respond()会自动使用你在ContentNegotiation中配置的自定义Json实例,但WebSocket发送时如果没有显式调用这个实例,可能会使用默认的Json序列化器,而默认配置可能不兼容你的字段或注解。

确保WebSocket发送时用你定义的json对象序列化:

// 你的WebSocket处理逻辑
webSocket("/kayak-updates") {
    val kayaks = kayaksDb.getAllKayaks()
    // 必须用你自定义的json实例编码
    val serializedMessage = json.encodeToString(kayaks)
    send(serializedMessage)
}

3. Kmongo代理对象导致序列化异常

Kmongo在查询时可能返回代理对象(比如支持懒加载的实例),这类对象的字段可能无法被Kotlinx.serialization正常识别。可以尝试将数据库返回的对象转换为原始Kayak实例:

val rawKayaks = kayaksDb.getAllKayaks().map {
    Kayak(it.id, it.available, it.type, it.reservesIds)
}
val serializedMessage = json.encodeToString(rawKayaks)

4. 注解顺序问题

尝试调整@BsonId和@Serializable的顺序,确保序列化注解优先被识别:

@Serializable
data class Kayak(
    @BsonId @Serializable(ObjectIdSerializer::class) val id: ObjectId = ObjectId(),
    val available: Boolean = true,
    val type: TypeOfKayak = TypeOfKayak.Single,
    val reservesIds: List<String> = emptyList()
)

验证步骤

  1. 先单独序列化一个手动创建的Kayak实例,看是否能输出所有字段:
val testKayak = Kayak(available = false, type = TypeOfKayak.Double)
println(json.encodeToString(testKayak))

如果这个输出正常,说明问题出在数据库返回的对象或WebSocket发送环节;如果输出仍只有id,那就是数据类本身的序列化配置问题。

  1. 检查Ktor依赖是否齐全,确保包含序列化相关库:
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")

内容的提问来源于stack exchange,提问作者Bobby ESP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 03:10:27