如何将@JsonIdentityInfo 与循环引用一起使用?
How to use @JsonIdentityInfo with circular references?
我正在尝试使用来自 Jackson 2 的 @JsonIdentityInfo,如 here 所述。
出于测试目的,我创建了以下两个 classes:
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 WhosebugError
Assert.assertEquals("{\"@id\":1,\"b\":{\"@id\":2,\"a\":1}}", s);
}
将@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
加到classAand/orclassB也不行。
我希望我可以将 a
序列化(然后反序列化)成这样的东西:(虽然对 JSON 不太确定)
{
"b": {
"@id": 1,
"a": {
"@id": 2,
"b": 1
}
}
}
我该怎么做?
似乎 jackson-jr 具有 Jackson 的一部分特征。 @JsonIdentityInfo
一定没有晋级。
如果您可以使用完整的 Jackson 库,只需使用带有您在问题中建议的 @JsonIdentityInfo
注释的标准 ObjectMapper
并序列化您的对象。例如
@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
引用根对象。
在某些情况下,可能需要用 @Json属性("id")
例如,就我而言,这使我的应用程序 运行 正确。
有几种方法可以解决此循环引用或无限递归问题。本link一一详解。我已经解决了我的问题,包括在每个相关实体上方的 @JsonIdentityInfo 注释,尽管 @JsonView 是更新的并且可能是更好的解决方案,具体取决于您的情况。
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
或者使用 IntSequenceGenerator 实现:
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class)
@Entity
public class A implements Serializable
...
我正在尝试使用来自 Jackson 2 的 @JsonIdentityInfo,如 here 所述。
出于测试目的,我创建了以下两个 classes:
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 WhosebugError
Assert.assertEquals("{\"@id\":1,\"b\":{\"@id\":2,\"a\":1}}", s);
}
将@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
加到classAand/orclassB也不行。
我希望我可以将 a
序列化(然后反序列化)成这样的东西:(虽然对 JSON 不太确定)
{
"b": {
"@id": 1,
"a": {
"@id": 2,
"b": 1
}
}
}
我该怎么做?
似乎 jackson-jr 具有 Jackson 的一部分特征。 @JsonIdentityInfo
一定没有晋级。
如果您可以使用完整的 Jackson 库,只需使用带有您在问题中建议的 @JsonIdentityInfo
注释的标准 ObjectMapper
并序列化您的对象。例如
@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
引用根对象。
在某些情况下,可能需要用 @Json属性("id")
例如,就我而言,这使我的应用程序 运行 正确。
有几种方法可以解决此循环引用或无限递归问题。本link一一详解。我已经解决了我的问题,包括在每个相关实体上方的 @JsonIdentityInfo 注释,尽管 @JsonView 是更新的并且可能是更好的解决方案,具体取决于您的情况。
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
或者使用 IntSequenceGenerator 实现:
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class)
@Entity
public class A implements Serializable
...