Reputation: 367
I have my own custom deserializer
@Override
public Map<String, Car<?, ?>> deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode carsNode = p.getCodec().readTree(p);
Map<String, Car<?, ?>> CarsMap = new HashMap<String, Car<?, ?>>();
ObjectMapper mapper = new ObjectMapper();
for (JsonNode node : carsNode) {
CarsMap.put(node.get("name").asText(), mapper.readValue(node.asText(), Car.class));
}
return CarsMap;
}
Thought this doesn't work because Car
is a base class and the map should have Map String, SubClasses of Cars)
Input JSON = [{"name": "honda", "type": "Regular , "speed": 60}]
this should be in map such as Map.put("honda", RegularCar.class)
Upvotes: 3
Views: 2701
Reputation: 22244
You may annotate base Car
class to tell Jackson which subclasses to instantiate according to the value of "type"
field in JSON. For example if you have RegularCar
and ClassicCar
extending Car
.
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = RegularCar.class, name = "Regular"),
@JsonSubTypes.Type(value = ClassicCar.class, name = "Classic")
})
class Car {
This would allow you to parse like this:
String json = "{\"name\": \"honda\", \"type\": \"Regular , \"speed\": 60}";
Car car = mapper.readValue(json, Car.class);
where Car car
actually points to a RegularCar
instance. Since the container is declared as Map<String, Car<?, ?>> CarsMap
this is exactly what you want to put
there and then cast appropriately what you get
from the Map
.
Upvotes: 2