8

假设我正在上课:

@Serializable
data class MyClass(
    @SerialName("a") val a: String?,
    @SerialName("b") val b: String
)

假设aisnullb' 的值为“b 值”,则Json.stringify(MyClass.serializer(), this)产生:

{ "a": null, "b": "b value" }

基本上如果anull,我想得到这个:

{ "b": "b value" }

通过一些研究,我发现目前 Kotlinx 序列化开箱即用是不可行的,所以我试图构建一个自定义序列化程序来显式忽略null值。我从这里按照指南进行操作,但无法做出正确的指南。

有人可以帮我解释一下吗?谢谢。

4

4 回答 4

4

使用encodeDefaults = false属性,JsonConfiguration它不会序列化空值(或其他可选值)

于 2020-05-28T19:30:46.553 回答
2

试试这个(未经测试,仅基于改编示例):

@Serializable
data class MyClass(val a: String?, val b: String) {
    @Serializer(forClass = MyClass::class)
        companion object : KSerializer<MyClass> {
        override val descriptor: SerialDescriptor = object : SerialClassDescImpl("MyClass") {
            init {
                addElement("a")
                addElement("b")
            }
        }

        override fun serialize(encoder: Encoder, obj: MyClass) {
            encoder.beginStructure(descriptor).run {
                obj.a?.let { encodeStringElement(descriptor, 0, obj.a) }
                encodeStringElement(descriptor, 1, obj.b)
                endStructure(descriptor)
            }
        }

        override fun deserialize(decoder: Decoder): MyClass {
            var a: String? = null
            var b = ""

            decoder.beginStructure(descriptor).run {
                loop@ while (true) {
                    when (val i = decodeElementIndex(descriptor)) {
                        CompositeDecoder.READ_DONE -> break@loop
                        0 -> a = decodeStringElement(descriptor, i)
                        1 -> b = decodeStringElement(descriptor, i)
                        else -> throw SerializationException("Unknown index $i")
                    }
                }
                endStructure(descriptor)
            }

            return MyClass(a, b)
        }
    }
}
于 2019-09-23T09:10:11.347 回答
1

JsonConfiguration自 kotlinx.serialization 1.0.0 -RC根据其changelog以来,不推荐使用builder 。Json {}

现在你必须像这样编码:

val json = Json { encodeDefaults = false }
val body = json.encodeToString(someSerializableObject)
于 2020-11-22T20:26:30.223 回答
1

您可以使用explicitNulls = false

例子:

@OptIn(ExperimentalSerializationApi::class)
val format = Json { explicitNulls = false }
    
@Serializable
data class Project(
    val name: String,
    val language: String,
    val version: String? = "1.3.0",
    val website: String?,
)
    
fun main() {
    val data = Project("kotlinx.serialization", "Kotlin", null, null)
    val json = format.encodeToString(data)
    println(json) // {"name":"kotlinx.serialization","language":"Kotlin"}
}

https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/json.md#explicit-nulls

于 2021-11-19T10:47:49.900 回答