#java #inheritance #jackson #jackson-databind
#java #наследование #джексон #jackson-databind
Вопрос:
У меня есть один суперкласс Field
и есть два других класса, которые наследуют суперкласс Field
.
Я хочу динамически добавлять подкласс, не влияя на изменения суперкласса
public class TestConfiguration {
private List<Field> fields;
}
Я хочу использовать сопоставление таким образом, когда fields является экземпляром того же класса Field, тогда без свойства className «Field», используемого для сопоставления
{
"fields" : [ {
"name" : "First_name",
"type" : {
"fieldType" : {
"name" : "string"
}
},
"required" : true
}]
}
Я хочу использовать сопоставление таким образом, когда fields является экземпляром дочернего класса ExtendedHierarchicalField, тогда свойство className «ExtendedHierarchicalField» используется для сопоставления или любым другим способом для сопоставления объектов
{
"fields" : [ {
"className" : "ExtendedHierarchicalField",
"name" : "First_name",
"type" : {
"fieldType" : {
"name" : "string"
}
},
"required" : true
}]
}
Ответ №1:
Вы можете добиться того же, используя аннотации jackson.
Определите свои классы как:
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;
}
основной метод
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);
}
Вывод:
{
"fields" : [ {
"className" : ".Field",
"name" : "main field"
}, {
"className" : ".SubField1",
"name" : "sub field 1",
"subField1Property" : "subField1Property value"
}, {
"className" : ".SubField2",
"name" : "sub field 2",
"subField2Property" : "subField2Property value"
} ]
}
Примечание:
className
свойство является своего рода обязательным (даже для класса верхнего уровняField
) из-за того, что при десериализации того же json обратно вPOJO
безclassName
свойства будет запутано, какой экземпляр создавать,Field
,SubField1
илиSubField2
.- Я использовал общедоступные свойства в
POJO
для простоты. Вы должны предпочесть закрытые поля только с установщиком / получателем.