You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Retrofit如何正确解析动态键名JSON并解决无法创建converter错误

错误根本原因

你当前的代码存在两个核心错误:

  1. AllLegends类中对同一个all字段重复添加@SerializedName注解,Gson不支持同一字段绑定多个序列化规则,直接触发转换器创建失败。
  2. 对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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 13:27:01