How To Deserialize Subclasses Using ObjectMapper

Posted By : Pradeep Singh Kushwah | 05-May-2018

Introduction:-In this blog, I will tell you how we can deserialize a JSON to subclass get the List of Parent class. As we know that If Directly deserialize JSON to Java Object it will bind only that class of properties and also we face Problem when we extend an abstract class,because as we know we can't instantiate abstract class. So here is the solution for these problems have to look

For example:- I Have a JSON Like this

       [{
            "id":0123,
                    "model":"Grand Punto",
                    "type":"Car",
                    "modelType":"seedan",
        },
        {
            "id":0156,
                "name":"Hummer",
                "type":"Truck",
                "speed":"70km",
                "capacity": "100 Ton"
        },
        {
            "id":0156,
                "name":"Force 501",
                "type":"Bus",
                "seatingCapacity":"5 person",
        }
]

And have classes like this:

public abstract class Vehicle{
    private int id;
    private String type;
}

public class Car extends Vehicle{
    private String model;
    private String modelType;
}

public class Truck extends Vehicle{
    private String name;
    private String speed;
    private String capacity;
}

public class Bus extends Vehicle{
    private String name;
    private String seatingCapacity;
}

And I want to create a list Vehicle class so that's why I use this Code

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
    List<Vehicle> vehicles = mapper.readValue(JSONString, mapper.getTypeFactory().constructCollectionType(
            List.class, Vehicle.class));
} catch (IOException e) {
    e.printStackTrace();
}

on Execution, it will throw the JsonMappingException,this is because of we can not instantiate abstract class or if you will not create abstract class on that condition objectmapper only map Vehicle class property only so we need to instantiate its concrete classes or make a custom deserializer so I choose first one solution

so I use some Annotations of Jackson for it are as follows:-

1.@JsonTypeInfo it has Three parameters like this

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type") // field name

2.@JsonSubTypes it takes Array of Type like this

@JsonSubTypes({
@JsonSubTypes.Type(value = Car.class, name = "Car"),
@JsonSubTypes.Type(value = Bus.class, name = "Bus"),
@JsonSubTypes.Type(value = Truck.class, name = "Truck")})

So I Annotated Vehicle class Like This

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Car.class, name = "Car"),
        @JsonSubTypes.Type(value = Bus.class, name = "Bus"),
        @JsonSubTypes.Type(value = Truck.class, name = "Truck")})
public abstract class Vehicle{
    private int id;
    private String type;
}

Try Again using code:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
    List<Vehicle> vehicles = mapper.readValue(JSONString, mapper.getTypeFactory().constructCollectionType(
            List.class, Vehicle.class));
} catch (IOException e) {
    e.printStackTrace();
}

It will give the list of Vehicle class but inside that list have three different objects of Car, Bus, and Truck because as we know that Superclass can hold child class Object

 

About Author

Author Image
Pradeep Singh Kushwah

Pradeep is an accomplished Backend Developer with in-depth knowledge and hands-on experience in various cutting-edge technologies. He specializes in Core Java, Spring-Boot, Optaplanner, Angular, and databases such as MongoDB, Neo4j, Redis, and PostgreSQL. Additionally, he has worked with cloud services like AWS and Google Cloud, and he has experience with monitoring tools such as Datadog and Raygun. Pradeep has honed his skills in API Implementations, Integration, optimization, Webservices, Development Testings, and deployments, code enhancements, and has contributed to company values through his deliverables in various client projects, including Kairos, Slick Payroll, Captionlabs, and FarmQ. He is a creative individual with strong analytical skills and a passion for exploring and learning new technologies.

Request for Proposal

Name is required

Comment is required

Sending message..