Jackson无类型元数据的多态列表反序列化实现方案咨询
你当前的实现思路是正确的,不需要在序列化时插入Jackson专属的类型元数据,完全可以满足多语言客户端调用API的需求。以下是具体的实现方案:
完善自定义反序列化器
我们可以先将整个JSON节点读取为JsonNode处理,避免受JSON字段顺序的影响,再根据name字段映射到对应的ResourceModel实现类,最后委托Jackson原生的反序列化能力处理列表转换:
public class CollectionExpandDeserializer extends StdDeserializer<CollectionExpand> { // 维护name与对应ResourceModel实现类的映射,新增实现时只需扩展此映射即可 private static final Map<String, Class<? extends ResourceModel>> TYPE_MAPPING = Map.of( "photos", PhotoResourceModel.class, "persons", PersonResourceModel.class ); public CollectionExpandDeserializer() { super(CollectionExpand.class); } @Override public CollectionExpand deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { CollectionExpand collectionExpand = new CollectionExpand(); // 先读取整个节点,无需关心字段顺序 JsonNode rootNode = p.getCodec().readTree(p); // 读取name字段 String name = rootNode.get("name").asText(); collectionExpand.setName(name); // 读取data字段并反序列化 JsonNode dataNode = rootNode.get("data"); if (dataNode != null && dataNode.isArray()) { Class<? extends ResourceModel> targetType = TYPE_MAPPING.get(name); if (targetType != null) { // 构造集合类型,告诉Jackson要反序列化为targetType的List CollectionType listType = ctxt.getTypeFactory() .constructCollectionType(List.class, targetType); List<? extends ResourceModel> dataList = ctxt.readValue(dataNode.traverse(p.getCodec()), listType); collectionExpand.setData(dataList); } else { // 未匹配到类型时的兜底逻辑,可根据业务需求调整,比如置空或抛出异常 collectionExpand.setData(List.of()); } } return collectionExpand; } }
注册反序列化器
有两种注册方式可选:
- 直接在
CollectionExpand类上添加注解,代码侵入性低:
@JsonDeserialize(using = CollectionExpandDeserializer.class) public class CollectionExpand { // 原有类定义不变 }
- 全局注册到
ObjectMapper,无需修改原有类代码:
ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(CollectionExpand.class, new CollectionExpandDeserializer()); objectMapper.registerModule(module);
其他可选方案
如果不想编写全量自定义反序列化器,也可以使用Jackson的@JsonIgnore加额外转换层的方案:先将data字段反序列化为List<Map<String, Object>>或者JsonNode,后续再根据name字段手动转换为对应类型,但这种方式性能和可维护性都不如自定义反序列化器,更推荐前者。
内容的提问来源于stack exchange,提问作者saw303
相关产品推荐
相关产品推荐

