java - 使用 Jackson 序列化和反序列化树结构
问题描述
我有一个树结构,其中包含以下对象,我需要使用 Jackson 对其进行序列化和反序列化,但不知道该怎么做。
Type
Type
有名字和版本。它也可能有父类型和子类型。
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name")
final class Type {
private final PrefixedName name;
private final Integer version;
private final Set<Type> subTypes = new HashSet<>();
private final Type parent;
private final PrefixedName parentName;
Type(final PrefixedName name, final Integer version) {
this(name, version, null);
}
@JsonCreator
Type(@JsonProperty("name") @JsonDeserialize(keyUsing = PrefixedNameKeyDeserializer.class) final PrefixedName name,
@JsonProperty("typeVersion") final Integer version, @JsonProperty("parent") final Type parent) {
this.name = Objects.requireNonNull(name);
Preconditions.checkArgument(version > 0, "Version number must be positive");
this.version = version;
this.parent = parent;
if (parent != null) {
this.parentName = parent.getName();
parent.addSubType(this);
} else {
this.parentName = null;
}
}
// Other methods to add sub-types; and getters for all properties omitted
}
Model
Model
包含树的根——一个Type
和一个版本。
final class Model {
private final Integer version;
private final Type root;
@JsonCreator
Model(@JsonProperty("modelVersion") final Integer version, @JsonProperty("root") final Type root) {
this.version = version;
this.root = root;
}
使用杰克逊的ObjectMapper
序列化看起来如我所料:
{
"root":{
"parent":null,
"name":{
"localName":"Base",
"prefix":"schema"
},
"subTypes":[
{
"parent":{
"localName":"Base",
"prefix":"schema"
},
"name":{
"localName":"Person",
"prefix":"schema"
},
"subTypes":[
{
"parent":{
"localName":"Person",
"prefix":"schema"
},
"name":{
"localName":"employee",
"prefix":"schema"
},
"subTypes":[
],
"version":1
}
],
"version":1
},
{
"parent":{
"localName":"Base",
"prefix":"schema"
},
"name":{
"localName":"organisation",
"prefix":"schema"
},
"subTypes":[
],
"version":1
},
{
"parent":{
"localName":"Base",
"prefix":"schema"
},
"name":{
"localName":"CreativeWork",
"prefix":"schema"
},
"subTypes":[
{
"parent":{
"localName":"CreativeWork",
"prefix":"schema"
},
"name":{
"localName":"Journal",
"prefix":"schema"
},
"subTypes":[
],
"version":1
},
{
"parent":{
"localName":"CreativeWork",
"prefix":"schema"
},
"name":{
"localName":"Book",
"prefix":"schema"
},
"subTypes":[
],
"version":1
}
],
"version":1
}
],
"version":1
},
"version":8
}
Type
请注意,类上的注释@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name")
意味着该parent
属性仅使用该属性编写name
- 这是为了防止无限递归和StackOverflowException
- 如果有更好的方法来做到这一点,我很乐意改变。
但是,反序列化失败,将属性NullPointerException
设置为:name
Type
this.name = Objects.requireNonNull(name);
我已经通过代码进行了调试,并且看到 Jackson 正在PrefixedName
将父级的(如下所示的类)的两个属性捕获为“未知”属性——我不确定这是否与问题有关,但它可能有用。
PrefixedName
这是两个带有 Jackson 注释的 String 属性的简单AutoValue类:
@AutoValue
@SuppressWarnings("squid:S1610")
@JsonDeserialize(builder = AutoValue_PrefixedName.Builder.class)
abstract class PrefixedName {
static Builder builder() {
return new AutoValue_PrefixedName.Builder();
}
@JsonProperty
abstract String prefix();
@JsonProperty
abstract String localName();
@AutoValue.Builder
abstract static class Builder {
@JsonProperty
abstract Builder prefix(final String prefix);
@JsonProperty
abstract Builder localName(final String localName);
abstract PrefixedName build();
}
}
谢谢你尽你所能的帮助。
解决方案
推荐阅读
- hibernate - 使用弹簧靴更改休眠列数
- angular - ngrx 和 ngxs 之间的性能差异?
- angular - Angular 6 的 Azure 应用程序设置
- excel - Excel VBA 使用样式
- javascript - 如何将选中复选框的输入值添加到列表中?
- python - Python:两个网络之间的jaccard相似性?
- javascript - Firebase 事务多次更新
- python - 从 BeautifulSoup 中删除 NoneType
- python - Librosa 和 matplotlib(使用 PyQt5)出现错误
- jmeter - 如何通过 Jmeter 测试启用 SSO(或 kerberos)的应用程序?我如何知道用于 kerberos 身份验证的 kdc 和 admin_server 值?