如何使用 kotlin 序列化防止序列化空值

问题描述

我正在使用 kotlinx-serialization-json

我有这门课:

@Serializable
data class Event(
    @SerialName("temperature") val temperature: Float?,@SerialName("pressure") val pressure: Float?,@SerialName("humidity") val humidity: Float?,)

还有这个电话

Json.encodetoString(Event(temperature = 42.0f,pressure = null,humidity = 20.9f))

在序列化期间我收到这样的json:

{
    "temperature": 20.5,"pressure": null,"humidity": 20.9
}

但我想防止序列化空值并接收这个:

{
    "temperature": 20.5,"humidity": 20.9
}

这对我来说是个问题,因为在序列化冗长的事件列表期间,我浪费了很多行。有人知道如何实现这一目标吗?

解决方法

您可以忽略所有默认值并执行以下操作:

file_writer

请注意,在上述情况下,您将忽略所有默认值。 如果您只想忽略空值,则必须实现自定义序列化程序。

对于此示例,自定义序列化程序将如下所示:

@Serializable
data class Event(
    @SerialName("temperature") val temperature: Float?,@SerialName("pressure") val pressure: Float? = null,@SerialName("humidity") val humidity: Float?,)

    val jsonMapper = Json { encodeDefaults = false}
    val body = jsonMapper.encodeToString(Event(temperature = 42.0f,pressure = null,humidity = 20.9f))

使用它 -> object EventSerializer: KSerializer<Event> { override fun deserialize(decoder: Decoder): Event { decoder.decodeStructure(descriptor) { var temperature: Float? = null var humidity:Float? = null var pressure: Float? = null while (true) { when (val index = decodeElementIndex(descriptor)) { 0 -> temperature = decodeFloatElement(descriptor,0) 1 -> pressure = decodeFloatElement(descriptor,1) 2 -> humidity = decodeFloatElement(descriptor,2) CompositeDecoder.DECODE_DONE -> break else -> error("Unexpected index: $index") } } return Event(temperature,pressure,humidity) } } override fun serialize(encoder: Encoder,value: Event) { encoder.beginStructure(descriptor).run { value.temperature?.let { encodeStringElement(descriptor,it.toString()) } value.pressure?.let { encodeStringElement(descriptor,1,it.toString()) } value.humidity?.let { encodeStringElement(descriptor,2,it.toString()) } endStructure(descriptor) } } override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Event") { element<String>("temperature") element<String>("pressure") element<String>("humidity") } }