使用 Kotlinx.Serialization 解析嵌套的 JSON

Posted

技术标签:

【中文标题】使用 Kotlinx.Serialization 解析嵌套的 JSON【英文标题】:Parse a nested JSON with Kotlinx.Serialization 【发布时间】:2019-08-20 02:25:08 【问题描述】:

我一直在玩 Kotlinx.serialization,我一直在尝试解析一个子字符串:

给定一个像这样的 JSON:


   "Parent" : 
     "SpaceShip":"Tardis",
     "Mark":40
   

我的代码是这样的:

data class SomeClass(
   @SerialName("SpaceShip") ship:String,
   @SerialName("Mark") mark:Int)

显然,Json.nonstrict.parse(SomeClass.serializer(), rawString) 将失败,因为“SpaceShip”和“Mark”这对不在 JSON 的根目录中。

如何让序列化器引用 JSON 的子树?

P.S:你会推荐改造吗(因为它更老,也许更成熟)?

【问题讨论】:

【参考方案1】:
import kotlinx.serialization.*
import kotlinx.serialization.json.Json


@Serializable
data class Parent(
    @SerialName("Parent")
    val parent: SomeClass
)

@Serializable
data class SomeClass(
    @SerialName("SpaceShip")
    val ship:String,
    @SerialName("Mark")
    val mark:Int
)

fun main() 
    val parent = Json.parse(Parent.serializer(), "\"Parent\":\"SpaceShip\":\"Tardis\",\"Mark\":40")
    println(parent)

【讨论】:

是的,我还没有找到更好的灵丹妙药。看起来与 JSON 完全一样的东西,并且可以很好地描述它。这可能是最好的。然后,我脑海中闪过一个问题:也许所有的 cmets 都是对的,而 GSON 也一样好?...【参考方案2】:
@Serializable
data class Parent(
    @SerialName("Parent")
    val someClass: SomeClass
)

@Serializable
data class SomeClass(
    @SerialName("SpaceShip")
    val ship: String,
    @SerialName("Mark")
    val mark: Int
)

fun getSomeClass(inputStream: InputStream): SomeClass 
    val json = Json(JsonConfiguration.Stable)
    val jsonString = Scanner(inputStream).useDelimiter("\\A").next()
    val parent = json.parse(Parent.serializer(), jsonString)
    return parent.someClass

【讨论】:

以上是关于使用 Kotlinx.Serialization 解析嵌套的 JSON的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 kotlinx.serialization 部分解码 JSON 字符串?

Ktor 与 Kmongo 和 kotlinx.serialization

使用 kotlinx.serialization 在 ktor 服务器中接收 Map

在 Kotlin/Native 中使用 kotlinx.serialization 进行多态反序列化

如何将 Spring Boot 映射器从 Jackson 交换到 kotlinx.serialization

使用 Kotlinx.serialization 将 JSON 数组解析为 Map<String, String>