改装-安卓系统-使用gson处理多种类型的密钥和值



因此,在处理响应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)
}

最新更新