如何序列化不同类型的字段?

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)])])