[英]Why do i get an stackoverflow error when using jackson even though using @JsonIgnoreProperties
I am trying to serialize a DefaultMutableTreeNode oject with jackson into a json string. 我试图将与杰克逊的DefaultMutableTreeNode对象序列化为json字符串。 Therefore i need to use a mix-in abstract class that is kind of a proxy to the DefaultMutableTreeNode class.
因此,我需要使用一种混合类抽象类,该类是DefaultMutableTreeNode类的代理。 This is probably because of self-reference fields but i am not able to recognize them.
这可能是由于自参考字段,但我无法识别它们。
Mix-in class: 混合类:
@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class DefaultMutableTreeNodeMixIn {
@JsonCreator
public DefaultMutableTreeNodeMixIn(@JsonProperty Object userObject) {};
@JsonCreator
public DefaultMutableTreeNodeMixIn(@JsonProperty Object userObject,
@JsonProperty boolean allowsChildren) {};
@JsonProperty("childCount")
abstract int getChildCount();
@JsonProperty("depth")
abstract int getDepth();
@JsonProperty("firstChild")
abstract TreeNode getFirstChild();
@JsonProperty("firstLeaf")
abstract DefaultMutableTreeNode getFirstLeaf();
@JsonProperty("lastChild")
abstract TreeNode getLastChild();
@JsonProperty("lastLeaf")
abstract DefaultMutableTreeNode getLastLeaf();
@JsonProperty("leafCount")
abstract int getLeafCount();
@JsonProperty("level")
abstract int getLevel();
@JsonProperty("nextLeaf")
abstract DefaultMutableTreeNode getNextLeaf();
@JsonProperty("nextNode")
abstract DefaultMutableTreeNode getNextNode();
@JsonProperty("nextSibling")
abstract DefaultMutableTreeNode getNextSibling();
@JsonProperty("parent")
abstract TreeNode getParent();
@JsonProperty("path")
abstract TreeNode[] getPath();
@JsonProperty("previousLeaf")
abstract DefaultMutableTreeNode getPreviousLeaf();
@JsonProperty("previousNode")
abstract DefaultMutableTreeNode getPreviousNode();
@JsonProperty("previousSibling")
abstract DefaultMutableTreeNode getPreviousSibling();
@JsonProperty("siblingCount")
abstract int getSiblingCount();
@JsonProperty("isLeaf")
abstract boolean isLeaf();
@JsonProperty("isRoot")
abstract boolean isRoot();
}
ObjectMapper: ObjectMapper:
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(DefaultMutableTreeNode.class,DefaultMutableTreeNodeMixIn.class);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(serverFileTree);
System.out.println(json);
(serverFileTree is an object of type DefaultMutableTreeNode) (serverFileTree是类型为DefaultMutableTreeNode的对象)
Error trace: 错误跟踪:
at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:252)
at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serialize(ObjectArraySerializer.java:213)
at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serialize(ObjectArraySerializer.java:22)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) [...]
Caused by: java.lang.StackOverflowError
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:737)
... 1011 more
As stated in the documentation of Jackson: https://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonProperty.html 如Jackson的文档所述: https : //fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonProperty.html
public @interface JsonProperty
公共@interface JsonProperty
Marker annotation that can be used to define a non-static method as a "setter" or "getter" for a logical property (depending on its signature), or non-static object field to be used (serialized, deserialized) as a logical property.
标记批注,可用于将非静态方法定义为逻辑属性的“设置者”或“获取器”(取决于其签名),或将要用作逻辑属性的非静态对象字段(序列化,反序列化)属性。
I do think that you've annoted methods that are not setter or getter of properties. 我确实认为您注释了不是属性的setter或getter的方法。
For example: 例如:
@JsonProperty("previousNode")
abstract DefaultMutableTreeNode getPreviousNode();
This method doesn't seems to not get a property, it's computing a node instead. 该方法似乎没有获得属性,而是计算节点。 Try to remove all the annotations on the methods to see if it solve the issue.
尝试删除方法上的所有注释,看看它是否可以解决问题。
This class generate cycles when you start travers theirs getters methods. 当您开始遍历其getter方法时,此类会生成循环。 To break them, you need to use
JsonBackReference
annotation. 要打破它们,您需要使用
JsonBackReference
批注。 Your mixin
could look like this: 您的
mixin
可能如下所示:
@JsonIgnoreProperties(ignoreUnknown = true)
abstract class DefaultMutableTreeNodeMixIn {
@JsonCreator
public DefaultMutableTreeNodeMixIn(@JsonProperty Object userObject) {
}
@JsonCreator
public DefaultMutableTreeNodeMixIn(@JsonProperty Object userObject, @JsonProperty boolean allowsChildren) {
}
@JsonProperty("childCount")
abstract int getChildCount();
@JsonProperty("depth")
abstract int getDepth();
@JsonProperty("firstChild")
@JsonBackReference
abstract TreeNode getFirstChild();
@JsonProperty("firstLeaf")
@JsonBackReference
abstract DefaultMutableTreeNode getFirstLeaf();
@JsonProperty("lastChild")
@JsonBackReference
abstract TreeNode getLastChild();
@JsonProperty("lastLeaf")
@JsonBackReference
abstract DefaultMutableTreeNode getLastLeaf();
@JsonProperty("leafCount")
abstract int getLeafCount();
@JsonProperty("level")
abstract int getLevel();
@JsonProperty("nextLeaf")
abstract DefaultMutableTreeNode getNextLeaf();
@JsonProperty("nextNode")
abstract DefaultMutableTreeNode getNextNode();
@JsonProperty("nextSibling")
abstract DefaultMutableTreeNode getNextSibling();
@JsonProperty("parent")
abstract TreeNode getParent();
@JsonProperty("path")
@JsonBackReference
abstract TreeNode[] getPath();
@JsonProperty("previousLeaf")
abstract DefaultMutableTreeNode getPreviousLeaf();
@JsonProperty("previousNode")
abstract DefaultMutableTreeNode getPreviousNode();
@JsonProperty("previousSibling")
abstract DefaultMutableTreeNode getPreviousSibling();
@JsonProperty("siblingCount")
abstract int getSiblingCount();
@JsonProperty("isLeaf")
abstract boolean isLeaf();
@JsonProperty("isRoot")
abstract boolean isRoot();
}
But probably the best and most OOP
way is to create new POJO
which represents your tree ready for serialisation and without cycles. 但是最好的也是最
OOP
方法是创建新的POJO
,它表示您的树已准备好进行序列化且没有循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.