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

如何用Gson/Retrofit处理含未知动态键的API响应POJO映射?

这种动态键的JSON结构确实有点棘手,不过Gson提供了几种简洁的解决方案,我来给你详细说说:

方法1:直接使用Map<Integer, 你的POJO类>

这是最直接的方案,因为Gson可以自动将JSON中的动态整数键映射为Map的键,对应的值则映射为你定义的内部POJO对象。

首先,先定义内部的POJO类(假设你需要解析的对象字段是name和value,你可以根据实际情况修改):

public class Item {
    private String name;
    private int value;

    // 生成构造函数、getter、setter和toString方法
    public Item() {}

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public int getValue() { return value; }
    public void setValue(int value) { this.value = value; }

    @Override
    public String toString() {
        return "Item{name='" + name + "', value=" + value + "}";
    }
}

然后用Gson解析JSON响应:

// 你的API返回的JSON字符串
String jsonResponse = "{ \"29593\": { \"name\": \"Item A\", \"value\": 100 }, \"29594\": { \"name\": \"Item B\", \"value\": 200 }, \"29600\": { \"name\": \"Item C\", \"value\": 300 } }";

Gson gson = new Gson();
// 使用TypeToken获取泛型Map的类型
Type itemMapType = new TypeToken<Map<Integer, Item>>(){}.getType();
Map<Integer, Item> itemMap = gson.fromJson(jsonResponse, itemMapType);

// 遍历Map获取每个对象和对应的ID
for (Map.Entry<Integer, Item> entry : itemMap.entrySet()) {
    int itemId = entry.getKey();
    Item item = entry.getValue();
    System.out.println("对象ID: " + itemId + ", 内容: " + item);
}

这种方法适合只需要关联ID和对象的场景,代码简单,不需要额外的自定义逻辑。

方法2:自定义反序列化器,将ID整合到POJO中

如果你希望把动态的对象ID直接放到POJO对象里(比如给Item类加一个id字段),可以通过自定义JsonDeserializer来实现。

首先修改Item类,添加id字段:

public class Item {
    private int id;
    private String name;
    private int value;

    // 生成构造函数、getter、setter和toString方法
    public Item() {}

    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; }

    public int getValue() { return value; }
    public void setValue(int value) { this.value = value; }

    @Override
    public String toString() {
        return "Item{id=" + id + ", name='" + name + "', value=" + value + "}";
    }
}

然后编写自定义的反序列化器:

import com.google.gson.*;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ItemListDeserializer implements JsonDeserializer<List<Item>> {
    @Override
    public List<Item> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        List<Item> itemList = new ArrayList<>();
        JsonObject jsonObject = json.getAsJsonObject();

        // 遍历JSON中的每个键值对
        for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
            // 将字符串键转为整数ID
            int itemId = Integer.parseInt(entry.getKey());
            // 解析内部的JSON对象为Item实例
            Item item = context.deserialize(entry.getValue(), Item.class);
            // 设置ID
            item.setId(itemId);
            itemList.add(item);
        }

        return itemList;
    }
}

最后注册并使用这个反序列化器:

String jsonResponse = "{ \"29593\": { \"name\": \"Item A\", \"value\": 100 }, \"29594\": { \"name\": \"Item B\", \"value\": 200 }, \"29600\": { \"name\": \"Item C\", \"value\": 300 } }";

Gson gson = new GsonBuilder()
        .registerTypeAdapter(new TypeToken<List<Item>>(){}.getType(), new ItemListDeserializer())
        .create();

List<Item> itemList = gson.fromJson(jsonResponse, new TypeToken<List<Item>>(){}.getType());

// 输出结果
for (Item item : itemList) {
    System.out.println(item);
}

这种方法适合你需要把ID和对象数据放在一起统一处理的场景,后续使用起来更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:44:18