Dynamically add new subtypes after the original supertype has already been configured in jackson

為{幸葍}努か 提交于 2021-02-10 09:28:12

问题


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 class Field) due to the fact that when you deserialize the same json back to POJO without className property, it will get confused which instance to create, Field, SubField1 or SubField2.
  • 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!