资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

Jackson不修改父类而实现多态解析-创新互联

前言

众所周知 jackson 可以如下进行多态处理

创新互联专业为企业提供宏伟网站建设、宏伟做网站、宏伟网站设计、宏伟网站制作等企业网站建设、网页设计与制作、宏伟企业网站模板建站服务,十余年宏伟做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes(value = {
        @JsonSubTypes.Type(value = FirstChild.class, name = "first-child"),
        @JsonSubTypes.Type(value = SecondChild.class, name = "second-child"),
})
public interface Parent {
}

@Data
public static class FirstChild implements Parent {
    private String foo;
}

@Data
public static class SecondChild implements Parent {
    private String bar;
}

序列化时 jackson 会读取 @JsonSubTypes 的属性, 最终输出如:

{
    "type": "first-child",
    "foo": "hello, world"
}

反序列化时 jackson 通过 JSON 中的 "type" 属性知道该使用哪一个子类.

问题

当新增一个子类型时, 必须修改父类型的 @JsonSubTypes 注解, 否则不生效

首先是 不够优雅,

更严重的是 如果父类是外部依赖, 我们根本不能修改, 怎么办?

这个问题在 GitHub 中也有讨论, 不过最终没有下文.

解决方案

既然没有现成的方案, 而且 Jackson 的模块化做的很好, 不如自己造个轮子, 其实实际很简单: 通过 SPI 把子类注册进 Jackson 就行. 当然不一定是 SPI, 也可以是 classgraph 等.

今天就厚着脸皮分享一下自己造的轮子: jackson-modules-dynamic-subtype

以最简方式演示:

io.github.black-06.jacksonjackson-modules-dynamic-subtype2.14.0
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
public interface Parent {
}

@Data
@AutoService(Parent.class)
@JsonSubType("first-child")
public static class FirstChild implements Parent {
    private String foo;
}
  • 父类上的 @JsonTypeInfo 仍必须有

  • @AutoService 注解是谷歌 auto 的, 用来自动生成 SPI 所需的 META-INF/services/package.Parent 文件, 具体可见 auto/service at main · google/auto (github.com)

  • @JsonSubType 是轮子里头发明的, 与 @JsonSubTypes 的区别是, 它注解在子类型上.

然后注册模块:

PS. 在 Spring Boot 中它会自动注册, 可以跳过这一步

import io.github.black.jackson.DynamicSubtypeModule;

ObjectMapper mapper = new ObjectMapper().registerModule(new DynamicSubtypeModule());

简简单单.

其他:
  • 轮子里面的 ServiceLoad 是我根据 JDK 8 重写的, 只返回 Class 而不返回 Instance. 如果它工作的不是很正常, 考虑调用 module.setUseStandardServiceLoader(true) 使用标准库的 Loader.

  • 如果你不喜欢 SPI, 可以自行想办法获取所有字类, 并手动调用 module.registerTypes 将其注册进去.

最后, 如果这个轮子帮到了你, 求一个 star~

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


标题名称:Jackson不修改父类而实现多态解析-创新互联
文章网址:http://www.cdkjz.cn/article/deohco.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220