如何使用Jackson的@JsonIdentityInfo对有向图的反序列化?

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更新中做了很多广告.

我在这里错过了什么?感谢您提前提出建设性的答案.

编辑

(从这里删除我的答案到答案部分)

Mal*_*teJ 3

我盯着它看了太久,有点盲目。这是出了问题的地方:

序列化实际上按预期进行了。不起作用的是反序列化,因为杰克逊无法实例化我的节点对象。我只是忘记正确注释构造函数方法的参数。

我现在面临另一个问题。生成的 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,因为它仍在构建中(在本例中你可以说它实际上是某种根)。解决这个问题的唯一方法似乎是构造所有没有边缘的节点,并在第二步中注入它们。

  • 您能否写出您是如何解决“忘记正确注释构造函数方法的参数”的,以便我们可以看到实际的解决方案?提前谢谢! (3认同)