【问题标题】:Parsing json in Kotlin在 Kotlin 中解析 json
【发布时间】:2018-01-22 20:59:19
【问题描述】:

我正在尝试在 Kotlin 中解析 Json。我遇到了很多麻烦,似乎很多人在 Java 之后学习 Kotlin ......不是我,我是一个 Python 人。我有一个运行得相当快的 Kotlin Jupyter Notebook (https://github.com/ligee/kotlin-jupyter),之后我设法从 bittrex api 中提取信息,如下所示:

import java.net.URL
val result = URL("https://bittrex.com/api/v1.1/public/getmarkets").readText()

我花了很长时间才发现我需要添加 import java.net.URL,这似乎总是隐含在所有代码示例中。无论如何,这给了我一个 json 的响应(“结果参数”):

{"success":true,"message":"","result":[{"MarketCurrency":"LTC","BaseCurrency":"BTC","MarketCurrencyLong":"Litecoin","BaseCurrencyLong":"Bitcoin","MinTradeSize":0.01469482,"MarketName":"BTC-LTC","IsActive":true,"Created":"2014-02-13T00:00:00","Notice":null,"IsSponsored":null,"LogoUrl":"https://bittrexblobstorage.blob.core.windows.net/public/6defbc41-582d-47a6-bb2e-d0fa88663524.png"},{"MarketCurrency":"DOGE","BaseCurrency":"BTC","MarketCurrencyLong":"Dogecoin","BaseCurrencyLong":"Bitcoin","MinTradeSize":274.72527473,"MarketName":"BTC-DOGE","IsActive":true,"Created":"2014-02-13T00:00:00","Notice":null,"IsSponsored":null,"LogoUrl":"https://bittrexblobstorage.blob.core.windows.net/public/a2b8eaee-2905-4478-a7a0-246f212c64c6.png"},{"MarketCurrency ...

现在,在 Python 中,我只需将 .json() 添加到“结果”参数中,然后我可以将 json 字段作为具有多个级别的字典来寻址,例如

result["success"]

会给我:

true

Kotlin 有类似的东西吗?我已经尝试过 Klaxon https://github.com/cbeust/klaxon,我又花了很多时间才意识到我必须这样做 import com.beust.klaxon.string,例如网站上没有提到它,所以一个附带问题是:你怎么知道你需要什么找到代码示例时要导入?似乎每个人都知道......但我离题了。

我的主要问题是:如何处理 Json 的单独字段并将它们放入单独的变量中?

致以最诚挚的问候。

【问题讨论】:

  • 重新导入:通过阅读 api 文档或源代码,和/或简单地告诉 IDE 添加缺少的导入。通过阅读文档来回答您的问题:github.com/cbeust/klaxon#lowLevelApigithub.com/cbeust/klaxon#objectBindingApi。阅读(文档、教程、自述文件)是编程的重要组成部分。
  • 是的,我意识到我还有很长的路要走。您链接到的内容并没有真正告诉我任何事情,一些自定义 json 对象已构建,但值不会被它们各自的键读回。有一些使用“解析器”的示例代码,但是我得到“错误:未解析的引用:解析器”,不知道如何解决(尝试谷歌搜索该错误)。我觉得如果可以开始从那个 json 中获取一些值,我就会开始有所收获。经过数小时的搜索和观看操作指南,我正在写这篇文章。
  • 这些值不会被它们各自的键读回:是的,它们是:println("Name : ${json.string("name")}, Age : ${json.int("age")}")。它读取键“name”处的字符串值,以及键“age”处的 int 值。 Re Parser:当然,再一次,它是一个你需要导入的类。

标签: json kotlin jupyter-notebook klaxon


【解决方案1】:

那里有很多 JSON 解析器。您的示例是 Kotlin 显式示例,这对于 Kotlin 不是强制性的,因为还有许多基本的 Java 解析器,您可以在 Kotlin 中同样使用它们。

为您的进口。显然,您需要导入要使用的类,而像 IntelliJ 这样的 IDE 会自动为您处理导入。这意味着您不必键入任何 import 语句,但它们会在引用这些类时自动添加。

我认为现在一些库只是希望您不自己处理导入,因此无法帮助您找到正确的导入。

我对解析器的建议是Fuel。 该库也针对 Kotlin 进行了优化。在 Fuel 的帮助下,这个简单的代码 sn-p 将解决您的问题:

"https://bittrex.com/api/v1.1/public/getmarkets".httpGet().responseJson { _, response, result ->
    if (response.responseMessage == "OK" && response.statusCode == 200) {
        val yourResult = result.get().obj().getBoolean("success")
    }
}

【讨论】:

    【解决方案2】:

    您可能知道也可能不知道 Kotlin 与 Java 100% 兼容,因此所有 Java json 解析器都可以很好地与 Kotlin 配合使用。我强烈推荐gson。它体积小(~200kb),速度快,而且使用起来非常简单。

    如果这段代码在服务器上运行,jackson 是相当标准的。它是目前 java 性能最高的 json 解析器,但它很重。不过这需要一些更复杂的配置,而且我认为它可能需要一些 Kotlin 特定的模块。

    我还没有尝试过,因为它还没有正式发布,但是 Kotlin 提供了一个plugin for generating json serialization code。这可能最终会成为 Kotlin 序列化/反序列化的标准方式,因为理论上它应该是最高性能的。

    【讨论】:

    • Gson 是一个 Java 库,因此不理解 Kotlin 的不可空字段。您最终将在应该为非空的字段中得到空值。否则效果很好。
    【解决方案3】:

    最好和快速的做法不是手动检查每个键,而是使用工具生成本机 Kotlin“数据类”,例如https://json2kotlin.com

    所以你的 API 响应变成了下面几个对应 JSON 结构的数据类:

    data class Json4Kotlin_Base (
    
        val success : Boolean,
        val message : String,
        val result : List<Result>
    )
    

    data class Result (
    
        val marketCurrency : String,
        val baseCurrency : String,
        val marketCurrencyLong : String,
        val baseCurrencyLong : String,
        val minTradeSize : Double,
        val marketName : String,
        val isActive : Boolean,
        val isRestricted : Boolean,
        val created : String,
        val notice : String,
        val isSponsored : String,
        val logoUrl : String
    )
    

    获得结果后,您只需将 JSON 响应映射到这些数据类。 video here 展示了如何一步一步完成。

    【讨论】:

      猜你喜欢
      • 2021-10-08
      • 1970-01-01
      • 2020-11-04
      • 2018-07-23
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多