反序列化 JSON 中的字符串

Posted

技术标签:

【中文标题】反序列化 JSON 中的字符串【英文标题】:Deserialize String inside JSON 【发布时间】:2022-01-14 20:05:31 【问题描述】:

我收到具有以下结构的 JSON 响应:

[
    
        "dateCreated": "07-22-2021",
        "comments": "Commenst",
        "url_list": "[\"id\":1,\"name\":\"\",\"img\":\"https://legacynissan-ez360.imgix.net/1C3CDFEB6GD555251/1C3CDFEB6GD555251-2016-Dodge-Dart.sp_turntable_pic.1000.16x9-3840x2160-4K.20210721130782.jpg?w=300\",\"is_checked\":false,\"pois\":[],\"id\":2,\"name\":\"\",\"img\":\"https://legacynissan-ez360.imgix.net/1C3CDFEB6GD555251/1C3CDFEB6GD555251-2016-Dodge-Dart.sp_turntable_pic.1001.16x9-3840x2160-4K.20210721130782.jpg?w=300\",\"is_checked\":false,\"pois\":[],\"id\":3,\"name\":\"\",\"img\":\"https://legacynissan-ez360.imgix.net/1C3CDFEB6GD555251/1C3CDFEB6GD555251-2016-Dodge-Dart.sp_turntable_pic.1002.16x9-3840x2160-4K.20210721130782.jpg?w=300\",\"is_checked\":false,\"pois\":[]]"

     
]

所以基本上我有一个对象列表(这个包含 dateCreated、cmets 和 url_list)我的问题是 url_list 是保存为字符串的对象列表,我不知道如何将该字符串反序列化为对象。

1)这可能吗? 2)怎么做?

我正在使用 Ktor 客户端和 kotlinx 序列化。

【问题讨论】:

【参考方案1】:

我正在使用 Ktor 客户端和 kotlinx 序列化。

我也没用过。所以我用谷歌搜索了“kotlinx 自定义序列化”。这导致我使用 the documentation on the the GitHub page 进行 Kotlinx 序列化。在那个页面上有a huge section on custom serialization。

基于此,您的答案是:

    这可能吗? -> 是的,完全可以。

    怎么做? -> 编写一个自定义序列化程序 - 根据文档 - 将 url_list JSON 字符串解析为类对象。

【讨论】:

我认为这是一个可能的解决方案,但对于我来说,我无法弄清楚如何编写自定义序列化程序,所以我想出了一个不同的方法。谢谢。【参考方案2】:

您需要将 url_list 模拟为它自己的对象。您可能需要稍作修改。

@Serializable
data class YourJson(
        var dateCreated: String,
        var comments: String
        @SerializedName("url_list")
        var urlStuff : List<UrlStuff>
)
@Serializable
data class UrlStuff(
        var id: Int,
        var name: String,
        @SerializedName("img")
        var image: String,
        @SerializedName("is_checked")
        var isChecked: Boolean,
        var pois: List<String>
)

【讨论】:

这行不通,因为 YourJson 类中的 urlStuff 嵌入在字符串中,所以你会得到这样的“UrlStuffObject”【参考方案3】:

我最终创建了 3 个对象来对传入的数据进行建模。

响应数据的结构如下:

    对象列表 每一个都包含嵌入在字符串中的对象列表 每一个都包含另一个对象列表。

我的三个对象与我得到的响应相匹配 现在通常我只需使用 @serializable 标记所有内容并正确完成类,然后 Kotlin 会处理其余的事情。

这次的问题是第二个对象被嵌入到一个字符串中。

解决这个问题的方法是使用这个来解析它:

Json.decodeFromString<List<myObject>>(theStringIWantToParse)

这解决了问题,我可以获取所有数据,但是,这非常不方便,因为我不会将所有数据都放在一个数据结构中,而且我每次都必须手动解析。

所以我将它与来自此 this 视频的信息结合起来

这导致我创建另外 3 个对象,这些对象按照我想要的方式构建(我称它们为 Entity),而不是响应给我的方式,然后是 3 个映射器类来映射 3 个响应对象(我追加这些与 Dto)到我自己的 3 个对象(实体)

缺点:

    更多代码(3 个实体和 3 个映射器类)

好处是:

    我有一个清晰的层次,可以快速简单地适应响应结构上的机会。 它为我的代码库提供了更多的结构,因此更容易 管理而不是到处随机解析

【讨论】:

以上是关于反序列化 JSON 中的字符串的主要内容,如果未能解决你的问题,请参考以下文章

为啥JSON字符串当中会出现反斜杠?

如何反序列化作为 System.Text.Json 中的字符串的嵌套 JSON 对象?

JavaScript中的JSON序列化/反序列化

JSON序列化

从 C# 中的文件反序列化 Json

杰克逊从JSON中的变量类型反序列化