杰克逊确定列表字段的子类

时间:2019-12-31 06:30:55

标签: java json jackson

@Data
public class Parent {
    private String type;
    private List<ChildBase> children;
}
public abstract class ChildBase {
    public void someMethod(){};
}
@Data
public class ChildA extents ChildBase {
    private String bar;
}
@Data
public class ChildB extents ChildBase {
    private String foo;
}

然后,原始的json字符串是:

{
  "type": "childA",
  "children": [
    {
       "bar": "baaaar"
    }
  ]
}

我如何反序列化此json字符串,反序列化的对象(实例为Parent),其children字段的实际类型应为ChildA,因为指定了type字段;

在问题use-property-of-parent-object-to-determine-subclass-when-deserializing中,答案打击显示了确定子类的方法,因为它不适用于列表字段

1 个答案:

答案 0 :(得分:0)

对于abstract类,一种方法是创建自定义解串器以实现您想要的目标,如下所示。

因为我不确定JSON数组children中的所有键是否都相同,例如如果barfootype,则所有键分别是{​​{1}}或childA。因此,我使用字段名称来确定应该将JSON对象反序列化到哪个类(childBChildA)。

代码段

ChildB

然后使用class ParentDeserializer extends StdDeserializer<Parent> { public ParentDeserializer() { this(null); } public ParentDeserializer(Class<?> vc) { super(vc); } @Override public Parent deserialize(JsonParser jp, DeserializationContext ctx) throws IOException, JsonProcessingException { JsonNode node = jp.getCodec().readTree(jp); String type = node.get("type").asText(); List<ChildBase> children = new ArrayList<>(); node.get("children").forEach(e -> { if (e.has("bar")) { children.add(new ChildA(e.get("bar").asText())); } if (e.has("foo")) { children.add(new ChildB(e.get("foo").asText())); } }); Parent parent = new Parent(); parent.setType(type); parent.setChildren(children); return parent; } } 直接在类@JsonDeserialize(using = ParentDeserializer.class)上注册反序列化器。

Parent