问题描述
我正在尝试将带有jackson的DefaultMutableTreeNode对象序列化为json字符串.因此,我需要使用一种混合类抽象类,该类是DefaultMutableTreeNode类的代理.这可能是由于自参考字段,但我无法识别它们.
I am trying to serialize a DefaultMutableTreeNode oject with jackson into a json string. Therefore i need to use a mix-in abstract class that is kind of a proxy to the DefaultMutableTreeNode class. This is probably because of self-reference fields but i am not able to recognize them.
混合类:
@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是类型为DefaultMutableTreeNode的对象)
(serverFileTree is an object of type DefaultMutableTreeNode)
错误跟踪:
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
推荐答案
当您开始遍历其getters方法时,此类将生成循环.要打破它们,您需要使用JsonBackReference
批注.您的mixin
可能看起来像这样:
This class generate cycles when you start travers theirs getters methods. To break them, you need to use JsonBackReference
annotation. Your mixin
could look like this:
@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();
}
但是最好和最OOP
的方式可能是创建新的POJO
,它表示您的树已准备好进行序列化并且没有循环.
But probably the best and most OOP
way is to create new POJO
which represents your tree ready for serialisation and without cycles.
这篇关于为什么即使使用@JsonIgnoreProperties,在使用杰克逊时也会出现stackoverflow错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!