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

如何在已自定义Jackson反序列化器的情况下反序列化对象数组?

嘿,我来帮你搞定对象数组的反序列化问题!首先先给你的自定义反序列化器补个小细节:记得加上泛型<MyClass>,避免裸类型带来的警告和类型安全问题,调整后的基础版应该是这样:

public static class MyDeserializer extends JsonDeserializer<MyClass> {
    @Override
    public MyClass deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        MyClass obj = new MyClass();
        while (!parser.isClosed()) {
            JsonToken jsonToken = parser.nextToken();
            if (JsonToken.FIELD_NAME.equals(jsonToken)) {
                String fieldName = parser.getCurrentName();
                // 一定要跳到字段值的token,否则会拿不到正确的字段内容
                parser.nextToken();
                // 这里根据你的MyClass字段做对应赋值
                if ("name".equals(fieldName)) {
                    obj.setName(parser.getText());
                } else if ("age".equals(fieldName)) {
                    obj.setAge(parser.getIntValue());
                }
                // 其他字段同理处理
            }
        }
        return obj;
    }
}

接下来,处理MyClass[]数组的反序列化有两种简便方式,选哪种都可以:

方式一:注册单个对象反序列化器,Jackson自动处理数组

Jackson默认会对数组中的每个元素复用对应单个对象的反序列化器,所以你只需要把MyDeserializer注册到ObjectMapper,直接就能反序列化数组了,不用额外写数组的反序列化器:

// 初始化ObjectMapper并注册反序列化器
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(MyClass.class, new MyDeserializer());
mapper.registerModule(module);

// 测试反序列化数组
String arrayJson = "[{\"name\":\"Alice\",\"age\":25},{\"name\":\"Bob\",\"age\":30}]";
MyClass[] myClassArray = mapper.readValue(arrayJson, MyClass[].class);

这种方式最省心,Jackson会帮你遍历数组结构,对每个元素调用你的MyDeserializer。

方式二:用注解指定数组元素的反序列化器

如果你的数组是某个实体类的字段,可以直接在字段上用@JsonDeserialize(contentUsing = ...)指定元素的反序列化器,这样不需要全局注册:

public class ParentEntity {
    // 指定数组里的每个MyClass对象用MyDeserializer处理
    @JsonDeserialize(contentUsing = MyDeserializer.class)
    private MyClass[] myClassList;

    // getter、setter省略
}

之后反序列化ParentEntity的时候,这个数组字段就会自动用你的自定义逻辑处理每个元素。

特殊场景:手动编写数组反序列化器

如果你的JSON数组结构比较特殊(比如不是标准的[{},{}]格式),那你可能需要手动写一个数组专用的反序列化器,复用单个对象的反序列化逻辑:

public static class MyClassArrayDeserializer extends JsonDeserializer<MyClass[]> {
    private final MyDeserializer singleDeserializer = new MyDeserializer();

    @Override
    public MyClass[] deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        List<MyClass> resultList = new ArrayList<>();
        // 跳过数组开始标记
        parser.nextToken();
        // 遍历直到数组结束
        while (!JsonToken.END_ARRAY.equals(parser.currentToken())) {
            // 复用单个对象的反序列化逻辑
            MyClass item = singleDeserializer.deserialize(parser, context);
            resultList.add(item);
        }
        return resultList.toArray(new MyClass[0]);
    }
}

然后把这个数组反序列化器注册到ObjectMapper:

module.addDeserializer(MyClass[].class, new MyClassArrayDeserializer());

不过这种情况比较少见,大部分标准JSON数组用方式一就足够啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:39:56