Jackson对嵌套对象进行反序列化,其中一个引用另一个。未解决的ForwardReference

时间:2018-08-23 23:56:13

标签: java json jackson deserialization

我正在尝试反序列化以下JSON结构:

{
  "node" : {
    "number" : 5,
    "x" : 2000.0,
    "y" : 1500.0
  },
  "force" : {
    "number" : 1,
    "value" : -20.0,
    "angle" : 90.0,
    "node" : 5
  }
}

进入以下对象:

public class NodeWithForce {

    private Node node;
    private Force force;

    public NodeWithForce(){}

    public NodeWithForce(Node node, Force force) {
        this.node = node;
        this.force = force;
    }

    //getters and setters for Node and Force, Equals and Hashcode
}

节点类:

public class Node {

    private long number;
    private double x;
    private double y;

    public Node() {}

    public Node(long number, double x, double y) {
        this.number = number;
        this.x = x;
        this.y = y;
    }

    //getters and setters for number, x and y, equals and hashcode
    }
}

强制班:

public class Force {

    private long number;
    private double value;
    private double angle;

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "number")
    @JsonIdentityReference(alwaysAsId = true)
    private Node node;

    public Force() {}

    public Force(long number, double value, double angle, Node node) {
        this.number = number;
        this.value = value;
        this.angle = angle;
        this.node = node;
    }

    //getters and setters for number, value, angle and node. Equals and Hashcode.
}

因此,Node是包装对象NodeWithForce的一部分,也是包装子元素之一:Force。实际的数据结构比这要复杂得多,但是我尝试在SO上降低复杂性并只保留对这个问题重要的部分。

然后当我运行此命令时:

public NodeWithForce getNodeWithForce() throws Exception {
    Node node = new Node(5, 2000, 1500);
    Force force = new Force(1, -20, 90, node);
    NodeWithForce nwf = new NodeWithForce(node,force);
    NodeWithForce nwf2 = null;
    ObjectMapper om = context.getBean(ObjectMapper.class);
    om.enable(SerializationFeature.INDENT_OUTPUT);
    String jsonRepresentation = null;
    jsonRepresentation = om.writeValueAsString(nwf);
    System.out.println(jsonRepresentation);
    nwf2 = om.readValue(jsonRepresentation, NodeWithForce.class);
    System.out.println("equal: " + nwf.equals(nwf2));
    return nwf2;
}

它给了我以下例外:

com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for: 
 at [Source: (String)"{
  "node" : {
    "number" : 5,
    "x" : 2000.0,
    "y" : 1500.0
  },
  "force" : {
    "number" : 1,
    "value" : -20.0,
    "angle" : 90.0,
    "node" : 5
  }
}"; line: 13, column: 1]Object id [5] (for `com.company.calculationmanager.pojos.Node`) at [Source: (String)"{
  "node" : {
    "number" : 5,
    "x" : 2000.0,
    "y" : 1500.0
  },
  "force" : {
    "number" : 1,
    "value" : -20.0,
    "angle" : 90.0,
    "node" : 5
  }
}"; line: 11, column: 15].
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.checkUnresolvedObjectId(DefaultDeserializationContext.java:165) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4015) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004) ~[jackson-databind-2.9.6.jar:2.9.6]

序列化之所以有效,是因为它即使将JsonIdentityInfo批注添加到控制台,也可以将对象作为json打印到控制台,但是序列化却不能。

我在这里缺少一些注释吗?我认为编写一个单独的反序列化器对于这个简单的部分来说太过分了。

2 个答案:

答案 0 :(得分:1)

@JsonIdentityInfo注释放在Node类上,而不是Force中的字段上:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "number")
public static class Node { //...

答案 1 :(得分:0)

在NodeWithForce类中创建一个接受int的新setter方法setNode:

    private void setNode(int number) {
        setNode(new Node(number));
    }