使用 kotlinx 序列化响应中的自定义对象列表

Posted

技术标签:

【中文标题】使用 kotlinx 序列化响应中的自定义对象列表【英文标题】:Serialize custom object list in a Response with kotlinx 【发布时间】:2021-08-22 23:36:12 【问题描述】:

我有下一个 json 作为响应:

 "id":1581,"title":"hhhh","tags":[],"iconUrl":"images/b94cdcde-9c6c-4ea1-9c22-47b4c1750cce","valoration":0,"postList":["id":41,"x":0.58,"y":0.3,"rotation":338,"resourceUrl":"images/ba4202c2-845f-4b70-8167-5ef4ffb347bf","valoration":0]

我已经在我的项目中声明了响应:

@Serializable
data class BoardResponse(
    @SerialName("id")
    val id: Int,
    @SerialName("title")
    val title: String,
    @SerialName("tags")
    val tags: List<String>,
    @SerialName("iconUrl")
    val iconUrl: String,
    @SerialName("valoration")
    val valoration: Float,
    @SerialName("postList")
    val posts: List<PostResponse>
)

问题是我在“posts”值中总是得到一个空值。

这是回复:

@Serializable
data class PostResponse(
    @SerialName("id")
    val id: Int,
    @SerialName("x")
    val x: Float,
    @SerialName("y")
    val y: Float,
    @SerialName("rotation")
    val rotation: Int,
    @SerialName("resourceUrl")
    val resourceUrl: String,
    @SerialName("valoration")
    val valoration: Float
)

我能以某种方式做我想做的事吗?

【问题讨论】:

【参考方案1】:

您的代码是正确的。使用与您完全相同的声明,并使用您提供的示例 JSON,以下测试通过(您得到非空 posts):

@Test
fun test() 
    val json = """"id":1581,"title":"hhhh","tags":[],"iconUrl":"images/b94cdcde-9c6c-4ea1-9c22-47b4c1750cce","valoration":0,"postList":["id":41,"x":0.58,"y":0.3,"rotation":338,"resourceUrl":"images/ba4202c2-845f-4b70-8167-5ef4ffb347bf","valoration":0]"""
    val resp = Json.decodeFromString<BoardResponse>(json)
    assertEquals(1, resp.posts.size)

我认为您将 Kotlinx 序列化设置为反序列化库的方式一定有问题。请更新您的问题,详细说明您如何使用该库来反序列化此 JSON,或提出另一个问题。

【讨论】:

我将 kotlin 版本降级为“1.4.32”,它解决了问题,是的,这可能是库的问题。 以上测试通过 Kotlin 1.5.10 和 Kotlinx 序列化 1.2.0【参考方案2】:

数据类 PostResponse( 有效 ID:整数, val x:浮点数, val y:浮点数, val 旋转:Int, val resourceUrl:字符串, val 估值:浮动 ) : 可序列化

注意:所有变量名称必须与您的响应参数(键)相同

【讨论】:

这是OP在他自己的答案中所说的(无需重新发布),实际上也仍然不正确。使用 @SerialName 可以将 Kotlin 属性名称与其 JSON 名称以序列化形式分离。【参考方案3】:

算了,唯一的问题是 val 的名称:

val 帖子:列表

只需将其更改为 postList 即可。不知道 val 名称可以链接到 json 名称。

【讨论】:

@SerialName 注释应该会覆盖此行为。你确定那是问题吗?可能是您没有使用 Kotlinx 序列化库来反序列化该 JSON,但您可能在不知情的情况下在幕后使用了其他东西(例如 Jackson)。 是的,对不起,当我回答这个问题时,我一定很困惑!我今天早上检查,我也将kotlin版本降级为“1.4.32”。但我不明白为什么“1.5.x”版本不起作用

以上是关于使用 kotlinx 序列化响应中的自定义对象列表的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用 kotlinx 序列化多态鉴别器?

@SerialInfo - 如何使用 Kotlinx 序列化管理用户定义的串行注释?

使用 kotlinx 序列化序列化选项列表

使用外部 kotlinx 序列化器序列化列表

Kotlinx 将 JSON Array 序列化为数据类

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