如何序列化不同类型的字段?
How to serialize fields with varying type?
我有以下数据 类 需要解析 JSON。我可以使用 decodeFromString
方法轻松解析它。但是,Info
类 可能会不时包含 List<Int>
类型以及 Int
类型,因此两者都包含在一个 JSON 中。我如何处理序列化中的这种变化?
@Serializable
data class Node (@SerialName("nodeContent") val nodeContent: List<Info>)
@Serializable
data class Info (@SerialName("info") val info: Int)
p.s。最接近我的问题是这个:。请问还有其他方法吗?
编辑:
下面给出一个例子。
"nodeContent": [
{
"info": {
"name": "1",
},
},
{
"info": [
{
"name": "1"
},
{
"name": "2"
},
],
},
{
"info": {
"name": "2",
},
}
]
这是一种使用自定义序列化程序的方法,类似于您提供的 link。这个想法是return一个只有一个元素的列表。
// Can delete these two lines, they are only for Kotlin scripts
@file:DependsOn("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0")
@file:CompilerOptions("-Xplugin=/snap/kotlin/current/lib/kotlinx-serialization-compiler-plugin.jar")
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.encoding.Decoder
@Serializable
data class Node (val nodeContent: List<Info>)
@Serializable(with = InfoSerializer::class)
data class Info (val info: List<Name>)
@Serializable
data class Name (val name: Int)
@Serializer(forClass = Info::class)
object InfoSerializer : KSerializer<Info> {
override fun deserialize(decoder: Decoder): Info {
val json = ((decoder as JsonDecoder).decodeJsonElement() as JsonObject)
return Info(parseInfo(json))
}
private fun parseInfo(json: JsonObject): List<Name> {
val info = json["info"] ?: return emptyList()
return try {
listOf(Json.decodeFromString<Name>(info.toString()))
} catch (e: Exception) {
(info as JsonArray).map { Json.decodeFromString<Name>(it.toString()) }
}
}
}
用法:
val ss2 = """
{
"nodeContent": [
{
"info":
{"name": 1}
},
{
"info": [
{"name": 1},
{"name": 2}
]
},
{
"info":
{"name": 2}
}
]
}
"""
val h = Json.decodeFromString<Node>(ss2)
println(h)
结果:
Node(nodeContent=[Info(info=[Name(name=1)]), Info(info=[Name(name=1), Name(name=2)]), Info(info=[Name(name=2)])])
我有以下数据 类 需要解析 JSON。我可以使用 decodeFromString
方法轻松解析它。但是,Info
类 可能会不时包含 List<Int>
类型以及 Int
类型,因此两者都包含在一个 JSON 中。我如何处理序列化中的这种变化?
@Serializable
data class Node (@SerialName("nodeContent") val nodeContent: List<Info>)
@Serializable
data class Info (@SerialName("info") val info: Int)
p.s。最接近我的问题是这个:
编辑: 下面给出一个例子。
"nodeContent": [
{
"info": {
"name": "1",
},
},
{
"info": [
{
"name": "1"
},
{
"name": "2"
},
],
},
{
"info": {
"name": "2",
},
}
]
这是一种使用自定义序列化程序的方法,类似于您提供的 link。这个想法是return一个只有一个元素的列表。
// Can delete these two lines, they are only for Kotlin scripts
@file:DependsOn("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0")
@file:CompilerOptions("-Xplugin=/snap/kotlin/current/lib/kotlinx-serialization-compiler-plugin.jar")
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.encoding.Decoder
@Serializable
data class Node (val nodeContent: List<Info>)
@Serializable(with = InfoSerializer::class)
data class Info (val info: List<Name>)
@Serializable
data class Name (val name: Int)
@Serializer(forClass = Info::class)
object InfoSerializer : KSerializer<Info> {
override fun deserialize(decoder: Decoder): Info {
val json = ((decoder as JsonDecoder).decodeJsonElement() as JsonObject)
return Info(parseInfo(json))
}
private fun parseInfo(json: JsonObject): List<Name> {
val info = json["info"] ?: return emptyList()
return try {
listOf(Json.decodeFromString<Name>(info.toString()))
} catch (e: Exception) {
(info as JsonArray).map { Json.decodeFromString<Name>(it.toString()) }
}
}
}
用法:
val ss2 = """
{
"nodeContent": [
{
"info":
{"name": 1}
},
{
"info": [
{"name": 1},
{"name": 2}
]
},
{
"info":
{"name": 2}
}
]
}
"""
val h = Json.decodeFromString<Node>(ss2)
println(h)
结果:
Node(nodeContent=[Info(info=[Name(name=1)]), Info(info=[Name(name=1), Name(name=2)]), Info(info=[Name(name=2)])])