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

Kotlin默认参数未随Retrofit请求体传递的问题排查与解决

问题描述

使用kotlinx.serialization的@Serializable注解定义了如下Request数据类:

@Serializable
data class Request(
    val a: String,
    val b: String,
    val c: String = "version"
)

在Retrofit接口及调用代码中:

@PUT(value = "path/to/endpoint")
suspend fun sendRequest(@Body request: Request): Response

override fun sendRequest(request: Request) =
    flow<Resource<Response, NetworkError>> {
        emit(Resource.Success(network.sendRequest(request)))
    }.catch {
        emit(Resource.Error(it.parseNetworkError()))
    }

发现默认参数val c: String = "version"不会被包含在请求体中,但显式传入该参数(如Request("test", "test", "version"))或在发送前断点调试时,该参数能正常随请求体传递。而使用Request("test", "test")创建实例则不行。请问这是否是编译器优化导致的?该如何避免这种情况?


原因与解决方案

原因

这不是编译器优化的问题,而是kotlinx.serialization的默认序列化规则导致的:

  • Kotlin数据类的默认参数在未显式赋值时,仅会在类内部使用默认值,但不会被kotlinx.serialization判定为已初始化的属性。
  • 序列化器默认仅序列化显式赋值的属性,未显式传入的默认参数会被跳过,不会生成对应的请求体字段。

解决方案

可以通过以下几种方式解决:

  1. 添加@Required注解强制序列化
    给默认参数加上@Required注解,让序列化器强制包含该属性,哪怕它使用了默认值(需kotlinx.serialization 1.3及以上版本支持):

    @Serializable
    data class Request(
        val a: String,
        val b: String,
        @Required val c: String = "version"
    )
    
  2. 开启序列化器的encodeDefaults配置
    创建Json序列化器时开启encodeDefaults选项,这样所有带默认值的属性都会被序列化,无论是否显式赋值:

    val json = Json { encodeDefaults = true }
    

    配合Retrofit使用时,需要在构建实例时指定这个自定义的Json转换器:

    Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
        .build()
    
  3. 构造时显式传入默认值
    创建Request实例时始终显式传入c的默认值,或者添加工厂方法统一处理:

    // 方式1:直接显式传参
    val request = Request("test", "test", "version")
    
    // 方式2:添加工厂方法
    @Serializable
    data class Request(
        val a: String,
        val b: String,
        val c: String
    ) {
        companion object {
            fun create(a: String, b: String) = Request(a, b, "version")
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:20:43