在 Android 中使用 Gson 处理 Json 数组到 POJO 数组映射中的单个对象异常

Handle exception of single object in mapping of Json Array to POJO Array using Gson in Android

我正在从第三方 API 读取 Json 数组,并使用 Gson 将其直接映射到 POJO 数组。我经常会丢失某些对象的数据,并且所有缺少的参数都具有 "N/A" 值。

我的 POJO class 混合了 StringDouble 变量,现在当 "N/A" 返回时 Double 值是预期的,应用程序崩溃.当然,我可以手动遍历它们并跳过缺少数据的对象,但我正在寻找替代解决方案来帮助我在使用 Gson 进行映射时做同样的事情。

POJO class(Kotlin 语法)

class StockData(
    var symbol: String?,
    var name: String?,
    var currency: String?,
    var price: Double,
    @SerializedName("day_change")
    var dayChange: Double,
    @SerializedName("change_pct")
    var changePct: Double,
    var price90DayHigh: Double,
    var price90DayLow: Double
)

映射

val stockDataList = Gson().fromJson(response.body()!!.asJsonObject.get("data"),
                    Array<StockData>::class.java).toList()

Json 有可用数据

{
    "symbol": "AAK.ST",
    "name": "AAK AB (publ)",
    "currency": "SEK",
    "price": "189.15",
    "price_open": "190.90",
    "day_high": "190.95",
    "day_low": "188.30",
    "52_week_high": "203.80",
    "52_week_low": "131.62",
    "day_change": "-1.35",
    "change_pct": "-0.71",
    "close_yesterday": "190.50",
    "market_cap": "47993210000",
    "volume": "110641",
    "volume_avg": "476416",
    "shares": "253730934",
    "stock_exchange_long": "Stockholm Stock Exchange",
    "stock_exchange_short": "OMX",
    "timezone": "CET",
    "timezone_name": "Europe/Stockholm",
    "gmt_offset": "3600",
    "last_trade_time": "2020-02-21 17:29:54",
    "pe": "32.60",
    "eps": "5.32"
}

Json 缺少数据

{
    "symbol": "HEMF-PREF.ST",
    "name": "N/A",
    "currency": "N/A",
    "price": "0.00",
    "price_open": "N/A",
    "day_high": "N/A",
    "day_low": "N/A",
    "52_week_high": "N/A",
    "52_week_low": "N/A",
    "day_change": "N/A",
    "change_pct": "N/A",
    "close_yesterday": "N/A",
    "market_cap": "N/A",
    "volume": "N/A",
    "volume_avg": "N/A",
    "shares": "N/A",
    "stock_exchange_long": "Stockholm Stock Exchange",
    "stock_exchange_short": "OMX",
    "timezone": "CET",
    "timezone_name": "Europe/Stockholm",
    "gmt_offset": "3600",
    "last_trade_time": "N/A",
    "pe": "N/A",
    "eps": "N/A"
}

有两种方式: 1.You 创建 GsonAdapter 适配器,例如

class StockDataAdapter: TypeAdapter<StockData> {
   fun read(reader: JsonReader): StockData {
      ....handle actual json parsing here, setting default value to field if parsing failed
    }
}

然后

val gson =GsonBuilder().registerTypeAdapter(StockData.class,  StockDataAdapter()).create();
val stockDataList = gson.fromJson(response.body()!!.asJsonObject.get("data"),
                Array<StockData>::class.java).toList()
  1. 您可以将所有字段设为 String 类型并就地解析实际值,例如

    class 股票数据( val 符号:String?, 验证名称:字符串?, val currency: String?, 有效价格:字符串, @SerializedName("day_change") val dayChange:字符串?, @SerializedName("change_pct") val changePct:字符串, val price90DayHigh:字符串, val price90DayLow:字符串 ) { 瓦尔 priceAsDouble:Double get() = try {price.toDouble()}catch(e:Exception){0.0} }