问题
I have one super class Field
and there are two other classes that inherit the super class Field
.
I want to dynamically add subclass without affecting super class changes
public class TestConfiguration {
private List<Field> fields;
}
I want to use the mapping in this way when fields is instance of same class Field then without className property "Field" used for mapping
{
"fields" : [ {
"name" : "First_name",
"type" : {
"fieldType" : {
"name" : "string"
}
},
"required" : true
}]
}
I want to use the mapping in this way when fields is instance of child class ExtendedHierarchicalField then className property "ExtendedHierarchicalField" used for mapping or any other way for mapping the objects
{
"fields" : [ {
"className" : "ExtendedHierarchicalField",
"name" : "First_name",
"type" : {
"fieldType" : {
"name" : "string"
}
},
"required" : true
}]
}
回答1:
You can achieve the same using jackson annotations.
Define your classes as:
Field.java
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, property = "className")
@JsonSubTypes({
@JsonSubTypes.Type(value = SubField1.class),
@JsonSubTypes.Type(value = SubField2.class)
})
public class Field {
public String name;
}
SubField1.java
public class SubField1 extends Field {
public String subField1Property = "subField1Property value";
}
SubField2.java
public class SubField2 extends Field {
public String subField2Property = "subField2Property value";
}
TestConfiguration.java
public class TestConfiguration {
public List<Field> fields;
}
main method
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Field field = new Field();
field.name = "main field";
Field subField1 = new SubField1();
subField1.name = "sub field 1";
Field subField2 = new SubField2();
subField2.name = "sub field 2";
TestConfiguration testConfiguration = new TestConfiguration();
testConfiguration.fields = Arrays.asList(field, subField1, subField2);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(testConfiguration);
System.out.println(json);
}
Output:
{
"fields" : [ {
"className" : ".Field",
"name" : "main field"
}, {
"className" : ".SubField1",
"name" : "sub field 1",
"subField1Property" : "subField1Property value"
}, {
"className" : ".SubField2",
"name" : "sub field 2",
"subField2Property" : "subField2Property value"
} ]
}
Note:
className
property is kind of mandatory (even for top level classField
) due to the fact that when you deserialize the same json back toPOJO
withoutclassName
property, it will get confused which instance to create,Field
,SubField1
orSubField2
.- I used public properties in
POJO
for ease. You should prefer private fields with setter / getter only.
来源:https://stackoverflow.com/questions/63612597/dynamically-add-new-subtypes-after-the-original-supertype-has-already-been-confi