添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

有时,一张表里面存储的具体对象可能不一样,比如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的对json字段的序列化和反序列化默认策略是根据getter和setter方法,去掉get和set,再把首字母小写,便找到了对应的字段。通常情况,我们都是对普通的POJO进行serialization/deserialization。那么如果遇到了解析抽象类呢?如何定位到对应的实现类?实现类都找不到,谈何匹配到对应的字段反序列化。 二、JsonTypeInfo 注解...
让我们看Jackson控制多的注解: @JsonTypeInfo – indicates details of what type information to include in serialization 指出序列化包含的类型信息细节 @JsonSubTypes – indicates sub-types of the annotated type 指出被注解类型的子类 ...
import com.fasterxml.jackson.annotation.JacksonAnnotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang...
博主github 博主个人博客http://blog.healerjean.com Jackson允许配置多类型处理,当进行反序列话时,Json数据匹配的对象可能有多个子类型,为了正确的读取对象的类型,我们需要添加一些类型信息。 1.1、@JsonTypeInfo @JsonTypeInfo这个注解可以直接放在类上,也可以放在某个属性上:下面是内部的属性值 1.1.1、use: ... 一、Jackson之序列化和反序列化 JSON作为一种轻量级的数据交换格式,其清晰和简洁的结构能够轻松地与Java对象产生映射关系。Java开发中常常使用Jackson对JSON文本格式进行序列化和反序列化: 序列化:是指将Java对象转换成Json文件或者Json字符串; 反序列化:是指将Json文件或者Json字符串转换成Java对象。 例如,有如下定义的java的bean: public cl.
@JsonTypeInfo 逻辑名称 @JsonSubTypes、@JsonTypeName@JsonTypeName@JsonSubTypeExampleJava ObjectsSerializing and deserializinginclude = JsonTypeInfo.As.WRAPPER_OBJECT原文链接 @JsonTypeInfo 的 use = JsonTypeInfo.Id.CLASS,会将完全限定类名序列化为类型标识符。当非 Java 客户端使用被序列化的 JSON 时,Java
使用@SerializedName注解解决json属性名和实体类名称不一致问题 首先引入依赖 <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version
本文实例讲述了Laravel5.1 框架模型多关联用法。分享给大家供大家参考,具体如下: 什么是多关联? 一个例子你就明白了:好比如说评论 它可以属于视频类 也可以属于文章类,当有个需求是 从评论表中取到视频类的数据,这就需要用到多关联了。 简单的一句话总结:一张表对应两张表。 1 实现多关联 1.1 文章表的结构 public function up() Schema::create('articles', function (Blueprint $table) { $table->increments('id'); $table->st
C++中的多类对象的大小取决于其成员变量和虚函数的数量和类型。一个多类对象的大小由以下几个因素决定: 1. 成员变量:多类对象中包含的成员变量所占用的空间大小会影响对象的总大小。每个成员变量都占用一定的字节,不同类型的成员变量可能占用不同的空间。 2. 虚函数表指针:多类中如果有虚函数,那么每个对象都会包含一个指向虚函数表的指针(通常称为虚函数表指针),该指针占用一定的空间。 3. 虚函数表:虚函数表是一个包含虚函数指针的表格,用于实现动绑定。虚函数表的大小取决于类中声明的虚函数数量。 因此,多类对象的大小是以上因素之和。请注意,不同的编译器可能对内存布局和对齐方式有所不同,因此实际的对象大小可能会有所差异。
一定要坚持创作更多高质量博客哦, 小小红包, 以资鼓励, 更多创作活动请看: 程序员有哪些绝对不能踩的坑?: https://activity.csdn.net/creatActivity?id=10433?utm_source=csdn_ai_ada_redpacket 如何入门Python: https://activity.csdn.net/creatActivity?id=10436?utm_source=csdn_ai_ada_redpacket 新人首创任务挑战赛: https://marketing.csdn.net/p/90a06697f3eae83aabea1e150f5be8a5?utm_source=csdn_ai_ada_redpacket 全部创作活动: https://mp.csdn.net/mp_blog/manage/creative?utm_source=csdn_ai_ada_redpacket