Mal*_*teJ 6 java serialization json directed-graph jackson
我想使用Jackson 2.3.3进行有向图的反序列化/序列化.我想出的结构大致如下:
public Class Graph {
private final Set<Node> nodes;
public Graph(Set<Node> nodes) { ... }
public Set<Node> getNodes() { ... }
}
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "name")
public Class Node {
private final String name;
private final Set<Edge> edges;
public Node(String name, Set<Edge> edges) { ... }
public String getName() { ... }
public Set<Edge> getEdges() { ... }
}
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "name")
public Class Edge {
private final String name;
private final Node successor;
public Edge(String name, Node successor) { ... }
public String getName() { ... }
public Node getSuccessor() { ... }
}
Run Code Online (Sandbox Code Playgroud)
我希望有这个JSON结构:
{
"graph": [{
"name": "A",
"edges": [{
"name": "0",
"successor": "B"
}, {
"name": "1",
"successor": "A"
}]
}, {
"name": "B",
"edges": [{
"name": "0",
"successor": "A"
}, {
"name": "1",
"successor": "B"
}]
}]
}
Run Code Online (Sandbox Code Playgroud)
但是反序列化时会出现以下错误(即使@JsonProperty("name")在Getters中有注释):
com.fasterxml.jackson.databind.JsonMappingException: Invalid Object Id definition for some.package.graph.Node: can not find property with name 'name'
我已经找到了一些带有反向引用注释的Jackson 1.6的解决方案,但是我想使用新的Jackson 2.x Annotation,因为它在杰克逊的1.9到2.0的API更新中做了很多广告.
我在这里错过了什么?感谢您提前提出建设性的答案.
(从这里删除我的答案到答案部分)
我盯着它看了太久,有点盲目。这是出了问题的地方:
序列化实际上按预期进行了。不起作用的是反序列化,因为杰克逊无法实例化我的节点对象。我只是忘记正确注释构造函数方法的参数。
我现在面临另一个问题。生成的 JSON 现在如下所示:
"graph": {
"nodes": [{
"name": "B",
"edges": [{
"label": "1",
"successor": "B"
}, {
"label": "0",
"successor": {
"name": "A",
"edges": [{
"label": "1",
"successor": "A"
}, {
"label": "0",
"successor": "B"
}]
}
}]
}, "A"]
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。但在绘制地图时,杰克逊向我提出了这个错误:
java.lang.IllegalStateException: Could not resolve Object Id [B] (for [simple
type, class some.package.graph.Node]) -- unresolved forward-reference?
Run Code Online (Sandbox Code Playgroud)
我什至更改了边缘的标签,因为我认为相同的属性名称可能会让杰克逊感到困惑,但这也没有帮助......
我的猜测是 Jackson 无法引用 Node B,因为它仍在构建中(在本例中你可以说它实际上是某种根)。解决这个问题的唯一方法似乎是构造所有没有边缘的节点,并在第二步中注入它们。