35

我使用 Jackson 库将我的 pojo 对象序列化为JSON表示形式。例如,我有 A 类和 B 类:

class A {
  private int id;
  private B b;

  constructors...
  getters and setters
}

class B {
  private int ind;
  private A a;

  constructors...
  getters and setters
}

如果我想从类 A 序列化对象,则在序列化时肯定有可能获得递归。我知道我可以通过使用来阻止它@JsonIgnore

是否可以通过深度级别限制序列化?

例如,如果级别为 2,则序列化将这样进行:

  • 序列化 a, level = 0 (0 < 2 ok) -> 序列化
  • 序列化 ab,级别 =1 (1 < 2 ok) -> 序列化
  • 序列化 aba,级别 = 2(2 < 2 不正确)-> 停止

提前致谢。

4

7 回答 7

26

我最近遇到了一个类似的问题:Jackson - serialization of entity with birectional Relations (avoiding cycles)

所以解决方案是升级到 Jackson 2.0,并在类中添加以下注释:

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, 
                  property = "@id")
public class SomeEntityClass ...

这完美地工作。

于 2012-04-17T22:38:52.130 回答
13

检查以下链接,它可能会有所帮助:

之后的唯一选择是为您的对象类型创建自己的自定义模块以进行序列化/反序列化。看这里:

问候。

于 2012-04-17T16:54:49.790 回答
4

不支持基于级别的忽略。

但是您可以让 Jackson 使用 2.0 处理循环引用,例如,请参阅“ Jackson 2.0 发布”以了解如何使用@JsonIdentityInfo.

于 2012-04-17T22:36:14.853 回答
3

如果您只想将自己限制在一个级别(即:您转到当前对象的子对象而不是进一步),@JsonView 有一个简单的解决方案。

在链接到另一个对象的每个字段上,使用当前类作为您的视图对其进行注释:

class A {
  private int id;
  @JsonView(A.class) private B b;

  constructors...
  getters and setters
}

class B {
  private int ind;
  @JsonView(B.class) private A a;

  constructors...
  getters and setters
}

然后,在序列化时,使用对象类作为您的视图。序列化 A 的实例会呈现如下内容:

{
  id: 42,
  b: {
    id: 813
  }
}

确保将 DEFAULT_VIEW_INCLUSION 设置为 true,否则将不会呈现没有 @JsonView 注释的字段。或者,您可以使用 Object 类或任何常见的超类使用 @JsonView 注释所有其他字段:

class A {
  @JsonView(Object.class) private int id;
  @JsonView(A.class) private B b;

  constructors...
  getters and setters
}
于 2015-07-02T09:06:55.307 回答
2

对于深度序列化,您可以参考此处的示例https://github.com/abid-khan/depth-wise-json-serializer

于 2014-08-25T09:54:26.007 回答
0

在某些情况下,您可以使用保持最大深度的线程本地整数来限制序列化深度。看到这个答案

于 2014-02-14T21:20:41.483 回答
0

经过几个月和大量的研究,我实现了自己的解决方案,以使我的域远离杰克逊依赖项。

public class Parent {
    private Child child;
    public Child getChild(){return child;} 
    public void setChild(Child child){this.child=child;}
}

public class Child {
    private Parent parent;
    public Child getParent(){return parent;} 
    public void setParent(Parent parent){this.parent=parent;}
}

首先,您必须以如下方式声明双向关系的每个实体:

public interface BidirectionalDefinition {

    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Parent.class)
    public interface ParentDef{};

    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Child.class)
    public interface ChildDef{};

}

之后,可以自动配置对象映射器:

ObjectMapper om = new ObjectMapper();
Class<?>[] definitions = BidirectionalDefinition.class.getDeclaredClasses();
for (Class<?> definition : definitions) {
    om.addMixInAnnotations(definition.getAnnotation(JsonIdentityInfo.class).scope(), definition);
}
于 2015-10-30T04:28:07.177 回答