kotlin 如何将带对象的json对象转换为带对象的json数组

vnzz0bqm  于 2023-02-16  发布在  Kotlin
关注(0)|答案(2)|浏览(436)

我有一个如下所示的json对象。

{
  "Items": {
    "zzzz": {
      "id": "zzzz",
      "title": "qqqqqqq",
      "notifications": []
    },
    "rrrrr": {
      "id": "rrrrr",
      "title": "rrrrrrrrrrrrrrrrrr",
      "notifications": []
    },
    "eeeee": {
      "id": "eeeee",
      "title": "eeeeeeeeeeeeeeeeeeee",
      "notifications": []
    },
    "wwww": null,
    "dddddd": {
      "id": "dddddd",
      "title": "ddddddddddddddddddddddddd",
      "notifications": []
    },
    "qqq": {
      "id": "qqq",
      "title": "qqqqqqqqqqqqqqqqqqqqqq",
      "notifications": []
    },
    "rrrrrr": null
  }
}

我的数据类:

data class Response( 
                    val Items: List<Notification>
                    ........)
data ckass Notification(
                    val id : String,
                    val title: String,
                    val notifications: List<...>,

我需要一个包含zzzz、rrrr等对象的List来进入包含val项的数据类,但是我不知道如何将传入的json对象转换为json数组
我想使用我自己的反序列化器,但在我的情况下,它不会有帮助,因为我使用okhttp的一个示例,并对所有请求进行改进。而且,响应总是来自服务器,其形式为:

"Items": {
       //other request body
  },
.....
}
vc9ivgsu

vc9ivgsu1#

要将给定的JSON对象转换为Notification对象列表,可以迭代“Items”对象中的键-值对,并为每个非空值创建一个Notification对象,下面是一些示例Kotlin代码:

val json = // the JSON object from your example
    val itemsObject = json.getJSONObject("Items")
    val notifications = mutableListOf<Notification>()
    for (key in itemsObject.keys()) {
        val item = itemsObject.getJSONObject(key)
        if (item != null) {
            val notification = Notification(
                item.getString("id"),
                item.getString("title"),
                // add logic to parse notifications list here
            )
            notifications.add(notification)
        }
    }
    val response = Response(notifications)

请注意,您需要填充逻辑来解析每个Notification对象的“notifications”列表,如果它只是一个字符串数组,您可以使用item.getJSONArray("notifications").toList()来获取字符串列表。

kt06eoxx

kt06eoxx2#

我不确定你用的是什么反序列化器。这里有一个假设是Jackson的解决方案,但是如果你用的是Gson,也许你可以借鉴一下。
关键的想法是使用一个中间对象来反序列化为-一个Map,其键值可以忽略:

// your desired data classes
data class Response(
    val items: List<Notification>,
)

data class Notification(
    val id: String,
    val title: String,
    val notifications: List<Any>,
)

// an intermediary object
// I notice that some Notifications are null, hence the `?`
data class ResponseWithObjects(
    @JsonProperty("Items") // this is needed for Jackson since I used a conventional variable name Kotlin side
    val items: Map<String, Notification?>,
)

fun main(args: Array<String>) {
    val actualResponse: ResponseWithObjects = TestUtils.deserialize("/test.json", ResponseWithObjects::class)
    println(actualResponse)
    val desiredResponse = Response(
        items = actualResponse.items
            .values.filterNotNull() // assuming you don't want the null notifications in the resultant array
            .toList(),
    )
    println(desiredResponse)
}

相关问题