杰克逊:如何反序列化嵌套的自定义地图和列表?

时间:2017-01-05 18:00:02

标签: java list dictionary jackson

我正在尝试将无类型的JSON文件反序列化为Map接口的自定义实现 此自定义地图实现只能包含java简单类型(DateStringIntegerLong)和嵌套类型(嵌套映射的自定义映射实现和自定义列表实现)嵌套数组或列表)

我尝试了以下内容:

CustomMap map = mapper.readValue(myJsonFile, CustomMap.class);

我得到了预期的类型,除了嵌套映射,我得到HashMap类型,对于嵌套数组,我得到ArrayList类型。

我认为Jackson对于未知类型的HashMap和对于数组的ArrayList都会有所收回。

对于未知的子类型,是否可以递归回退到CustomMap而不是HashMap,对于数组是CustomList

提前致谢

2 个答案:

答案 0 :(得分:2)

您可以通过在地图工具上创建并注册SimpleModule来实现此目的。这样可以更改您案例中Map的类型映射以及List等其他类型。 E.g。

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("CustomCollections", Version.unknownVersion());
module.addAbstractTypeMapping(Map.class, CustomMap.class);
module.addAbstractTypeMapping(List.class, CustomList.class);
mapper.registerModule(module);

您可能需要像这样致电readValue

Map<String, Object> data = mapper.readValue(myJsonFile, new TypeReference<CustomMap<String, Object>>() {});

请注意,这在Jackson 2.6.0及更高版本中有效,因为之前有bug

此外,杰克逊默认为LinkedHashMap Map而不是HashMap,以维护JSON文档中的数据顺序。

答案 1 :(得分:1)

Manos提出的解决方案,在我的情况下,由于缺少方法的实现,我需要为CustomList添加自定义反序列化器。

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("CustomCollections", Version.unknownVersion());
module.addAbstractTypeMapping(Map.class, CustomMap.class);
module.addAbstractTypeMapping(List.class, CustomList.class);
module.addDeserializer(CustomList.class, new CustomListDeserializer());
mapper.registerModule(module);