android - 如何使用 Gson 和 Retrofit 将类似的 Json 对象转换为 Json 数组
问题描述
假设我收到 API 的响应低于
{"success":true,
"base":"EUR",
"date":"2021-04-16",
"rates":
{"AED":4.393943,"AFN":92.83145,"ALL":123.125765,"AMD":621.059723}}
我希望最后一个费率对象是费率类列表,即费率(代码 =“AED”,值 =“4.393943”)。我正在使用改造和 Gson。我知道我需要一个解串器或一个类型适配器。我只是不知道怎么写。
费率等级:
data class Rate(
val code:String,
val value:Float
)
货币类别:
data class Currency(
@SerializedName("success")
val success: Boolean?,
@SerializedName("base")
val base: String?,
@SerializedName("date")
val date: Date?,
@SerializedName("rates")
val rates: List<Rate>?
)
这是请求:
val gson: Gson = GsonBuilder()
.registerTypeHierarchyAdapter(Rate::class.java, TypeAdapterOrDeserializer())
.create()
val retrofit = Retrofit.Builder()
.baseUrl("https://api.exchangerate.host")
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
val jsonPlaceholderApi = retrofit.create(JsonPlaceholderApi::class.java)
val call = jsonPlaceholderApi.currency
当我从 api 请求数据时,它给出了这个错误,我知道为什么;)因为我在 Currency 类中给出了汇率列表,但它是一个 json 汇率对象。com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:应为 BEGIN_ARRAY 但为 BEGIN_OBJECT
感谢您的帮助 :)
解决方案
API 返回的数据rates
是一个 JSON 对象,但在您的数据类中,您将其定义为 aList
所以Gson
期望它是一个 JSON 数组。Currency
在这种情况下,您需要为您的课程进行自定义解析。
使用这个解串器:
class CurrencyDeserializer : JsonDeserializer<Currency> {
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Currency {
if (json == null || context == null) {
// handle error here
throw Exception("Error")
}
val obj = json.asJsonObject
// let Gson handle the other 3 properties
val success = context.deserialize<Boolean?>(obj.get("success"), Boolean::class.java)
val base = context.deserialize<String?>(obj.get("base"), String::class.java)
val date = context.deserialize<Date?>(obj.get("date"), Date::class.java)
// create List<Rate> from the rates JsonObject
val ratesSet = obj.get("rates").asJsonObject.entrySet()
val ratesList = ratesSet.map {
val code = it.key
val value = it.value.asFloat
Rate(code, value)
}
return Currency(success, base, date, ratesList)
}
}
像这样添加它Gson
:
val gson: Gson = GsonBuilder()
.registerTypeAdapter(Currency::class.java, CurrencyDeserializer())
.create()
推荐阅读
- python - 从代码 python 中减少 if - elif-else 语句
- ios - 如何创建具有不同起始价格的订阅?
- pine-script - OANDA:XAUUSD - 基础货币为空
- typescript - NestJS 和无服务器 - 处理程序“处理程序”不是函数
- oracle - 用于 kibana 的 oracle jdbc 驱动程序配置
- javascript - 如何确保 shinyjs::runjs 在 DOM 更新后运行?
- javascript - Chart.js:如何获得由其他线的总和创建的线?
- amazon-web-services - Route53:将多个域名解析到单个私有托管区域
- python - 执行 pandas 操作以填充缺失的月份数据时出错
- javascript - 日期最小值和最大值,onchange 事件侦听器迄今为止无法正常工作