使用Retrofit2无法解析双层嵌套JSON数据的求助
问题分析
你当前的核心问题是JSON结构与接收类型不匹配:返回的JSON是一个键值对对象(键为USD/EUR等货币代码,值为对应价格数据),但你用List<CurrencyModel>(数组类型)去接收,Gson无法完成解析,自然拿不到数据。
解决方案
推荐使用Map<String, CurrencyModel>来接收数据,这种方式既匹配JSON结构,又能灵活应对新增的货币类型,不需要频繁修改Model类。
1. 修改API接口定义
将返回类型从Call<List<CurrencyModel>>改为Call<Map<String, CurrencyModel>>:
interface CurrencyAPI { @GET("embed/para-birimleri.json") fun getData(): Call<Map<String, CurrencyModel>> }
2. 调整主类的回调逻辑
更新回调的泛型类型,并处理Map数据:
private fun loadData() { val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build() val service = retrofit.create(CurrencyAPI::class.java) val call = service.getData() call.enqueue(object : Callback<Map<String, CurrencyModel>> { override fun onResponse( call: Call<Map<String, CurrencyModel>>, response: Response<Map<String, CurrencyModel>> ) { if (response.isSuccessful) { response.body()?.let { currencyMap -> // 遍历Map获取每个货币的代码和对应数据 currencyMap.forEach { (code, model) -> println("货币代码:$code") println("卖出价:${model.selling}") println("买入价:${model.buying}") println("变动幅度:${model.change}") } // 如果需要将数据转为List存入集合 currencyModels = ArrayList(currencyMap.values) } } else { println("请求失败,状态码:${response.code()}") } } override fun onFailure(call: Call<Map<String, CurrencyModel>>, t: Throwable) { t.printStackTrace() } }) }
备选方案(固定货币类型)
如果确定只会返回USD/EUR两种货币,也可以创建顶层响应Model类,但扩展性较差:
data class CurrencyResponse( @SerializedName("USD") val usd: CurrencyModel, @SerializedName("EUR") val eur: CurrencyModel )
对应的API接口改为:
interface CurrencyAPI { @GET("embed/para-birimleri.json") fun getData(): Call<CurrencyResponse> }
回调中直接获取response.body()?.usd或response.body()?.eur即可。
内容的提问来源于stack exchange,提问作者nicksizadam
相关产品推荐
相关产品推荐

