如何用Retrofit(GsonConverterFactory)序列化JSON到GetDataResponse数据类?
解决方案
1. 定义基础数据类
先把JSON结构里的固定部分用常规Kotlin数据类定义:
data class GetDataResponse( val id: Int, val result: Result ) data class Result( val list: List<ListItem> ) data class ListItem( val user: User, val id: Int, val changes: Changes ) data class User( val firstName: String, val lastName: String ) data class OldNew( val old: String, val new: String )
2. 解决Changes的混合类型序列化问题
原JSON中changes字段存在两种类型的值:单个OldNew对象(如firstName)、OldNew数组(如emails),这是自动序列化失败的核心原因。我们通过自定义Gson反序列化器来统一处理:
定义Changes类
data class Changes( val changesMap: Map<String, List<OldNew>> )
编写自定义反序列化器
class ChangesDeserializer : JsonDeserializer<Changes> { override fun deserialize( json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext? ): Changes { val changesMap = mutableMapOf<String, List<OldNew>>() json?.asJsonObject?.entrySet()?.forEach { entry -> val key = entry.key val value = entry.value val oldNewList = when { value.isJsonObject -> { // 单个OldNew对象转成单元素列表 listOf(context?.deserialize<OldNew>(value, OldNew::class.java)!!) } value.isJsonArray -> { // 直接解析为OldNew列表 context?.deserialize<List<OldNew>>(value, object : TypeToken<List<OldNew>>() {}.type)!! } else -> emptyList() } changesMap[key] = oldNewList } return Changes(changesMap) } }
3. 配置Gson并关联到Retrofit
把自定义反序列化器注册到Gson实例,再让Retrofit使用这个Gson:
val gson = GsonBuilder() .registerTypeAdapter(Changes::class.java, ChangesDeserializer()) .create() val retrofit = Retrofit.Builder() .baseUrl("你的接口基础URL") .addConverterFactory(GsonConverterFactory.create(gson)) .build() // 创建API服务实例 val apiService = retrofit.create(YourApiService::class.java)
4. 动态展示变更列表的用法
拿到Changes对象后,遍历changesMap即可统一处理所有变更:
// 示例:遍历打印所有变更 changes.changesMap.forEach { (fieldName, oldNewList) -> println("字段:$fieldName") oldNewList.forEach { oldNew -> println(" 旧值:${oldNew.old},新值:${oldNew.new}") } }
这样就能完美适配原JSON的混合结构,实现自动序列化,同时支持动态展示所有变更项。
内容的提问来源于stack exchange,提问作者CookieMonster
相关产品推荐
相关产品推荐

