gson Kotlin使用新的行分隔符解析json数组

pdtvr36n  于 2022-11-06  发布在  Kotlin
关注(0)|答案(1)|浏览(201)

我在Kotlin应用程序中使用OKHttpClient将一个文件发送到一个被处理的API。当进程运行时,API发送回消息以保持连接活动,直到结果完成。所以我收到了以下内容(这是使用println()打印到控制台的内容)

  1. {"status":"IN_PROGRESS","transcript":null,"error":null}
  2. {"status":"IN_PROGRESS","transcript":null,"error":null}
  3. {"status":"IN_PROGRESS","transcript":null,"error":null}
  4. {"status":"DONE","transcript":"Hello, world.","error":null}

我相信这是由一个新的行字符,而不是逗号分隔。
我通过执行以下操作找到了提取数据的方法,但是有没有一种在技术上更正确的方法来转换数据呢?我已经使用了这种方法,但是在我看来,这种方法很容易出错。

  1. data class Status (status : String?, transcript : String?, error : String?)
  2. val myClient = OkHttpClient ().newBuilder ().build ()
  3. val myBody = MultipartBody.Builder ().build () // plus some stuff
  4. val myRequest = Request.Builder ().url ("localhost:8090").method ("POST", myBody).build ()
  5. val myResponse = myClient.newCall (myRequest).execute ()
  6. val myString = myResponse.body?.string ()
  7. val myJsonString = "[${myString!!.replace ("}", "},")}]".replace (",]", "]")
  8. // Forces the response from "{key:value}{key:value}"
  9. // into a readable json format "[{key:value},{key:value},{key:value}]"
  10. // but hoping there is a more technically sound way of doing this
  11. val myTranscriptions = gson.fromJson (myJsonString, Array<Status>::class.java)
kupeojn6

kupeojn61#

另一种解决方案是在宽松模式下使用JsonReader。这允许解析不严格遵守规范的JSON,例如在您的情况下解析多个顶级值。它还使解析的其他方面变得宽松,但这可能对您的用例是可以接受的。
然后,您可以使用单个JsonReader Package 响应流,重复调用Gson.fromJson,并自己将反序列化的对象收集到列表中。例如:

  1. val gson = GsonBuilder().setLenient().create()
  2. val myTranscriptions = myResponse.body!!.use {
  3. val jsonReader = JsonReader(it.charStream())
  4. jsonReader.isLenient = true
  5. val transcriptions = mutableListOf<Status>()
  6. while (jsonReader.peek() != JsonToken.END_DOCUMENT) {
  7. transcriptions.add(gson.fromJson(jsonReader, Status::class.java))
  8. }
  9. transcriptions
  10. }

但是,如果服务器持续提供状态更新直到处理完成,那么直接处理解析的状态而不是在处理它们之前将它们全部收集在列表中可能更有意义。

展开查看全部

相关问题