Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jackson JSON序列化,通过级别定义避免递归_Java_Json_Serialization_Jackson - Fatal编程技术网

Java Jackson JSON序列化,通过级别定义避免递归

Java Jackson JSON序列化,通过级别定义避免递归,java,json,serialization,jackson,Java,Json,Serialization,Jackson,我使用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序列化对象,那个么在序列化对象时有一定的可能得到递归。

我使用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,则序列化将按以下方式进行:

  • 序列化一个,级别=0(0<2正常)->序列化
  • 序列化a.b,级别=1 (1<2正常)->序列化
  • 序列化a.b.a,级别=2(2<2不正确)-> 停止

提前感谢。

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

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


关于。

不支持基于级别的Ignoral


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

我最近遇到了一个类似的问题:Jackson-(避免循环)

因此,解决方案是升级到Jackson 2.0,并向类添加以下注释:

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

这非常有效。

在某些情况下,可以使用包含最大深度的线程本地整数限制序列化深度。见此。

有关深度序列化,如果您想将自己限制为一个级别(即:转到当前对象的子对象,而不是更高级别),可以参考此处的示例。

有一个简单的解决方案@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
}
然后,序列化时,使用对象类作为视图。序列化的实例将呈现以下内容:

{
  id: 42,
  b: {
    id: 813
  }
}
确保默认的_VIEW_INCLUSION设置为true,否则将不会呈现没有@JsonView注释的字段。或者,您可以使用对象类或任何公共超类使用@JsonView注释所有其他字段:

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

  constructors...
  getters and setters
}

经过几个月和大量的研究,我已经实现了我自己的解决方案,以保持我的域没有jackson依赖关系

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);
}
ObjectMapper om=new ObjectMapper();
类[]定义=双向定义.Class.getDeclaredClasses();
for(类定义:定义){
om.addMixinNotations(definition.getAnnotation(JsonIdentityInfo.class).scope(),definition);
}

您最终找到了一种方法来指定要进行序列化的递归深度吗?我通过对引用的实体(使用递归)使用@JsonIgnore来解决这个问题,所以我不将其包含在序列化中。当我需要特定的实例时,我已经有了ID,我会另外调用来获取实例。我没有使用一个通用的解决方案,幸运的是我有几个案例。这是一个非常好的方法。但是你知道限制图表深度的方法吗?很好,谢谢。注意:属性的默认值是“@id”,因此可以在这里省略它(请参阅JsonIdentityInfo=>String property()的源代码默认值“@id”)。您可以在这里给出一些指针吗。谢谢