使用Retrofit加载钱包遇JSON格式异常,需设临时值规避错误
解决Retrofit解析Wallet字段类型不匹配的异常问题
你的问题核心是:接口返回的wallet字段可能是对象、空数组或空字符串,但你的实体类定义的是Wallet对象类型,导致Retrofit解析时直接抛出java.lang.IllegalStateException——因为解析器期望对象,却收到了数组/字符串。你之前的代码没用是因为异常发生在Retrofit解析响应的阶段,还没走到你判断data.wallet == null的逻辑就报错了。
下面提供两种可行的解决方案:
方案一:自定义Gson TypeAdapter(推荐)
给Wallet类自定义解析适配器,在解析时捕获类型不匹配的异常,直接返回默认值。
步骤1:编写TypeAdapter
class WalletTypeAdapter : TypeAdapter<Wallet>() { override fun write(out: JsonWriter, value: Wallet?) { // 序列化逻辑(如果不需要自定义,用默认Gson序列化即可) Gson().toJson(value, Wallet::class.java, out) } override fun read(`in`: JsonReader): Wallet { return try { // 尝试正常解析为Wallet对象 Gson().fromJson(`in`, Wallet::class.java) } catch (e: JsonSyntaxException) { // 解析失败(说明是数组/空字符串等非对象类型),跳过错误值并返回默认Wallet `in`.skipValue() Wallet(subscriberId = 0, currentBalance = "0.00") } } }
步骤2:注册Adapter到Gson并配置Retrofit
创建Gson实例时注册这个适配器,再传给Retrofit的ConverterFactory:
val customGson = GsonBuilder() .registerTypeAdapter(Wallet::class.java, WalletTypeAdapter()) .create() val retrofit = Retrofit.Builder() .baseUrl(YOUR_BASE_URL) .addConverterFactory(GsonConverterFactory.create(customGson)) // 其他配置(如OkHttpClient) .build()
这样,当接口返回wallet为数组或空字符串时,适配器会自动处理并返回默认的Wallet对象,不会抛出解析异常,后续你的业务逻辑可以正常执行。
方案二:将Wallet字段改为JsonElement手动解析
修改实体类的wallet字段类型为JsonElement,在解析后手动判断类型并处理:
步骤1:修改响应实体类
data class WalletResponse( val wallet: JsonElement? ) data class Wallet( val subscriberId: Long, val currentBalance: String )
步骤2:在业务逻辑中手动解析
.suspendOnSuccess { val targetWallet = when { // 处理null或空值 data.wallet == null || data.wallet.isJsonNull -> Wallet(0, "0.00") // 正常对象类型,解析为Wallet data.wallet.isJsonObject -> { val jsonObj = data.wallet.asJsonObject Wallet( subscriberId = jsonObj.get("subscriberId").asLong, currentBalance = jsonObj.get("currentBalance").asString ) } // 数组或其他非法类型,返回默认值 else -> Wallet(0, "0.00") } // 这里可以根据需要转换为业务模型,或者直接使用targetWallet emit(targetWallet) }
这种方式不需要自定义适配器,但需要手动处理解析逻辑,适合快速临时解决问题。
内容的提问来源于stack exchange,提问作者denver
相关产品推荐
相关产品推荐

