如何在保留访问键名称的情况下将 Kotlin 对象数组转换为 json 数组?

How to convert an Kotlin array of objects into json array with preserving access key names?

我有一个 API 要求 json 请求采用特定的数组形式,其中使用名称访问数组对象字段,然后使用 Retrofit 发布。请参考以下代码:

科特林:

class RailPoint(
 var railPointId,
 var startTime,
 var endTime
)

var rails: ArrayList<RailPoint>()
rails.add(RailPointObject1)
rails.add(RailPointObject2)

因此,将上面的 rails 数组转换为 json 后,应该会产生以下结果:

{
  "railPoint[0][railPointId]": 5,
  "railPoint[0][startTime]": "",
  "railPoint[0][endTime]": "2021-10-19 07:37:19",
  "railPoint[1][railPointId]": 1,
  "railPoint[1][startTime]": "2021-10-19 07:33:37",
  "railPoint[1][endTime]": "2021-10-19 07:35:20",
}

那么,如何实现这种json数组形式呢?

这是一个丑陋的请求,你也许可以用一个丑陋的解决方案来解决它:)

我不建议将此用于任何严肃的、大型的或需要一些艰苦和复杂维护的任何东西,但如果这个 object 将保持那么简单(一个 int 和两个字符串,non-nullable 字段)并且不会有太大变化,您可以手动完成:

class RailPoint(
    var railPointId: Int,
    var startTime: String,
    var endTime: String
)

val rails = listOf(
    RailPoint(1, "", "2021-10-19 07:37:19"),
    RailPoint(2, "2021-10-19 07:33:37", "2021-10-19 07:35:20"),
)

fun toJson(rails: List<RailPoint>): String {
    val sb = StringBuilder()
    
    rails.forEachIndexed { index, railPoint ->
        sb.append("\"railPoint[$index][railPointId]\": ${railPoint.railPointId},")
        sb.append("\"railPoint[$index][startTime]\": \"${railPoint.startTime}\",")
        sb.append("\"railPoint[$index][endTime]\": \"${railPoint.endTime}\",")
    }

    return "{ $sb }"
}

这是一种非常肮脏的方法,但可能就足够了,只要您不让 RailPoint 变得更复杂,尤其是如果您不添加自定义成员 类 或collections.

(我假设时间是Strings,但如果不是,只需在公式中添加一些日期格式)

这可以通过首先让 Gson 将列表序列化为 JsonArray, then combining the elements in a new JsonObject 然后将该对象序列化为 JSON:

来解决
val rails: List<RailPoint> = ...

val gson = Gson()
val railsJsonList = gson.toJsonTree(rails).asJsonArray!!
val railsJsonObject = JsonObject()
// Transform elements
for (i in 0 until railsJsonList.size()) {
    val railPointJson = railsJsonList[i].asJsonObject

    for ((name, value) in railPointJson.entrySet()) {
        railsJsonObject.add("railPoint[$i][$name]", value)
    }
}
println(gson.toJson(railsJsonObject))