gpt4 book ai didi

jackson - 如何反序列化引用 Jackson 中的抽象类型的 JSON

转载 作者:行者123 更新时间:2023-12-01 03:21:30 34 4
gpt4 key购买 nike

我对抽象类和 JSON 序列化和反序列化的对象引用有问题。抽象的问题如下所示:

我有一个由节点和边组成的图。每条边连接两个节点。节点可以是红色和绿色的。因此,有一个抽象类Node和两个派生类 RedNodeGreenNode .一个 Node需要一个 id ( @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") ):

@JsonSubTypes({
@JsonSubTypes.Type(value = GreenNode.class, name = "GreenNode"),
@JsonSubTypes.Type(value = RedNode.class, name = "RedNode")
})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public abstract class Node {
public String id;
}

public class RedNode extends Node {
// ...
}

public class GreenNode extends Node {
// ...
}

Edge具有类型为 Node 的源和目标,它们被序列化为引用( @JsonIdentityReference(alwaysAsId = true) ):
public class Edge {
@JsonIdentityReference(alwaysAsId = true)
public Node source;
@JsonIdentityReference(alwaysAsId = true)
public Node target;
}

该图定义如下:
public class Graph {
public List<GreenNode> greenNodes = new ArrayList();
public List<RedNode> redNodes = new ArrayList();
public List<Edge> edges = new ArrayList();
}

JSON 示例如下所示:
{
"greenNodes" : [ {
"id" : "g",
"content" : "green g",
"greenProperty" : "green"
} ],
"redNodes" : [ {
"id" : "r",
"content" : "red r",
"redProperty" : "red"
} ],
"edges" : [ {
"source" : "g",
"target" : "r"
} ]
}

使用 ObjectMapper不能读这个:

Can not construct instance of com.github.koppor.jsonidentityissue.model.Node: abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information



错误位置是“行:13,列:16”。因此,它在边缘的 id 处被击中。节点本身已正确序列化。

一种解决方法是在 json 中添加类型信息:
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
public abstract class Node {

然后,一切正常:
{
"greenNodes" : [ {
"id" : "g",
"type" : "GreenNode",
"content" : "green g",
"greenProperty" : "green"
} ],
"redNodes" : [ {
"id" : "r",
"type" : "RedNode",
"content" : "red r",
"redProperty" : "red"
} ],
"edges" : [ {
"source" : "g",
"target" : "r"
} ]
}

然后,一切正常。

真的有必要在 中包含类型信息吗?引用 对象具有 引用 在职的?如果没有类型信息,可以加载带有红色和绿色节点(并且没有边)的图。边缘进来后,就不能了。但是,边的 JSON 仅包含一个 id。引用的对象已经被解析。

我真的很想摆脱 @JsonTypeInfo注解。有没有办法拥有一个干净的 JSON?

完整示例可在 https://github.com/koppor/jackson-jsonidentityreference-issue/tree/issue 获得。 .

最佳答案

当前的解决方案是包含假类型信息。完整代码在 https://github.com/koppor/jackson-jsonidentityreference-issue .
Node获取现有属性 type ,没有写成:

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "type")
public abstract class Node {
@JsonIgnore
public abstract String getType();
}

每个子类将自己指定为 defaultImpl并提供了 getType 的实现:
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "type",
defaultImpl=GreenNode.class)
public class GreenNode extends Node {
@Override
public String getType() {
return "GreeNode";
}
}

这样,JSON 保持干净,但 Jackson 可以毫无问题地解析 id 引用。

关于jackson - 如何反序列化引用 Jackson 中的抽象类型的 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44789227/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com