在 Kotlin 中使用自定义 JsonDeserializer 进行改造

Retrofit with custom JsonDeserializer in Kotlin

我需要解析这个 json。默认情况下它工作正常,但我需要添加时间戳,所以我使用自定义反序列化工厂。

[
  {
"ccy": "USD",
"base_ccy": "UAH",
"buy": "26.60000",
"sale": "26.96000"
  },
  {
"ccy": "EUR",
"base_ccy": "UAH",
"buy": "28.95000",
"sale": "29.60000"
  },
  {
"ccy": "RUR",
"base_ccy": "UAH",
"buy": "0.35000",
"sale": "0.38500"
  },
  {
"ccy": "BTC",
"base_ccy": "USD",
"buy": "8610.8989",
"sale": "9517.3093"
 }
]

但是json:JsonElement? MyDeserializer 中的参数从不与 ArrayList 一起提供,总是在单个对象中。我如何读取 ArrayList 的远程 json,并修改它?

 class MyDeserializer : JsonDeserializer<ArrayList<CurrencyItem>> {

    override fun deserialize(
        json: JsonElement?,
        typeOfT: Type?,
        context: JsonDeserializationContext?
    ): ArrayList<CurrencyItem> {

        //Clean array save result
        var currrencyList = ArrayList<CurrencyItem>()

        // Get remote json
        val itemsJsonArray = jsonObject.asJsonArray

       //Modify remote json to custom object with timestamp
        for (item in itemsJsonArray) {

            var JsonObject = item.asJsonObject

            var ccy = JsonObject.get("ccy").asString
            var base_ccy = JsonObject.get("base_ccy").asString
            var buy = JsonObject.get("buy").asString
            var sale = JsonObject.get("sale").asString

            var timestamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())

            currrencyList.add(CurrencyItem(1, ccy, base_ccy, buy, sale, time))

        }
        return currrencyList
    }


}

添加自定义转换器进行改造

       //Add converter to retrofit
        val retrofit =
        Retrofit.Builder().baseUrl("https://api.privatbank.ua/")

            //My custom converter
            .addConverterFactory(GsonConverterFactory.create(customGson))

           .client(okkHttpclient)
           .build()

问题是您使用错误的类型注册了反序列化器:

JsonDeserializer<ArrayList<CurrencyItem>>

您的反序列化器的类型是

ArrayList<CurrentItem>

但是,您正在使用

注册它
CurrencyItem::class.java

现在,注册泛型不像普通类型那么简单。 在您的情况下,您需要:

Type currencyItemListType = new TypeToken<ArrayList<CurrencyItem>>() {}.getType();
registerTypeAdapter(currencyItemListType, MyDeserializer())code here

因此,当使用成功代码 (2xx) 进行反改造调用 returns 时,它应该会自动尝试使用反序列化器 json 反序列化