深入分析Jackson的@JsonTypeInfo与@JsonSubTypes
在Java的序列化与反序列化过程中,Jackson库提供了强大的功能来处理复杂的数据范例,尤其是在处理多态时。本文将具体探究@JsonTypeInfo和@JsonSubTypes注解的利用,并通过一个实例来展示如安在Jackson中利用这些注解。配景知识
在JSON序列化过程中,如果利用Java类的全限定名作为范例标识符,这在非Java客户端消费序列化后的JSON时可能不是一个好的选择。为相识决这个题目,我们可以利用"逻辑范例名称"作为范例标识符。
利用@JsonTypeInfo与@JsonSubTypes
@JsonTypeInfo注解用于指定如何序列化和反序列化范例信息。当设置use = JsonTypeInfo.Id.NAME时,范例名称将被用作范例标识符。为了将这个名称分析为实际的具体范例,我们必要利用@JsonSubTypes注解。
实例分析
假设我们有一个Shape抽象类,它有两个子类Rectangle和Circle。我们希望在序列化时利用逻辑范例名称,而不是Java类的全限定名。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes({
@JsonSubTypes.Type(value = Rectangle.class),
@JsonSubTypes.Type(value = Circle.class)
})
public abstract class Shape { }
@JsonTypeName("rectangle")
public class Rectangle extends Shape {
private int w;
private int h;
// 构造函数和getter/setter省略
}
@JsonTypeName("circle")
public class Circle extends Shape {
private int radius;
// 构造函数和getter/setter省略
}
public class View {
private List<Shape> shapes;
// 构造函数和getter/setter省略
}
序列化与反序列化示例
在ExampleMain类中,我们创建了一个View对象,其中包罗Rectangle和Circle对象的列表。然后利用ObjectMapper进行序列化和反序列化。
public class ExampleMain {
public static void main(String[] args) throws IOException {
View v = new View();
v.setShapes(new ArrayList<>(List.of(Rectangle.of(3, 6), Circle.of(5))));
System.out.println("-- serializing --");
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(v);
System.out.println(s);
System.out.println("-- deserializing --");
View view = om.readValue(s, View.class);
System.out.println(view);
}
}
输出结果
序列化输出:
{"shapes":[{"@type":"rectangle","w":3,"h":6},{"@type":"circle","radius":5}]}
反序列化输出:
View{shapes=}
自定义范例属性名称
如果我们想要自定义范例属性的名称,而不是利用默认的@type,可以通过property元向来指定。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "typeName")
...
这将序列化输出为:
{"shapes":[{"typeName":"rectangle","w":3,"h":6},{"typeName":"circle","radius":5}]}
利用范例包装器
除了JsonTypeInfo.As.PROPERTY,我们还可以利用JsonTypeInfo.As.WRAPPER_OBJECT或JsonTypeInfo.As.WRAPPER_ARRAY来包装范例信息。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
...
这将序列化输出为:
{"shapes":[{"rectangle":{"w":3,"h":6}},{"circle":{"radius":5}}]}
项目依赖和技术
[*]jackson-databind 2.9.6: Jackson的核心数据绑定功能。
[*]JDK 10
[*]Maven 3.3.9
通过本文的分析,我们可以看到@JsonTypeInfo和@JsonSubTypes在处理多态和范例安全方面的告急作用。希望这个实例能够帮助你更好地明确和利用这些注解。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]