如何在已自定义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
相关产品推荐
相关产品推荐

