使用Moshi反序列化Cryptocompare API嵌套JSON对象时遇到问题
解决Moshi反序列化嵌套动态键JSON的问题
我帮你梳理下这个问题的解决思路,核心是处理返回结果里动态键名的嵌套结构(比如DISPLAY下的1337、007这些加密货币代号),Moshi对这种场景有很直接的处理方式:
1. 定义对应的数据类
根据JSON结构,我们可以用Map来承接动态变化的键名,同时给固定字段的层级定义数据类:
首先是最内层的货币详情类(对应EUR/USD下的对象):
import com.squareup.moshi.Json data class CurrencyDisplay( @Json(name = "FROMSYMBOL") val fromSymbol: String, @Json(name = "TOSYMBOL") val toSymbol: String // 把你需要的其他字段都加在这里,比如PRICE、CHANGE24HOUR等 )
然后是外层的响应类,用Map来处理动态的加密货币代号和目标货币键:
data class CryptoPriceFullResponse( val RAW: Map<String, Any?>?, // 既然不用这个字段,用Map接收或者标记@Transient忽略都行 val DISPLAY: Map<String, Map<String, CurrencyDisplay>> )
这里DISPLAY的类型是Map<String, Map<String, CurrencyDisplay>>:
- 第一层key是加密货币代号(比如
1337、007) - 第二层key是目标货币(比如
EUR、USD) - 最终对应到我们定义的
CurrencyDisplay实体类
2. 执行反序列化
用Moshi构建适配器,直接解析即可:
import com.squareup.moshi.Moshi val moshi = Moshi.Builder().build() val responseAdapter = moshi.adapter(CryptoPriceFullResponse::class.java) // 假设你已经获取到了API返回的JSON字符串 val response = responseAdapter.fromJson(jsonResponseString) // 示例:获取1337的EUR数据 val display1337EUR = response?.DISPLAY?.get("1337")?.get("EUR") println(display1337EUR?.fromSymbol) // 输出1337
额外说明
- 如果你需要更类型安全的目标货币处理(比如只固定EUR、USD),也可以把第二层的Map换成实体类:
data class TargetCurrencyDisplays( val EUR: CurrencyDisplay?, val USD: CurrencyDisplay? ) // 然后DISPLAY的类型改成Map<String, TargetCurrencyDisplays> - 关于你提到的
TOSYMBOL返回乱码鈧�,这个大概率是API返回的编码问题(比如原符号是特殊字符,传输时编码错误),你可以先检查API返回的原始响应编码,或者在拿到toSymbol后做字符串编码转换处理。
内容的提问来源于stack exchange,提问作者 ""MARKET"":""CryptoCompare Index""
相关产品推荐
相关产品推荐

