java - 在 Jackson 中以编程方式设置类型鉴别器
问题描述
对于多态反序列化,Jackson 的 ObjectMapper 想知道:
- 需要考虑哪些子类型
- 如何决定,使用哪个子类型
有一些标准方法,使用完全限定的类名和某些保留的 JSON 属性,因此 Jackson 无需进一步配置即可扣除这些东西。
@JsonTypeInfo
另一种常见的方法是,通过将注释和添加@JsonSubtypes
到基本类型来为杰克逊提供必要的信息。然而,这意味着,当添加新的子类型时,必须修改声明基类的文件。
也可以在运行时通过objectMapper.registerSubtypes(...)
.
现在我正在寻找一种在运行时以编程方式提供来自@JsonTypeInfo 的信息而不使用该注释的方法。
像objectMapper.addTypeInfo(new TypeInfo(BaseType.class, PROPERTY, "myPropertyName", NAME);
这样我可以对在另一个项目中声明的类型使用多态反序列化,这对 Jackson 或其任何注释一无所知。
解决方案
要在@JsonTypeInfo
不修改实际类的情况下注册,您必须使用这样的 mixin:
// actual base type that we don't want to or can't modfiy
// because it is in a different module / 3rd party
public class BaseType {
...
}
// mixin for BaseType to define @JsonTypeInfo
// this can be in a completely different package / module
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY, property = "type")
public abstract class BaseTypeMixIn {
}
必须为 ObjectMapper 手动注册 mixin:
objectMapper.addMixIn(BaseType.class, BaseTypeMixIn.class);
BaseType 现在有效地@JsonTypeInfo
从 mixin 中获取。jackson 中的 Mixin 是“如何注释我无法修改的类”问题的一般解决方案。
对于子类型,可以使用 注册ObjectMapper.registerSubtypes
或通过使用 注释 mixin来注册类型信息@JsonSubtypes
。在这种情况下,我更喜欢在没有注释的情况下进行操作,因为如果不同的模块具有不同的基本类型的子类型,它也可以工作。注册多个 mixin 很可能不起作用。
public class SubTypeA extends BaseType {
...
}
public class SubTypeB extends BaseType {
...
}
在 ObjectMapper 中注册:
objectMapper.registerSubtypes(
new NamedType(SubTypeA.class, "A"),
new NamedType(SubTypeB.class, "B"));
推荐阅读
- c++ - 冰雹序列 C++ 递归
- mysql - Mysql:如何从给定模式中的所有表中删除 NOT NULL 约束
- php - Laravel 使用用户或管理员加入 post 表
- django-models - 在插入行时使用 Django 条件表达式
- windows - IIS 绑定问题 - AWS 自动缩放 - HTTP 404
- mysql - MySQL 在 between 语句中使用 max(date)
- php - maxAttemptsExceededException : Laravel Jobs 由于最大尝试或超时而失败
- jhipster - JHipster - 如何使用 Angular 7 直接编译 SCSS 文件
- javascript - 你如何让 axios GET 请求等待?
- node.js - 为什么文档没有从 mongodb 数据库中删除?