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

如何将JSON反序列化为带嵌套泛型的Java对象?

完全可以解决这个问题!不管是用Gson还是Jackson,我们都能通过自定义反序列化逻辑,把JSON里的扁平值适配到你的嵌套包装类里。下面分别给你两种框架的实现方案:

Gson 解决方案

核心思路是为BaseModel<T>和BaseListModel<T>编写自定义反序列化器,让Gson知道如何把单个JSON值/数组转换成对应的包装类实例。

1. 编写BaseModel通用反序列化器

这个反序列化器会直接把JSON中的单个值包装成BaseModel对象:

public class BaseModelDeserializer<T> implements JsonDeserializer<BaseModel<T>> {
    private final Type valueType;

    public BaseModelDeserializer(Type valueType) {
        this.valueType = valueType;
    }

    @Override
    public BaseModel<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        // 直接将JSON值反序列化为泛型类型,再包装进BaseModel
        T value = context.deserialize(json, valueType);
        return new BaseModel<>(value);
    }
}

2. 编写BaseListModel通用反序列化器

针对数组类型的JSON值,我们需要把它转换成List<T>后再包装进BaseListModel:

public class BaseListModelDeserializer<T> implements JsonDeserializer<BaseListModel<T>> {
    private final Type elementType;

    public BaseListModelDeserializer(Type elementType) {
        this.elementType = elementType;
    }

    @Override
    public BaseListModel<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        // 先把JSON数组反序列化为List<T>
        List<T> valueList = context.deserialize(json, TypeToken.getParameterized(List.class, elementType).getType());
        BaseListModel<T> model = new BaseListModel<>();
        model.setValue(valueList);
        return model;
    }
}

3. 配置Gson并完成反序列化

注意:JSON中的字段是"ID"(大写开头),而你的POJO字段是id(小写),需要在MyObject类的id字段上添加@SerializedName("ID")注解来匹配,或者在GsonBuilder中配置字段命名策略。

// 先修改MyObject类添加注解
public class MyObject {
    @SerializedName("ID")
    private BaseModel<Integer> id;
    private BaseModel<String> title;
    private BaseListModel<Integer> numbers;
    // 可添加getter/setter,Gson默认可访问私有字段
}

// 主类中的反序列化代码
public class Main {
    public static void main(String[] args) {
        String json = "[{\"ID\":1,\"title\":\"title1\",\"numbers\":[1,2]},{\"ID\":2,\"title\":\"title2\",\"numbers\":[10,20]}]";

        Gson gson = new GsonBuilder()
                // 注册BaseModel<Integer>的反序列化器(对应id字段)
                .registerTypeAdapter(TypeToken.getParameterized(BaseModel.class, Integer.class).getType(),
                        new BaseModelDeserializer<>(Integer.class))
                // 注册BaseModel<String>的反序列化器(对应title字段)
                .registerTypeAdapter(TypeToken.getParameterized(BaseModel.class, String.class).getType(),
                        new BaseModelDeserializer<>(String.class))
                // 注册BaseListModel<Integer>的反序列化器(对应numbers字段)
                .registerTypeAdapter(TypeToken.getParameterized(BaseListModel.class, Integer.class).getType(),
                        new BaseListModelDeserializer<>(Integer.class))
                .create();

        List<MyObject> myObjects = gson.fromJson(json, new TypeToken<List<MyObject>>(){}.getType());

        // 测试输出验证结果
        for (MyObject obj : myObjects) {
            System.out.println("ID: " + obj.id.getValue());
            System.out.println("Title: " + obj.title.getValue());
            System.out.println("Numbers: " + obj.numbers.getValue());
        }
    }
}
Jackson 解决方案

Jackson同样可以通过自定义反序列化器实现需求,步骤和Gson类似:

1. 编写BaseModel反序列化器

public class BaseModelDeserializer<T> extends StdDeserializer<BaseModel<T>> {
    private final JavaType valueType;

    public BaseModelDeserializer(JavaType valueType) {
        super(BaseModel.class);
        this.valueType = valueType;
    }

    @Override
    public BaseModel<T> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        T value = ctxt.readValue(p, valueType);
        return new BaseModel<>(value);
    }
}

2. 编写BaseListModel反序列化器

public class BaseListModelDeserializer<T> extends StdDeserializer<BaseListModel<T>> {
    private final JavaType listType;

    public BaseListModelDeserializer(JavaType elementType, DeserializationContext ctxt) {
        super(BaseListModel.class);
        this.listType = ctxt.getTypeFactory().constructCollectionType(List.class, elementType);
    }

    @Override
    public BaseListModel<T> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        List<T> list = ctxt.readValue(p, listType);
        BaseListModel<T> model = new BaseListModel<>();
        model.setValue(list);
        return model;
    }
}

3. 配置ObjectMapper并反序列化

Jackson可以通过配置开启大小写不敏感匹配,来处理"ID"和id的字段名差异:

public class Main {
    public static void main(String[] args) throws IOException {
        String json = "[{\"ID\":1,\"title\":\"title1\",\"numbers\":[1,2]},{\"ID\":2,\"title\":\"title2\",\"numbers\":[10,20]}]";

        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        TypeFactory typeFactory = mapper.getTypeFactory();

        // 注册各泛型类型的反序列化器
        module.addDeserializer(typeFactory.constructParametricType(BaseModel.class, Integer.class),
                new BaseModelDeserializer<>(typeFactory.constructType(Integer.class)));
        module.addDeserializer(typeFactory.constructParametricType(BaseModel.class, String.class),
                new BaseModelDeserializer<>(typeFactory.constructType(String.class)));
        module.addDeserializer(typeFactory.constructParametricType(BaseListModel.class, Integer.class),
                new BaseListModelDeserializer<>(typeFactory.constructType(Integer.class), mapper.getDeserializationContext()));

        mapper.registerModule(module);
        // 开启字段名大小写不敏感匹配,解决JSON中"ID"和POJO中"id"的差异
        mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);

        List<MyObject> myObjects = mapper.readValue(json, new TypeReference<List<MyObject>>(){});

        // 测试输出验证结果
        for (MyObject obj : myObjects) {
            System.out.println("ID: " + obj.id.getValue());
            System.out.println("Title: " + obj.title.getValue());
            System.out.println("Numbers: " + obj.numbers.getValue());
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:38:16