如何反/序列化具有动态类型属性的实例

使用 Jackson 序列化/反序列化 MyClass 实例的最佳方法是什么?


class MyClass {

    private String name;

    private MyInterface classInstance;


    // standard getters setters

}

属性 classInstance 可以是实现接口 MyInterface 的任意类型


理想情况下,我希望 yaml 结构看起来像这样


name: com.example.ClassE

classInstance: 

  value: 42

  category: "fancy"

请注意,“name”属性实际上包含“classInstance”属性内的对象的完全限定类型。


慕斯王
浏览 89回答 1
1回答

ABOUTYOU

检查JsonTypeInfo注释。它可以为您生成class属性并YAML使用此属性反序列化有效负载。检查以下示例:import com.fasterxml.jackson.annotation.JsonTypeInfo;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;import java.math.BigDecimal;public class JsonApp {    public static void main(String[] args) throws Exception {        YAMLFactory yamlFactory = new YAMLFactory();        yamlFactory.disable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID);        ObjectMapper mapper = new ObjectMapper(yamlFactory);        serialiseAndDeserialise(mapper, new MyValue());        serialiseAndDeserialise(mapper, new MyBigDecimal());    }    private static void serialiseAndDeserialise(ObjectMapper mapper, MyInterface myInterface) throws java.io.IOException {        MyClass myClass = new MyClass();        myClass.setInstance(myInterface);        String yaml = mapper.writeValueAsString(myClass);        System.out.println(yaml);        System.out.println(mapper.readValue(yaml, MyClass.class));    }}class MyClass {    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "name")    private MyInterface instance;    public MyInterface getInstance() {        return instance;    }    public void setInstance(MyInterface instance) {        this.instance = instance;    }    @Override    public String toString() {        return "MyClass{" +                "instance=" + instance +                '}';    }}interface MyInterface {}class MyValue implements MyInterface {    private int value = 42;    private String category = "fancy";    public int getValue() {        return value;    }    public void setValue(int value) {        this.value = value;    }    public String getCategory() {        return category;    }    public void setCategory(String category) {        this.category = category;    }    @Override    public String toString() {        return "MyValue{" +                "value=" + value +                ", category='" + category + '\'' +                '}';    }}class MyBigDecimal implements MyInterface {    private BigDecimal pi = BigDecimal.valueOf(Math.PI);    public BigDecimal getPi() {        return pi;    }    public void setPi(BigDecimal pi) {        this.pi = pi;    }    @Override    public String toString() {        return "MyBigDecimal{" +                "pi=" + pi +                '}';    }}上面的代码打印:---instance:  name: "com.celoxity.MyValue"  value: 42  category: "fancy"MyClass{instance=MyValue{value=42, category='fancy'}}---instance:  name: "com.celoxity.MyBigDecimal"  pi: 3.141592653589793MyClass{instance=MyBigDecimal{pi=3.141592653589793}}如果您想移动到与仅更改注释name相同的级别:instance@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "name")输出将变为:---instance:  value: 42  category: "fancy"name: "com.celoxity.MyValue"MyClass{instance=MyValue{value=42, category='fancy'}}---instance:  pi: 3.141592653589793name: "com.celoxity.MyBigDecimal"MyClass{instance=MyBigDecimal{pi=3.141592653589793}}我更喜欢第一个,因为它通知name属性属于instance. 如果您name从注释中删除属性,Jackson则会使用这种类型的默认名称use- '@class'。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java