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

如何用Retrofit解析含未知Key的JSON并转为ArrayList?

解决Retrofit解析动态Key JSON并存入ArrayList的问题

我来帮你搞定这个动态Key JSON解析的难题——之前尝试的方案没出结果,应该是没抓准Retrofit配合Gson处理动态字段的正确方式。下面给你两种直接可用的方案,覆盖大多数常见场景:

方案一:直接用Map接收动态Key,再转成ArrayList

这是最简洁的方法,适合JSON外层全是动态Key的情况(比如下面这种结构):

{
"random_key_1": {"id": 1, "name": "苹果"},
"random_key_2": {"id": 2, "name": "香蕉"},
"random_key_3": {"id": 3, "name": "橙子"}
}

步骤1:定义数据模型类

先写对应每个动态Key内部数据的POJO,比如Goods.java:

public class Goods {
    private int id;
    private String name;

    // 务必添加Getter和Setter方法,或者用Lombok的@Data注解简化
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

步骤2:定义Retrofit接口

把接口的返回类型改成Call<Map<String, Goods>>,让Gson自动把动态Key解析成Map的键:

public interface GoodsApi {
    @GET("goods/list") // 替换成你的实际接口路径
    Call<Map<String, Goods>> getDynamicGoods();
}

步骤3:发起请求并转成ArrayList

在回调里把Map的values()直接转成ArrayList即可:

GoodsApi goodsApi = retrofit.create(GoodsApi.class);
goodsApi.getDynamicGoods().enqueue(new Callback<Map<String, Goods>>() {
    @Override
    public void onResponse(Call<Map<String, Goods>> call, Response<Map<String, Goods>> response) {
        if (response.isSuccessful() && response.body() != null) {
            // 核心操作:把Map的值集合转成ArrayList
            ArrayList<Goods> goodsList = new ArrayList<>(response.body().values());
            // 现在goodsList就是你要的列表,直接用它做后续业务逻辑就行
        } else {
            // 处理请求失败(比如状态码非200)
            Log.e("Retrofit", "请求失败:" + response.message());
        }
    }

    @Override
    public void onFailure(Call<Map<String, Goods>> call, Throwable t) {
        // 处理网络错误
        Log.e("Retrofit", "网络异常:" + t.getMessage());
    }
});

方案二:外层有固定Key,内部嵌套动态Key的情况

如果你的JSON是外层有固定字段,里面才是动态Key(比如下面这种),就需要在外层POJO里用Map接收动态部分:

{
"code": 200,
"msg": "请求成功",
"data": {
"random_key_1": {"id": 1},
"random_key_2": {"id": 2}
}
}

步骤1:定义外层响应类

public class ApiResponse {
    private int code;
    private String msg;
    private Map<String, Goods> data; // 用Map接收动态Key的部分

    // Getter和Setter方法
    public int getCode() { return code; }
    public void setCode(int code) { this.code = code; }
    public String getMsg() { return msg; }
    public void setMsg(String msg) { this.msg = msg; }
    public Map<String, Goods> getData() { return data; }
    public void setData(Map<String, Goods> data) { this.data = data; }
}

步骤2:修改Retrofit接口

返回类型改成Call<ApiResponse>:

public interface GoodsApi {
    @GET("goods/list")
    Call<ApiResponse> getDynamicGoods();
}

步骤3:解析并转成ArrayList

goodsApi.getDynamicGoods().enqueue(new Callback<ApiResponse>() {
    @Override
    public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
        if (response.isSuccessful() && response.body() != null) {
            ApiResponse apiResponse = response.body();
            if (apiResponse.getCode() == 200 && apiResponse.getData() != null) {
                ArrayList<Goods> goodsList = new ArrayList<>(apiResponse.getData().values());
                // 拿到列表做后续操作
            }
        }
    }

    @Override
    public void onFailure(Call<ApiResponse> call, Throwable t) {
        // 处理网络错误
    }
});

关键提醒

确保你的Retrofit实例已经添加了Gson转换器,否则无法自动解析JSON:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://your-base-url.com/") // 替换成你的基础URL
        .addConverterFactory(GsonConverterFactory.create())
        .build();

如果这两种方案还是不行,你可以把具体的JSON结构贴出来,我再帮你调整适配方案~

内容的提问来源于stack exchange,提问作者Siddhesh Pawar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:04:48