有时,一张表里面存储的具体对象可能不一样,比如Person表,里面我存了man和woman,除去共有属性如姓名,年龄,性别等,可能还有一些属性不一样,针对man,woman又有不同的其他业务处理等,此时,新增或者修改接口我们都是用的同一个,如果传一个具体的对象避免不了要做各种判断逻辑,代码太冗余,那如何直接传顶层的抽象类(Person)呢?这就涉及到了一个多态的处理~ 这就是本文的主角Jackson框架
jackson允许配置多态类型处理,当进行反序列话时,JSON数据匹配的对象可能有多个子类型,为了正确的读取对象的类型,我们需要添加一些类型信息。可以通过下面几个注解来实现:
@JsonTypeInfo
作用于类/接口,被用来开启多态类型处理,对基类/接口和子类/实现类都有效
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "partner", visible = true, defaultImpl = Man.class)
属性介绍:
JsonTypeInfo.Id.CLASS
:使用完全限定类名做识别JsonTypeInfo.Id.MINIMAL_CLASS
:若基类和子类在同一包类,使用类名(忽略包名)作为识别码JsonTypeInfo.Id.NAME
:一个合乎逻辑的指定名称JsonTypeInfo.Id.CUSTOM
:自定义识别码,由@JsonTypeIdResolver
对应,稍后解释JsonTypeInfo.Id.NONE
:不使用识别码use
为JsonTypeInfo.Id.CLASS
(若不指定property则默认为@class
)、JsonTypeInfo.Id.MINIMAL_CLASS
(若不指定property则默认为@c
)、JsonTypeInfo.Id.NAME
(若不指定property默认为@type
),include
为JsonTypeInfo.As.PROPERTY
、JsonTypeInfo.As.EXISTING_PROPERTY
、JsonTypeInfo.As.EXTERNAL_PROPERTY
时才有效defaultImpl
(可选):如果类型识别码不存在或者无效,可以使用该属性来制定反序列化时使用的默认类型@JsonSubTypes
作用于类/接口,用来列出给定类的子类,只有当子类类型无法被检测到时才会使用它,一般是配合@JsonTypeInfo在基类上使用,比如:
- @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "partner", visible = true, defaultImpl = Man.class)
- @JsonSubTypes({
- @JsonSubTypes.Type(value = Man.class, name = "wife"),
- @JsonSubTypes.Type(value = Woman.class, name = "husband")
- })
@JsonTypeName
作用于子类,用来为多态子类指定类型标识符的值,使用该注解则可以不使用@JsonSubTypes
比如:
- @JsonTypeName("husband")
- public class Woman extends Person {...}
- @JsonTypeName("wife")
- public class Man extends Person {...}
依赖:
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- <version>2.13.3</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>2.13.3</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.13.3</version>
- </dependency>
- package com.cjian.jackson;
-
- import com.fasterxml.jackson.annotation.JsonSubTypes;
- import com.fasterxml.jackson.annotation.JsonTypeInfo;
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- /**
- * @Author: cjian
- * @Date: 2022/6/27 10:42
- * @Des:
- */
- @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "partner", visible = true, defaultImpl = Man.class)
- @JsonSubTypes({
- @JsonSubTypes.Type(value = Man.class, name = "wife"),
- @JsonSubTypes.Type(value = Woman.class, name = "husband")
- })
- public abstract class Person {
- private String name;
- private int age;
- private String sex;
- private String partner;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
-
- public String getSex() {
- return sex;
- }
-
- public void setSex(String sex) {
- this.sex = sex;
- }
-
- public String getPartner() {
- return partner;
- }
-
- public void setPartner(String partner) {
- this.partner = partner;
- }
- }
两个子类:
- package com.cjian.jackson;
-
- import com.fasterxml.jackson.annotation.JsonTypeName;
-
- /**
- * @Author: cjian
- * @Date: 2022/6/27 10:44
- * @Des:
- */
- public class Man extends Person {
- private String wife;
-
- public String getWife() {
- return wife;
- }
-
- public void setWife(String wife) {
- this.wife = wife;
- }
-
- @Override
- public String toString() {
- return "Man{" +
- "wife='" + wife + '\'' +
- '}';
- }
- }
- package com.cjian.jackson;
-
- import com.fasterxml.jackson.annotation.JsonTypeName;
-
- /**
- * @Author: cjian
- * @Date: 2022/6/27 10:43
- * @Des:
- */
- public class Woman extends Person {
-
- private String husband;
-
- public String getHusband() {
- return husband;
- }
-
- public void setHusband(String husband) {
- this.husband = husband;
- }
-
- @Override
- public String toString() {
- return "Woman{" +
- "husband='" + husband + '\'' +
- '}';
- }
- }
测试:
- package com.cjian.jackson;
-
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- /**
- * @Author: cjian
- * @Date: 2022/6/29 10:30
- * @Des:
- */
- public class Test {
-
- public static void main(String[] args) throws JsonProcessingException {
- ObjectMapper objectMapper = new ObjectMapper();
- String jsonString1 = "{\"name\":\"cjian\",\"age\":28,\"sex\":\"男\",\"partner\":\"wife\",\"wife\":\"lili\"}";
- String jsonString2 = "{\"name\":\"lili\",\"age\":28,\"sex\":\"女\",\"partner\":\"husband\",\"husband\":\"cjian\"}";
- Person p1 = objectMapper.readValue(jsonString1, Man.class);
- Person p2 = objectMapper.readValue(jsonString2, Woman.class);
- System.out.println(p1);
- System.out.println(p2);
- }
- }