如何在Retrofit中构建适配动态请求的响应数据模型?
处理Retrofit中动态键的JSON响应
针对这种顶级键随请求参数动态变化的JSON结构,最直接高效的方案是用Map来接收响应,完全适配动态键的场景,比JsonObject好用得多。
1. 定义Retrofit接口
直接把响应类型声明为Map<String, Map<String, Double>>(如果接口返回的价格存在字符串格式,可把Double换成String):
// Kotlin示例 interface CoinGeckoApi { @GET("simple/price") suspend fun getCoinPrices( @Query("ids") coinIds: String, // 传入格式如"bitcoin,cardano,dogecoin" @Query("vs_currencies") vsCurrencies: String // 传入格式如"usd,eth" ): Response<Map<String, Map<String, Double>>> }
// Java示例 public interface CoinGeckoApi { @GET("simple/price") Call<Map<String, Map<String, Double>>> getCoinPrices( @Query("ids") String coinIds, @Query("vs_currencies") String vsCurrencies ); }
2. 解析响应
拿到Map后,就能通过币种ID和目标币种直接获取价格:
// Kotlin调用示例 val response = coinGeckoApi.getCoinPrices("bitcoin,cardano", "usd,eth") if (response.isSuccessful) { val priceMap = response.body() // 获取Bitcoin对USD的价格 val btcUsdPrice = priceMap?.get("bitcoin")?.get("usd") // 获取Cardano对ETH的价格 val adaEthPrice = priceMap?.get("cardano")?.get("eth") }
3. 进阶封装(可选)
如果想让代码更具可读性,可以封装一个数据类,再结合Map使用:
data class CoinPrice( val prices: Map<String, Double> // key是目标币种,比如usd/eth ) // 接口修改为 interface CoinGeckoApi { @GET("simple/price") suspend fun getCoinPrices( @Query("ids") coinIds: String, @Query("vs_currencies") vsCurrencies: String ): Response<Map<String, CoinPrice>> } // 调用时 val adaPrice = priceMap?.get("cardano")?.prices?.get("usd")
这种方式完全适配动态键场景,不用写复杂的自定义解析器,Retrofit搭配Gson/Moshi等序列化库会自动处理Map的序列化/反序列化。
内容的提问来源于stack exchange,提问作者amir nourafkan
相关产品推荐
相关产品推荐

