Retrofit如何正确解析动态键名JSON并解决无法创建converter错误
错误根本原因
你当前的代码存在两个核心错误:
AllLegends类中对同一个all字段重复添加@SerializedName注解,Gson不支持同一字段绑定多个序列化规则,直接触发转换器创建失败。- 对JSON结构理解错误:
legends.all对应的不是单个固定英雄对象,是键为英雄名称、值为英雄详情的动态Map集合,另外ImgAssets是嵌套对象,你定义成String类型也会触发类型不匹配错误。
正确数据类定义
// 通用图片资源结构 data class ImgAssets( val icon: String, val banner: String ) // 排名信息结构:rankPos和topPercent可能返回数字或字符串"NOT_CALCULATED_YET",统一用String接收 data class RankInfo( val rankPos: String, val topPercent: String ) // 英雄数据单条结构 data class LegendDataItem( val name: String, val value: Int, val key: String, val rank: RankInfo, val rankPlatformSpecific: RankInfo ) // 通用英雄详情结构:data字段可空,适配没有数据统计的英雄 data class LegendDetail( val data: List<LegendDataItem>? = null, val ImgAssets: ImgAssets ) // Legends根结构:all字段用Map接收动态英雄key data class AllLegends( @SerializedName("all") val all: Map<String, LegendDetail> ) // 顶层返回结构:如果返回结果中没有global字段,需要把global属性设为可空避免解析失败 data class TestHero ( @SerializedName("global") val global: PlayerInf? = null, @SerializedName("legends")val legends: AllLegends ) // 其余你自定义的PlayerInf、BanInf、RankInf结构如果和返回字段匹配可以保留 data class PlayerInf ( val name: String, val uid: Long, val avatar: String, val platform: String, val level: Int, val toNextLevelPercent: Int, val internalUpdateCount: Int, val bans: BanInf, val rank: RankInf ) data class BanInf ( val isActive: Boolean, val remainingSeconds: Int ) data class RankInf ( val rankScore: Int, val rankName: String, val rankDiv: Int, val rankImg: String )
使用说明
解析完成后,你可以通过英雄名作为key直接从all集合中取对应英雄的详情:
- 取亡灵信息:
legends.all["Revenant"] - 取恶灵信息:
legends.all["Wraith"] - 没有统计数据的英雄
data字段会自动赋值为null,不会触发解析异常
内容的提问来源于stack exchange,提问作者Ethernets
相关产品推荐
相关产品推荐

