Reputation: 9
I got a deserialization problem: Trying to convert class which extends parent class. Please find my class below,
public class Base {
Parent parent;
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
-----------------
public class Parent {
String name;
String city;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
-----------------
public class Child extends Parent {
String field;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
}
Main method:
public class TestDeserial {
public static void main(String[] args) {
Child c = new Child();
c.setName("test1");
c.setCity("Mumbai");
c.setField("allow");
Base b = new Base();
b.setParent(c);
// Convert object to json
File file = new File("C:\\temp\\c.json");
try {
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(file, b);
} catch (IOException e) {
e.printStackTrace();
}
// Convert json to object
Base baseResult = null;
try (InputStream in = new FileInputStream("C:\\temp\\c.json")) {
ObjectMapper objMapper = new ObjectMapper();
baseResult = objMapper.readValue(in, Base.class);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
Error: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "field" (class com.mapper.example.Parent), not marked as ignorable (2 known properties: "name", "city"]) at [Source: (FileInputStream); line: 1, column: 52] (through reference chain: com.mapper.example.Base["parent"]->com.mapper.example.Parent["field"])
I don't want to add any annotation in class file.
Upvotes: -1
Views: 909
Reputation: 9408
You need to tell Jackson to use deduction-based inference for determing the appropriate sub-class. Jackson will inspect the fields in the JSON and compare to the fields in the sub-classes.
If you don't want to add annotations to the original classes then you can use mix-ins, e.g.:
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({ @JsonSubTypes.Type(Child.class) })
public abstract class ParentMixin {}
and then just register it with your ObjectMapper (the one used for deserialisation):
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Parent.class, ParentMixin.class);
Upvotes: 1