Jackson JSON serialization, recursion avoidance by level defining
我使用Jackson库将我的pojo对象序列化为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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序列化对象,那么在序列化对象时,有一定的可能性得到递归。我知道我可以通过使用
是否可以按深度级别限制序列化?
例如,如果级别为2,则序列化将按以下方式进行:
- 序列化A,级别=0(0<2 OK)->序列化
- 序列化A.B,级别=1(1<2正常)->序列化
- 序列化a.b.a,级别=2(2<2不正确)->停止
事先谢谢。
我最近遇到了一个类似的问题:Jackson——具有双向关系的实体的序列化(避免循环)
因此,解决方案是升级到Jackson 2.0,并将以下注释添加到类中:
1 2 3 | @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property ="@id") public class SomeEntityClass ... |
这很管用。
检查以下链接,可能会有所帮助:
- http://wiki.fasterxml.com/jacksonfeaturebidisreferences
- 如何解决由Hibernate双向映射引起的JSON序列化程序中的循环引用问题?
之后的唯一选项是为对象类型创建自己的自定义模块,用于序列化/反序列化。请参见此处:
- http://wiki.fasterxml.com/jacksonhowtocustomerializer
- http://wiki.fasterxml.com/jacksonhowtocustomdeserializer
当做。
不支持基于级别的忽略。
但是您可以让Jackson使用2.0处理循环引用,请参见例如"Jackson 2.0 released"以了解如何使用
如果您只想将自己限制在一个级别(即:转到当前对象的子级,而不是更进一步),那么@jsonview有一个简单的解决方案。
在每个链接到另一个对象的字段上,用当前类作为视图对其进行注释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 } |
号
然后,在序列化时,使用对象类作为视图。序列化的实例将呈现如下情况:
1 2 3 4 5 6 | { id: 42, b: { id: 813 } } |
确保默认的_view_inclusion设置为true,否则将不会呈现没有@jsonview注释的字段。或者,您可以使用对象类或任何常见的超级类,用@jsonview注释所有其他字段:
1 2 3 4 5 6 7 | class A { @JsonView(Object.class) private int id; @JsonView(A.class) private B b; constructors... getters and setters } |
。
有关深度序列化,请参阅以下示例:https://github.com/abid-khan/depth-wise-json-serializer
经过几个月和大量的研究,我已经实现了自己的解决方案,以使我的领域远离杰克逊的依赖性。
1 2 3 4 5 6 7 8 9 10 11 | 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;} } |
首先,您必须以如下方式声明双向关系的每个实体:
1 2 3 4 5 6 7 8 9 | 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{}; } |
。
之后,可以自动配置对象映射器:
1 2 3 4 5 | ObjectMapper om = new ObjectMapper(); Class<?>[] definitions = BidirectionalDefinition.class.getDeclaredClasses(); for (Class<?> definition : definitions) { om.addMixInAnnotations(definition.getAnnotation(JsonIdentityInfo.class).scope(), definition); } |
。
在某些情况下,可以使用保持最大深度的线程局部整数来限制序列化深度。看看这个答案。