@Data
public class Parent {
private String type;
private List<ChildBase> children;
}
public abstract class ChildBase {
public void someMethod(){};
}
@Data
public class ChildA extends ChildBase {
private String bar;
}
@Data
public class ChildB extends ChildBase {
private String foo;
}
Then, the original JSON string is:
{
"type": "childA",
"children": [
{
"bar": "baaaar"
}
]
}
How can I deserialize this JSON string, the deserialized object(instance of Parent
), its children
field's actual type should be ChildA
, because the type
field specified;
In the question use-property-of-parent-object-to-determine-subclass-when-deserializing , the answer blow shows the way to determine subclass, by it doesn't work with a list field.
For abstract
class, one way is to create a custom deserializer to achieve what you want as follows.
Because I am not sure whether all the keys in JSON array children
are going to be identical, eg all the keys are bar
or foo
if the type
is childA
or childB
, respectively. Therefore, I use the field name to determine the JSON object is supposed to be deserialized to which class ( ChildA
or ChildB
).
Code snippet
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;
}
}
Then use @JsonDeserialize(using = ParentDeserializer.class)
to register the deserializer directly on the class Parent
.
@JsonDeserialize(using = ParentDeserializer.class)
class Parent {
...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.