【问题标题】:Retrofit - Android - Handling multiple type keys and values with gsonRetrofit - Android - 使用 gson 处理多种类型的键和值
【发布时间】:2018-12-09 05:49:09
【问题描述】:

因此,在处理响应 json 的键和值的多种类型时,我想从我的应用程序中使用的 api 遇到了一些问题。

让我给你看一下 json 响应:

{
   "error":[

   ],
   "result":{
      "field1":[
         [
            1544258160,
            "57.15",
            "57.15",
            "57.15",
            "57.15",
            "0.00",
            "0.00000000",
            0
         ],
         [
            1544258220,
            "56.89",
            "56.89",
            "56.89",
            "56.89",
            "56.89",
            "2.94406281",
            1
         ]
      ],
      "field2":1544301240
   }
}

这是 pojo 类的表示:

data class Response(val error: List<String>, val result: LinkedTreeMap<String, List<List<Result>>>)

data class Result(
    val time: Double,
    val open: String,
    val high: String,
    val low: String,
    val close: String,
    val vwap: String,
    val volume: String,
    val count: Double
)

我知道当前的结构无法表示 json 格式。但我的想法已经用完了。

顺便说一句,堆栈错误是这样说的:

Expected BEGIN_OBJECT but was NUMBER

编辑:添加更多上下文

我将 Gsonconverter 用于改造构建器。

val retrofit = Retrofit.Builder().baseUrl(API_URL).client(client)
            .addConverterFactory(GsonConverterFactory.create()).build()

【问题讨论】:

    标签: android json gson retrofit retrofit2


    【解决方案1】:

    您可以为filed1、filed2 类型构建一个Gson JsonDeserializer
    它是更多手动编写的代码,但是这样您可以检查文件的类型并调用正确的反序列化器。

    【讨论】:

      【解决方案2】:

      是的,导致错误的是您的响应字段(结果),它是不同的类型。但是。您只需使用第一种类型 Response(val error: List&lt;String&gt;, val result:LinkedTreeMap&lt;String, List&lt;List&lt;Result&gt;&gt;&gt; 接收所有 json。

      在我看来,您可以使用以下方法来解决它。

      首先,重新定义你接收的模型,也许你可以使用 Gson JsonObject 并且在处理值时记得检查类型。

      其次,与你的后台服务器工程师讨论,同意每种类型的响应。可能是“field2”可以是“field2:[[]]”

      接下来,改变你的模型。可能是你在它下面定义的

      @Serialized("field1")
      LinkedTreeMap<String, List<List<Result>>> field;
      @Serialized("field2")
      String fields;
      

      希望能帮到你。

      【讨论】:

        【解决方案3】:

        你的问题在这里:

        "field2":1544301240
        

        你定义如下:

        val result: LinkedTreeMap<String, List<List<Result>>>
        

        但是你得到的不是那个数字!!!

        编辑

        试试这个:

        data class Response(val error: List<String>, val result: YourModel)
        
        data class YourModel(val field1: LinkedTreeMap<String, List<List<Result>>>, val field2: Double)
        
        data class Result(
            val time: Double,
            val open: String,
            val high: String,
            val low: String,
            val close: String,
            val vwap: String,
            val volume: String,
            val count: Double
        )
        

        【讨论】:

        • 是的,你是对的,但是我可以处理值类型从一组到另一组不同的情况吗?
        • 您可以发送您可能收到的完整状态 json 吗?
        • 完整的 json 太大但 API 是公开的,这里是一个例子:api.kraken.com/0/public/OHLC?pair=XZECZUSD
        【解决方案4】:

        已经有一段时间了,但我已经得出了我需要的结论。

        data class OHLCResponse(
        private val error: List<String>,
        val result: LinkedTreeMap<String, Any>)
        

        事实证明,在 LinkedTreeMap 类上,我只需将第二个类类型参数作为Any 传递,它可以向下转换为您需要的任何东西。

        我在这里留下了一个很好的工具,可以帮助您将 json 响应映射到 kotlin 普通对象/DTO:

        https://app.quicktype.io/

        感谢大家的回复。

        【讨论】:

          【解决方案5】:

          我在适配器类中用这样的解决方案解决了这个问题。

          override fun getItemCount(): Int = leagueTableList[0].size
          
          override fun onBindViewHolder(holder: LeagueTableViewHolder, position: Int) {
              val gs = Gson()
              val js = gs.toJson(leagueTableList[0][position])
              val standing = gs.fromJson(js, Standing::class.java)
              holder.view.table = standing
              holder.bind(standing,onItemClick)
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-02-16
            • 1970-01-01
            • 2019-12-08
            • 2015-09-27
            • 1970-01-01
            • 1970-01-01
            • 2023-03-15
            • 2019-12-03
            相关资源
            最近更新 更多