Jackson无类型字段的递归多态反序列化问题求解
问题根因
你当前的类定义存在2个核心错误,导致Jackson无法通过字段推断出正确的子类:
- 抽象类
AbstractRuleObject中定义了condition、rules、ruleGroups三个冗余字段:Rule类本身不存在condition和rules属性,你将这两个字段放在抽象类中,会让Jackson认为Rule类也可以匹配包含condition的JSON结构,最终两个子类都符合匹配条件,抛出冲突错误;额外的ruleGroups字段在JSON结构中不存在,属于冗余定义,需要删除。 RuleGroup中的rules字段类型定义错误:你定义为List<Rule>,但JSON中rules数组可以嵌套RuleGroup,应该改为List<AbstractRuleObject>才能支持多层嵌套。
修正后的类定义
// 顶层包装类和JSON根结构对应 static class Wrapper { public Condition condition; public List<AbstractRuleObject> rules; } // 抽象父类只放类型推断注解,不要定义任何子类独有的字段 @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION) @JsonSubTypes({ @JsonSubTypes.Type(RuleGroup.class), @JsonSubTypes.Type(Rule.class) }) static abstract class AbstractRuleObject { } // 规则组:只有condition和rules两个字段 static class RuleGroup extends AbstractRuleObject { public Condition condition; // rules元素可以是Rule或者RuleGroup,所以用抽象父类类型 public List<AbstractRuleObject> rules; } // 单条规则:只有业务字段,没有condition和rules static class Rule extends AbstractRuleObject { public String id; public String field; public String type; public String input; public Operator operator; public List<String> value; }
验证说明
修改后Jackson会通过JSON对象的字段自动推断类型:
- 如果JSON对象包含
id/field等字段,自动判定为Rule类型 - 如果JSON对象包含
condition/rules字段,自动判定为RuleGroup类型 - 因为
Rule类不再包含condition/rules字段,不会出现子类匹配冲突的问题,支持最多5层的嵌套结构正常反序列化。
内容的提问来源于stack exchange,提问作者Matthias Nicklisch
相关产品推荐
相关产品推荐

