Jackson框架处理多态类
Posted cj_eryue
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jackson框架处理多态类相关的知识,希望对你有一定的参考价值。
有时,一张表里面存储的具体对象可能不一样,比如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)
属性介绍:
- use:定义使用哪一种类型识别码,它有下面几个可选值:
JsonTypeInfo.Id.CLASS
:使用完全限定类名做识别JsonTypeInfo.Id.MINIMAL_CLASS
:若基类和子类在同一包类,使用类名(忽略包名)作为识别码JsonTypeInfo.Id.NAME
:一个合乎逻辑的指定名称JsonTypeInfo.Id.CUSTOM
:自定义识别码,由@JsonTypeIdResolver
对应,稍后解释JsonTypeInfo.Id.NONE
:不使用识别码
- include(可选):指定识别码是如何被包含进去的,它有下面几个可选值:
- JsonTypeInfo.As.PROPERTY:作为数据的兄弟属性(默认)
- JsonTypeInfo.As.EXISTING_PROPERTY:作为POJO中已经存在的属性
- JsonTypeInfo.As.EXTERNAL_PROPERTY:作为扩展属性
- JsonTypeInfo.As.WRAPPER_OBJECT:作为一个包装的对象
- JsonTypeInfo.As.WRAPPER_ARRAY:作为一个包装的数组
- property(可选):制定识别码的属性名称
此属性只有当: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
(可选):如果类型识别码不存在或者无效,可以使用该属性来制定反序列化时使用的默认类型- visible(可选,默认为false):是否可见
属性定义了类型标识符的值是否会通过JSON流成为反序列化器的一部分,默认为fale,也就是说,jackson会从JSON内容中处理和删除类型标识符再传递给JsonDeserializer。
@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 ...
demo:
依赖:
<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);
以上是关于Jackson框架处理多态类的主要内容,如果未能解决你的问题,请参考以下文章