Kotlinx 序列化 MissingFieldException

Kotlinx Serialization MissingFieldException

我正在使用 Ktor 从 Moshi 转换为 kotlinx 序列化,当我尝试发出获取数据的请求时出现此错误

kotlinx.serialization.MissingFieldException: Field 'attachments' is required, but it was missing

这是有道理的,因为这个特定的响应不包含这个字段

回应Json

{
    "data": {
        "id": "1299418846990921728",
        "text": "This is a test"
    }
}

但是我的序列化 class 的 attachments 字段可以为空(它只在需要时出现在响应中)所以它应该忽略它我认为就像它对 Moshi

@Serializable
data class ResponseData(
    val id: Long
    val attachments: Attachments?,
    val author_id: String?,
    val text: String
}

在我的 Ktor 客户端设置中,我将其设置为忽略未知密钥

private val _client: HttpClient = HttpClient(engine) {
    install(JsonFeature) {
        val json = Json {
            this.isLenient = true
            this.ignoreUnknownKeys = true
        }
        serializer = KotlinxSerializer(json)
    }
}

为什么它仍然说该字段是必需的,即使它可以为空?

我想通了,显然即使您将某些内容标记为可为空,它仍然被认为是必需的。

为了让它真正成为可选的,您需要给它一个默认值,例如,数据 class 与可空值

看起来像这样
@Serializable
data class ResponseData(
    val id: Long
    val attachments: Attachments? = null,
    val author_id: String? = null,
    val text: String
}

一旦你设置了值,字段就变成可选的并且不会抛出异常

从 v1.3.0 开始,您可以配置 Json 功能以将缺失的字段视为 null,使用 explicitNulls = false

install(JsonFeature) {
    serializer = KotlinxSerializer(
        json = kotlinx.serialization.json.Json {
            explicitNulls = false
        }
    )
}

explicitNulls 的文档:

Specifies whether null values should be encoded for nullable properties and must be present in JSON object during decoding. When this flag is disabled properties with null values without default are not encoded; during decoding, the absence of a field value is treated as null for nullable properties without a default value. true by default.