使用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() )
验证步骤
- 先单独序列化一个手动创建的
Kayak实例,看是否能输出所有字段:
val testKayak = Kayak(available = false, type = TypeOfKayak.Double) println(json.encodeToString(testKayak))
如果这个输出正常,说明问题出在数据库返回的对象或WebSocket发送环节;如果输出仍只有id,那就是数据类本身的序列化配置问题。
- 检查Ktor依赖是否齐全,确保包含序列化相关库:
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
内容的提问来源于stack exchange,提问作者Bobby ESP
相关产品推荐
相关产品推荐

