Ktor Serializer序列化data class时默认参数未输出到JSON的问题
问题根本原因
这个异常现象是kotlinx.serialization(Ktor客户端/Android网络请求生态中默认使用的JSON序列化框架)的内置默认策略导致,不属于代码逻辑错误:
- 框架默认配置
encodeDefaults = false - 该配置的触发逻辑为:序列化对象时,若某字段的当前值与字段声明的默认值完全相等,会直接跳过该字段,不将其写入最终输出的JSON字符串。
对应你碰到的场景:你为companyUUID设置了默认值,构造实例时没有显式传入该参数,字段值自然与默认值完全一致,序列化阶段就会被框架直接剔除,最终请求的JSON体中不会出现这个键。而你之前不带默认值的实现,不存在字段匹配默认值的触发条件,所有字段都会正常输出,因此表现符合预期。
可落地的解决方法
你可以根据实际业务需求选择适配方案:
方案1:全局开启默认值序列化
在初始化序列化器(或Ktor客户端的内容协商模块)时,显式打开encodeDefaults配置,全局生效后所有带默认值的字段,无论当前值是否与默认值一致,都会强制输出到JSON中:
// JSON实例配置示例 Json { encodeDefaults = true // 核心配置项 // 保留你已有的其他配置,比如ignoreUnknownKeys等 }
将配置好的Json实例绑定到客户端的序列化模块后,所有请求的序列化逻辑都会遵循这个规则。
方案2:单字段强制序列化标记
如果你不想调整全局配置,只需要对companyUUID字段做强制序列化,可以在字段上添加@EncodeDefault注解,单独指定该字段不受全局encodeDefaults配置的约束:
@Serializable data class ComanyCustomerLoginData( val email: String, val credential: String, @EncodeDefault val companyUUID: String = "d80f0b72-a062-11eb-bcbc-0242ac130002", )
这种方式不会影响其他带默认值字段的原有序列化逻辑,仅对标记的字段生效。
排查注意点
- 该现象完全发生在序列化阶段,和HTTP客户端的请求拦截、网络层处理无关。你可以在发请求前直接调用
Json.encodeToString(customerLoginData)打印序列化结果,就能看到剔除字段的行为在请求发出前就已经完成。 - 这个默认行为是kotlinx.serialization 1.0正式版开始就确定的设计初衷——减少无意义的默认值流量传输,不属于框架bug,仅因为多数开发者不熟悉默认配置,才会频繁遇到这类问题。
内容的提问来源于stack exchange,提问作者Tarun Chawla
相关产品推荐
相关产品推荐

