如何在循环引用中使用@JsonIdentityInfo?

我正在尝试使用Jackson 2中的@JsonIdentityInfo,如此处所述。

出于测试目的,我创建了以下两个类:

public class A { private B b; // constructor(s) and getter/setter omitted } public class B { private A a; // see above } 

当然,天真的方法很糟糕:

 @Test public void testJacksonJr() throws Exception { A a = new A(); B b = new B(a); a.setB(b); String s = JSON.std.asString(a);// throws StackOverflowError Assert.assertEquals("{\"@id\":1,\"b\":{\"@id\":2,\"a\":1}}", s); } 

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")到A类和/或B类也不起作用。

我希望我可以序列化(以后反序列化) a到这样的东西:(虽然不太确定JSON)

 { "b": { "@id": 1, "a": { "@id": 2, "b": 1 } } } 

我怎样才能做到这一点?

看来jackson-jr有Jackson的一部分function。 @JsonIdentityInfo一定不能削减。

如果您可以使用完整的Jackson库,只需使用标准的ObjectMapper和您在问题中建议的@JsonIdentityInfo注释,并序列化您的对象。 例如

 @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") public class A {/* all that good stuff */} @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") public class B {/* all that good stuff */} 

接着

 A a = new A(); B b = new B(a); a.setB(b); ObjectMapper mapper = new ObjectMapper(); System.out.println(mapper.writeValueAsString(a)); 

会产生

 { "@id": 1, "b": { "@id": 2, "a": 1 } } 

嵌套a通过其@id引用根对象的位置。

有几种方法可以解决此循环引用或无限递归问题。 这个链接详细解释了每一个。 我已经解决了我的问题,包括每个相关实体上面的@JsonIdentityInfo注释,尽管@JsonView是最新的,根据你的风景,它可能是一个更好的解决方案。

 @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") 

或者使用IntSequenceGenerator实现:

 @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class) @Entity public class A implements Serializable ... 

在某些情况下,可能需要使用@JsonProperty(“id”)注释Id属性

例如,在我的情况下,这使我的应用程序正确运行。

Interesting Posts