因此,在处理响应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()
您可以为filed1、filed2类型构建GsonJsonDeserializer
它更多的是手动编写的代码,但通过这种方式,您可以检查文件的类型并调用正确的反序列化程序。
是的,导致错误的是您的响应字段(结果(,它是不同的类型。但是,您只使用第一个类型Response(val error: List<String>, val result:LinkedTreeMap<String, List<List<Result>>>
接收所有json。
在我看来,你可以使用以下方法来解决它。
首先,重新定义你接收的模型,也许你可以使用Gson JsonObject,在处理值时记得检查类型。
其次,与您的后台服务器工程师讨论,就每种类型的响应达成一致。可能是"field2"也可能是"field2:[[]]">
接下来,改变你的模型。你可以在下面定义吗
@Serialized("field1")
LinkedTreeMap<String, List<List<Result>>> field;
@Serialized("field2")
String fields;
希望能帮助你。
您的问题在这里:
"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
)
已经有一段时间了,但我已经得出了我需要什么的结论。
data class OHLCResponse(
private val error: List<String>,
val result: LinkedTreeMap<String, Any>)
事实证明,在LinkedTreeMap类上,我只需要将第二个类类型参数作为Any
传递,它就可以向下转换为您需要的任何类型。
此外,我在这里留下了一个很好的工具,可以帮助您将json响应映射到kotlin纯对象/DTO:
https://app.quicktype.io/
感谢大家的回复。
我在适配器类中用这样的解决方案解决了这个问题。
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)
}