Jackson多态处理

本文详细介绍了Jackson库在处理多态类型时的配置方法,包括JsonTypeInfo注解的use、include、property和visible等参数的使用,以及JsonSubTypes的配合。通过多个示例解析了如何正确地进行序列化和反序列化操作。
摘要由CSDN通过智能技术生成

前言

博主github
博主个人博客http://blog.healerjean.com

Jackson允许配置多态类型处理,当进行反序列话时,Json数据匹配的对象可能有多个子类型,为了正确的读取对象的类型,我们需要添加一些类型信息。

1、解释

1.1、@JsonTypeInfo

@JsonTypeInfo这个注解可以直接放在类上,也可以放在某个属性上:下面是内部的属性值

1.1.1、use: (必选):

use: (必选):定义使用哪一种类型识别码(property为识别码的key),可选值有多种:在序列化时标志出不同的类型用什么区分,用在反序列化时转换成响应的类型

use属性值 若不指定property则默认 作用 是否依赖JsonTypeInfo的值
JsonTypeInfo.Id.NAME @type 使用JsonTypeInfo的值作为识别码的值 如果有多个子类的情况,必须有 @JsonSubTypes,否则无法判断是哪个子类
JsonTypeInfo.Id.CLASS @class 用类的全路劲名称来作为识别码的值 与是否有@JsonSubTypes无关
JsonTypeInfo.Id.MINIMAL_CLASS @c 表示具有最小路径的Java类名称用作识别 是否有@JsonSubTypes无关
JsonTypeInfo.Id.NONE 暂不介绍
JsonTypeInfo.Id.CUSTOM 暂不介绍
1.1.2、include (可选)

设置识别码包含在哪里。 包含类型元数据的一种机制

include属性值 作用
JsonTypeInfo.As.PROPERTY 作为POJO的属性出现 默认
JsonTypeInfo.As.WRAPPER_OBJECT 作为一个包装的对象
JsonTypeInfo.As.WRAPPER_ARRAY 作为一个包装的数组
JsonTypeInfo.As.EXTERNAL_PROPERTY 作为一个额外的属性,跟POJO同级,只能用于属性,如何作用于类则跟JsonTypeInfo.As.PROPERTY是相同效果
JsonTypeInfo.As.EXISTING_PROPERTY 序列化,则Jackson不主动处理,由我们自行处理。 反序列化的时候,跟JsonTypeInfo.As.PROPERTY的处理相同;
1.1.3、property 可选)

设置识别码是名称, 自定义的区分类型的id,根据 use的属性值不同,默认值不同,具体默认值看(1.1.1)

1.1.4、visible (可选)

visible(可选):定义识别码在反序列化时是否保留(不管false或true都不影响序列化)。默认是false,表示Jackson可以将识别码识别为类型后就删除。

1.2、@JsonSubTypes

可以用来表明这个父类的子类型有哪些

2、准备

2.1、Demo实体类

public abstract class Human {
   

    private String district;

    @Data
    public static class Man extends Human {
   
        private String manField;
    }

    @Data
    public static class Woman extends Human {
   
        private String womanField;
    }

}

2.2、正常情况下的错误的演示



    @Test
    public void normal() throws IOException {
   
        ObjectMapper mapper = new ObjectMapper();
        Man man = new Man();
        man.setManField("男人");
        man.setDistrict("山西");
        String json = mapper.writeValueAsString(man);
        System.out.println(json);
        // {"district":"山西","manField":"男人"}
        //报错 子类转父类,再不能直接序列化为子类
        man =((Man)mapper.readValue(json, Human.class)) ;
    }
    

3、开始

3.1、实体demo

@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY
)
@JsonSubTypes({
   
        @JsonSubTypes.Type(value = Human.Man.class, name = "man"),
        @JsonSubTypes.Type(value = Human.Woman.class, name = "woman"),
})
public abstract class Human {
   

    private String district;

    @Data
    public static class Man extends Human {
   
        private String manField;
    }

    @Data
    public static class Woman extends Human {
   
        private String womanField;
    }

}

3.2、测试用例

  @Test
    public void testOne() throws IOException {
   
        ObjectMapper mapper = new ObjectMapper();
        Man man = new Man();
        man.setManField("男人");
        man.setDistrict("北京");

        String manJson = mapper.writeValueAsString(man);
        log.info("序列化Man :【 {} 】", manJson);
        Human human = mapper.readValue(manJson, Human.class);
        log.info("子类转父类 ================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值