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

使用Gson反序列化含动态数字键的嵌套JSON对象报错问询

问题根因

你遇到的报错核心原因是JSON结构和实体类定义不匹配:

java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1

你将People字段声明为数组类型,但实际JSON返回的People是对象类型,Gson解析时预期匹配数组起始符[,实际匹配到了对象起始符{,因此抛出异常。同时你的实体类层级也和JSON不匹配:AddressData是People节点的子属性,不是General节点的子属性。


正确实现方案

由于People节点下同时包含动态数字键的用户对象、固定的AddressData对象,我们需要自定义Gson反序列化器处理混合结构,具体步骤如下:

1. 修正实体类定义

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;

// 最外层JSON根节点
public class Root {
    @SerializedName("General")
    @Expose
    private General general;

    public General getGeneral() {
        return general;
    }
}

public class General {
    @SerializedName("Code")
    @Expose
    private String code;
    
    @SerializedName("People")
    @Expose
    private PeopleContainer peopleContainer;

    // 对应数字键的用户对象
    public static class PeopleItem {
        @SerializedName("Name")
        @Expose
        private String name;

        public String getName() {
            return name;
        }
    }

    // 对应地址对象
    public static class AddressData {
        @SerializedName("Street")
        @Expose
        private Integer street;

        @SerializedName("ZIP")
        @Expose
        private Integer zip;

        public Integer getStreet() {
            return street;
        }

        public Integer getZip() {
            return zip;
        }
    }

    // 对应整个People节点的容器
    public static class PeopleContainer {
        private List<PeopleItem> peopleList;
        private AddressData addressData;

        public List<PeopleItem> getPeopleList() {
            return peopleList;
        }

        public AddressData getAddressData() {
            return addressData;
        }

        public void setPeopleList(List<PeopleItem> peopleList) {
            this.peopleList = peopleList;
        }

        public void setAddressData(AddressData addressData) {
            this.addressData = addressData;
        }
    }

    public String getCode() {
        return code;
    }

    public PeopleContainer getPeopleContainer() {
        return peopleContainer;
    }
}

注意:所有内部POJO类需要加static修饰,否则Gson无法实例化非静态内部类。

2. 实现自定义反序列化器

import com.google.gson.Gson;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Map;

public class PeopleContainerDeserializer implements JsonDeserializer<General.PeopleContainer> {
    @Override
    public General.PeopleContainer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject peopleObject = json.getAsJsonObject();
        General.PeopleContainer container = new General.PeopleContainer();
        ArrayList<General.PeopleItem> peopleList = new ArrayList<>();
        Gson gson = new Gson();

        // 遍历People节点的所有键值对
        for (Map.Entry<String, JsonElement> entry : peopleObject.entrySet()) {
            String key = entry.getKey();
            if (key.equals("AddressData")) {
                // 匹配固定地址字段
                General.AddressData addressData = gson.fromJson(entry.getValue(), General.AddressData.class);
                container.setAddressData(addressData);
            } else if (key.matches("\\d+")) {
                // 匹配动态数字键的用户对象
                General.PeopleItem item = gson.fromJson(entry.getValue(), General.PeopleItem.class);
                peopleList.add(item);
            }
        }
        container.setPeopleList(peopleList);
        return container;
    }
}

3. 注册反序列化器并执行解析

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class JsonParseDemo {
    public static void main(String[] args) {
        String jsonStr = "你的完整JSON字符串";
        // 注册自定义反序列化器
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(General.PeopleContainer.class, new PeopleContainerDeserializer())
                .create();
        // 直接解析JSON
        Root root = gson.fromJson(jsonStr, Root.class);
        // 可通过get方法获取对应属性
        General general = root.getGeneral();
        List<General.PeopleItem> people = general.getPeopleContainer().getPeopleList();
        General.AddressData address = general.getPeopleContainer().getAddressData();
    }
}

该方案兼容动态变化的数字键数量,无需修改代码即可适配不同拉取时机返回的用户数量。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 21:15:08