在 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 反序列化
我需要解析这个 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 反序列化