Android Retrofit如何自定义模型类实现响应数据自动映射至Map
用Retrofit+Gson自动映射指定字段为LinkedHashMap
需求说明
常规使用Retrofit+Gson解析API返回的JSON时,会创建Temperature、Data、Cold、Hot、Widget等对应的数据类。现在需要将Widget改为包含LinkedHashMap<Int, Int>的结构,自动把Hot类的key字段作为Map的键,Cold类的value字段作为Map的值,无需手动循环提取赋值,通过自定义转换器工厂实现自动化处理。
实现步骤
1. 定义目标数据结构
调整Widget为LinkedHashMap<Int, Int>类型,保留必要的层级结构:
data class Temperature( val data: Data ) data class Data( val widget: LinkedHashMap<Int, Int> )
2. 自定义Gson TypeAdapter
编写自定义TypeAdapter处理原JSON中widget节点的解析逻辑,将hot数组的key和cold数组的value映射到LinkedHashMap:
class WidgetMapAdapter : TypeAdapter<LinkedHashMap<Int, Int>>() { override fun write(writer: JsonWriter, map: LinkedHashMap<Int, Int>?) { // 若无需序列化,可跳过此方法;如需序列化则实现对应逻辑 writer.beginObject() map?.forEach { (key, value) -> writer.name(key.toString()).value(value) } writer.endObject() } override fun read(reader: JsonReader): LinkedHashMap<Int, Int> { val resultMap = LinkedHashMap<Int, Int>() val hotKeys = mutableListOf<Int>() reader.beginObject() while (reader.hasNext()) { when (reader.nextName()) { "hot" -> { // 解析hot数组的key字段 reader.beginArray() while (reader.hasNext()) { reader.beginObject() while (reader.hasNext()) { if (reader.nextName() == "key") { hotKeys.add(reader.nextInt()) } else { reader.skipValue() } } reader.endObject() } reader.endArray() } "cold" -> { // 解析cold数组的value字段,与hot的key一一对应 reader.beginArray() var index = 0 while (reader.hasNext()) { reader.beginObject() while (reader.hasNext()) { if (reader.nextName() == "value" && index < hotKeys.size) { resultMap[hotKeys[index]] = reader.nextInt() index++ } else { reader.skipValue() } } reader.endObject() } reader.endArray() } else -> reader.skipValue() } } reader.endObject() return resultMap } }
3. 注册适配器到Gson实例
创建Gson时注册自定义适配器,让Gson识别并使用该解析逻辑:
val customGson = GsonBuilder() .registerTypeAdapter(LinkedHashMap::class.java, WidgetMapAdapter()) .create()
4. 配置Retrofit使用自定义Gson
在Retrofit构建时指定这个自定义Gson实例,替换默认的解析逻辑:
val retrofit = Retrofit.Builder() .baseUrl("你的API基础地址") .addConverterFactory(GsonConverterFactory.create(customGson)) .build()
关键提示
- 上述适配器的解析逻辑基于常见的JSON结构(
widget包含hot和cold两个数组),请根据实际API返回的JSON格式调整字段名和结构判断逻辑。 - 若
hot和cold数组长度不一致,需添加边界处理(比如忽略多余的键或值)。 - 如果需要将
LinkedHashMap序列化为原JSON格式,完善write方法即可。
内容的提问来源于stack exchange,提问作者Ishika Singh
相关产品推荐
相关产品推荐

