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

时间:2014-07-22 14:42:12

标签: java json serialization jackson directed-graph

我想使用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() { ... }
}

我希望有这个JSON-Structure:

{
  "graph": [{
    "name": "A",
    "edges": [{
      "name": "0",
      "successor": "B"
    }, {
      "name": "1",
      "successor": "A"
    }]
  }, {
    "name": "B",
    "edges": [{
      "name": "0",
      "successor": "A"
    }, {
      "name": "1",
      "successor": "B"
    }]
  }]
}

但是我在反序列化时遇到以下错误(即使在Getters上注释@JsonProperty("name")):

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注释,因为它在杰克逊1.9到2.0的API更新中做了很多广告

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

修改

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

1 个答案:

答案 0 :(得分:2)

我有点盲目地盯着它看。这里出了什么问题:

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

我现在面临另一个问题。生成的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"]
}

到目前为止一切顺利。但在制图过程中,杰克逊面临这个错误:

java.lang.IllegalStateException: Could not resolve Object Id [B] (for [simple
type, class some.package.graph.Node]) -- unresolved forward-reference?

我甚至更改了边缘的标签,因为我认为相同的属性名称可能会让杰克逊在这里感到困惑,但这对...都没有帮助......

我的猜测是杰克逊无法引用Node B,因为它仍在构建中(你可以说它在这个例子中实际上是某种根)。解决这个问题的唯一方法似乎是构造没有边缘的所有节点,并在第二步中注入它们。