Java 如何使用动态类型化属性反序列化实例
使用Jackson序列化/反序列化MyClass实例的最佳方法是什么Java 如何使用动态类型化属性反序列化实例,java,jackson,yaml,Java,Jackson,Yaml,使用Jackson序列化/反序列化MyClass实例的最佳方法是什么 class MyClass { private String name; private MyInterface classInstance; // standard getters setters } 属性classInstance可以是实现接口MyInterface的任意类型 理想情况下,我希望yaml结构像这样 name: com.example.ClassE classInstance:
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”属性中包含完全限定类型的对象 检查
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.141592653589793
MyClass{instance=MyBigDecimal{pi=3.141592653589793}}
如果要将名称
移动到与实例
相同的级别,请仅将注释更改为:
@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.141592653589793
name: "com.celoxity.MyBigDecimal"
MyClass{instance=MyBigDecimal{pi=3.141592653589793}}
我更喜欢第一个,因为它通知name
属性属于instance
。如果从注释中删除name
属性Jackson
将使用此类的默认名称使用-'@class'
另见: