Kotlinx 将 JSON Array 序列化为数据类
Posted
技术标签:
【中文标题】Kotlinx 将 JSON Array 序列化为数据类【英文标题】:Kotlinx serialization of JSON Array to data class 【发布时间】:2021-12-21 11:20:14 【问题描述】:对于我的 android 应用,我尝试使用 Kotlinx 序列化来解析网络响应。网络响应是来自Kraken 的 WebSocket Payload,看起来像一个 JSON 数组,其中包含没有键的元素。我想为此响应创建一个数据类并分配缺少的键。网络响应如下所示:
[
324,
"a": [
"65534.00000",
8,
"8.45840938"
],
"b": [
"65533.90000",
0,
"0.00352122"
],
"c": [
"65533.90000",
"0.00458332"
],
"v": [
"2282.41761567",
"3048.01677262"
],
"p": [
"65297.21555",
"64608.96127"
],
"t": [
27317,
38224
],
"l": [
"63319.60000",
"61810.00000"
],
"h": [
"66420.00000",
"66420.00000"
],
"o": [
"63319.60000",
"61962.00000"
]
,
"ticker",
"XBT/USD"
]
【问题讨论】:
这是什么反应?我在这里看不到任何模式。你能解释一下吗?你还想要什么样的数据类?你能给出一些大纲吗? 这是来自 Kraken 的 WebSocket 的有效负载:Kraken 我有一个回调函数,用于推送更新的数据。我之前尝试的是构建 Payload。 【参考方案1】:对于 JSON 数组
[
"id": 324,
"items":
"a": [
"65534.00000",
8,
"8.45840938"
],
"b": [
"65533.90000",
0,
"0.00352122"
],
"c": [
"65533.90000",
"0.00458332"
],
"v": [
"2282.41761567",
"3048.01677262"
],
"p": [
"65297.21555",
"64608.96127"
],
"t": [
27317,
38224
],
"l": [
"63319.60000",
"61810.00000"
],
"h": [
"66420.00000",
"66420.00000"
],
"o": [
"63319.60000",
"61962.00000"
]
,
"unit" : "ticker",
"code" : "XBT/USD"
]
Kotlin 数据类将是
import com.google.gson.annotations.SerializedName
data class Example (
@SerializedName("id") var id : Int,
@SerializedName("items") var items : Items,
@SerializedName("unit") var unit : String,
@SerializedName("code") var code : String
)
但是,您的响应看起来不像 JSON 数组,其格式应为:
[,,]
你的回复是一个普通的数组形式:
[,,,]
【讨论】:
感谢您的回答!我认为它是一个 JSON 数组,除了 Objects 之外还包含 Int 和 String 类型的值。如果在您的示例中存在值的键,则可以在数据类中分配一个名称。但在我的回复中,钥匙不见了。【参考方案2】:最后我最终将有效负载解码为 JsonArray 并手动将其内容提供给我的数据类。
这是我的数据类:
@Serializable
data class Ticker(
var channelID : String,
var channelName : String,
var pair : String,
var ticker : TickerData,
)
@Serializable
data class TickerData(
@SerialName("a")
val ask: Ask,
@SerialName("b")
val bid: Bid,
@SerialName("c")
val close: Close,
@SerialName("h")
val volume: Volume,
@SerialName("l")
val volumeWeightedAveragePrice: VolumeWeightedAveragePrice,
@SerialName("o")
val numberOfTrades: NumberOfTrades,
@SerialName("p")
val lowPrice: LowPrice,
@SerialName("t")
val highPrice: HighPrice,
@SerialName("v")
val openPrice: OpenPrice,
)
@Serializable
data class Ask(
var price: String,
var wholeLotVolume: Int,
var lotVolume: String,
)
@Serializable
data class Bid(
var price: String,
var wholeLotVolume: Int,
var lotVolume: String,
)
@Serializable
data class Close(
var price: String,
var lotVolume: String,
)
@Serializable
data class Volume(
var today: String,
var last24Hours: String,
)
@Serializable
data class VolumeWeightedAveragePrice(
var today: String,
var last24Hours: String,
)
@Serializable
data class NumberOfTrades(
var today: String,
var last24Hours: String,
)
@Serializable
data class LowPrice(
var today: String,
var last24Hours: String,
)
@Serializable
data class HighPrice(
var today: String,
var last24Hours: String,
)
@Serializable
data class OpenPrice(
var today: String,
var last24Hours: String,
)
这是我的有效负载解析器:
class KrakenApiWebSocketPayload(val json: Json)
fun getTicker(response:String): Ticker
val tickerArray : JsonArray = json.decodeFromString(response)
val tickerObject : JsonObject = tickerArray[1].jsonObject
val ask : JsonArray = tickerObject.get("a")!!.jsonArray
val bid : JsonArray = tickerObject.get("b")!!.jsonArray
val close : JsonArray = tickerObject.get("c")!!.jsonArray
val volume : JsonArray = tickerObject.get("h")!!.jsonArray
val volumeWeightedAveragePrice : JsonArray = tickerObject.get("l")!!.jsonArray
val numberOfTrades : JsonArray = tickerObject.get("o")!!.jsonArray
val lowPrice : JsonArray = tickerObject.get("p")!!.jsonArray
val highPrice : JsonArray = tickerObject.get("t")!!.jsonArray
val openPrice : JsonArray = tickerObject.get("v")!!.jsonArray
return Ticker(tickerArray[0].toString(),tickerArray[2].toString(),tickerArray[3].toString(),
TickerData(
Ask(ask[0].toString(),ask[1].toString().toInt(),ask[2].toString()),
Bid(bid[0].toString(),bid[1].toString().toInt(),bid[2].toString()),
Close(close[0].toString(),close[1].toString()),
Volume(volume[0].toString(),volume[1].toString()),
VolumeWeightedAveragePrice(volumeWeightedAveragePrice[0].toString(),volumeWeightedAveragePrice[1].toString()),
NumberOfTrades(numberOfTrades[0].toString(),numberOfTrades[1].toString()),
LowPrice(lowPrice[0].toString(),lowPrice[1].toString()),
HighPrice(highPrice[0].toString(),highPrice[1].toString()),
OpenPrice(openPrice[0].toString(),openPrice[1].toString())
)
)
【讨论】:
以上是关于Kotlinx 将 JSON Array 序列化为数据类的主要内容,如果未能解决你的问题,请参考以下文章
在 kotlinx.serialization 中编码/解码 JSON“字符串”
kotlinx.serialization - 使用自定义 DateSerializer 将 ArrayList<Date> 序列化为数据类变量