Ktor框架下MongoDB查询列表无法正常返回null值字段问题
问题描述
从MongoDB collection 查询包含null值的字段时,返回结果无法正常展示对应null值,存在null被替换为0、字段直接缺失的异常。
现有Ktor实现代码
val teacherList = teacherTableCollection.find().toList() if (teacherList.isNotEmpty()) { call.respond(SuccessResponse("Teacher List", teacherList)) } else { call.respond(SuccessResponse("Teacher List", "Sorry, teacher not added yet.")) }
预期返回结果
{ "message": "Teacher List", "data": [ { "t_id": 11, "t_name": "Pratik", "s_id": null }, { "t_id": 12, "t_name": "Pratik", "s_id": null } ] }
实际返回结果
{ "message": "Teacher List", "data": [ { "t_id": 10, "t_name": "Pratik", "s_id": 0 }, { "t_id": 11, "t_name": "Pratik" }, { "t_id": 12, "t_name": "Pratik" } ] }
故障原因
- 实体类字段类型声明错误:对应教师类的
s_id字段被声明为Kotlin非空基础类型Int,MongoDB驱动反序列化时,遇到字段值为null、或字段不存在的场景,会自动给非空基础类型赋默认值0,无法识别null值;如果字段值反序列化后为非null的默认值,后续序列化也不会输出null。 - JSON序列化配置默认跳过null字段:Ktor默认的JSON序列化配置会自动忽略值为null的字段,不会将其写入最终响应体,导致s_id字段直接缺失。
修复方案
- 修改实体类字段类型,将允许为null的字段声明为可空类型
修正前的实体类示例:
修正后的实体类:data class Teacher( val t_id: Int, val t_name: String, val s_id: Int // 非空类型,无法接收null )data class Teacher( val t_id: Int, val t_name: String, val s_id: Int? // 声明为可空类型,支持接收null值 ) - 修改Ktor的JSON序列化配置,强制输出null字段,不要自动跳过
如果使用kotlinx.serialization(Ktor默认JSON实现),在安装ContentNegotiation时添加如下配置:
如果使用Jackson作为JSON序列化实现,在配置中关闭空值跳过开关、开启null值输出即可。install(ContentNegotiation) { json(Json { encodeDefaults = true // 强制输出所有字段,包括值为null的字段 ignoreUnknownKeys = true // 忽略Mongo文档中存在、实体类未定义的多余字段,避免反序列化报错 }) } - 校验MongoDB存量数据:确认t_id为11、12的文档中
s_id字段是显式存储为null,还是未存储该字段。两种场景下只要字段声明为可空类型,配合序列化配置,都能正常输出s_id: null的结果。
内容的提问来源于stack exchange,提问作者Pratik Fagadiya
相关产品推荐
相关产品推荐

