我在应用程序中使用外部API,而反序列化是通过Kotlinx序列化程序包完成的,但是当api结果是多个值的Int数组和单个值的原始int时,我遇到了问题。我如何避免在此过程中崩溃。有没有更好的方法来避免崩溃或创建数据类
例如:
import kotlinx.serialization.Serializable
@Serializable
data class Bookings (val slots: List<Int>)
插槽具有单一值API时返回{slots: 1}
当广告位具有多个值API时,返回{ slots: [1,2,3,4]}
答案 0 :(得分:1)
可以使用自定义序列化器完成
import kotlinx.serialization.*
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonInput
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.int
@Serializable(with = BookingsSerializer::class)
data class Bookings(val slots: List<Int>)
@Serializer(forClass = Bookings::class)
object BookingsSerializer : KSerializer<Bookings> {
override fun deserialize(decoder: Decoder): Bookings {
val json = (decoder as JsonInput).decodeJson().jsonObject
return Bookings(parseSlots(json))
}
private fun parseSlots(json: JsonObject): List<Int> {
val slotsJson = json["slots"] ?: return emptyList()
return try {
slotsJson.jsonArray.content.map { it.int }
} catch (e: Exception) {
listOf(slotsJson.int)
}
}
}
@ImplicitReflectionSerializer
fun main() {
val json = """{"slots": 1}"""
val result = Json.parse<Bookings>(json)
println(result) // prints Bookings(slots=[1])
}
答案 1 :(得分:1)
我更新了@Andrei 2021 年的答案,因为自 2019 年以来类和方法名称发生了一些变化:
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.encoding.Decoder
@Serializable(with = BookingsSerializer::class)
data class Bookings(val slots: List<Int>)
@Serializer(forClass = Bookings::class)
object BookingsSerializer : KSerializer<Bookings> {
override fun deserialize(decoder: Decoder): Bookings {
val json = (decoder as JsonDecoder).decodeJsonElement().jsonObject
return Bookings(parseSlots(json))
}
private fun parseSlots(json: JsonObject): List<Int> {
val slotsJson = json["slots"] ?: return emptyList()
return try {
slotsJson.jsonArray.map { it.jsonPrimitive.int }
} catch (e: Exception) {
listOf(slotsJson.jsonPrimitive.int)
}
}
}
val json = """{"slots": 1}"""
val result = Json.decodeFromString<Bookings>(json)
println(result.toString()) // prints Bookings(slots=[1])