如何通过Retrofit获取含动态Key的API响应?
Retrofit解析含动态Key的响应解决方案
方法一:直接用Map接收动态字段
如果你的响应是固定外层结构+内层动态Key(比如外层有code、message这类固定字段,内层数据是动态键值对),直接把对应动态字段的类型改成Map即可。
假设响应结构如下:
{
"code": 200,
"message": "success",
"data": {
"dynamic_1": {"id": 1, "content": "msg1"},
"dynamic_2": {"id": 2, "content": "msg2"}
}
}
修改ReadMessagesResponse类:
public class ReadMessagesResponse { private int code; private String message; // 用Map接收动态Key的部分,泛型值为动态Key对应的固定结构类 private Map<String, MessageItem> data; // getter、setter方法 public static class MessageItem { private int id; private String content; // getter、setter方法 } }
之后ApiInterface正常定义返回Call<ReadMessagesResponse>,调用接口时Gson会自动将动态Key解析为Map的键值对。
方法二:自定义Gson TypeAdapter(复杂动态结构)
如果整个响应的Key几乎都是动态的,或者需要更灵活的解析逻辑,就需要自定义TypeAdapter手动处理解析流程:
- 编写自定义TypeAdapter类:
public class DynamicResponseAdapter extends TypeAdapter<ReadMessagesResponse> { @Override public void write(JsonWriter out, ReadMessagesResponse value) throws IOException { // 若不需要序列化,此方法留空即可 } @Override public ReadMessagesResponse read(JsonReader in) throws IOException { ReadMessagesResponse response = new ReadMessagesResponse(); Map<String, MessageItem> dynamicData = new HashMap<>(); in.beginObject(); while (in.hasNext()) { String key = in.nextName(); // 区分固定字段和动态字段 switch (key) { case "code": response.setCode(in.nextInt()); break; case "message": response.setMessage(in.nextString()); break; default: // 解析动态Key对应的对象 MessageItem item = new Gson().fromJson(in, MessageItem.class); dynamicData.put(key, item); break; } } in.endObject(); response.setData(dynamicData); return response; } }
- 在RetrofitClient中注册该适配器:
Gson customGson = new GsonBuilder() .registerTypeAdapter(ReadMessagesResponse.class, new DynamicResponseAdapter()) .create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create(customGson)) .build();
- 正常调用API即可,Retrofit会使用自定义适配器完成动态Key的解析。
排查要点
如果你之前尝试StackOverflow方案失败,可检查以下几点:
- 动态Key对应的实体类
MessageItem字段是否和JSON结构完全匹配,必要时用@SerializedName注解做字段映射 - TypeAdapter中是否正确区分了固定字段和动态字段,解析动态对象时的类型是否正确
- Map的泛型键类型是否和JSON中的动态Key类型一致(比如动态Key是数字的话,用
Integer而非String)
内容的提问来源于stack exchange,提问作者Faizan Ahmad
相关产品推荐
相关产品推荐

