Java 为什么即使使用@JsonIgnoreProperties,在使用jackson时也会出现堆栈溢出错误

Java 为什么即使使用@JsonIgnoreProperties,在使用jackson时也会出现堆栈溢出错误,java,jackson,stack-overflow,mixins,self-reference,Java,Jackson,Stack Overflow,Mixins,Self Reference,我正在尝试将带有jackson的DefaultMutableTreeNode项目序列化为json字符串。因此,我需要在抽象类中使用一个mix,它是DefaultMutableTreeNode类的代理。这可能是因为自参考字段,但我无法识别它们 课堂混合: @JsonIgnoreProperties(ignoreUnknown = true) public abstract class DefaultMutableTreeNodeMixIn { @JsonCreator publi

我正在尝试将带有jackson的DefaultMutableTreeNode项目序列化为json字符串。因此,我需要在抽象类中使用一个mix,它是DefaultMutableTreeNode类的代理。这可能是因为自参考字段,但我无法识别它们

课堂混合:

@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 mapper = new ObjectMapper();
mapper.addMixIn(DefaultMutableTreeNode.class,DefaultMutableTreeNodeMixIn.class);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(serverFileTree);
System.out.println(json);
(serverFileTree是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

如Jackson文件所述:

public@interface JsonProperty

标记注释,可用于将非静态方法定义为 逻辑属性的“setter”或“getter”(取决于其 签名),或要使用的非静态对象字段(序列化, 反序列化)作为逻辑属性

我确实认为您已经注释了不是属性的setter或getter的方法

例如:

@JsonProperty("previousNode")
    abstract DefaultMutableTreeNode getPreviousNode();

这个方法似乎没有得到属性,而是计算一个节点。尝试删除方法上的所有注释,看看它是否解决了问题。

当您开始遍历它们的getter方法时,此类将生成循环。要打破它们,需要使用
JsonBackReference
annotation。您的
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();
}

但是最好的也是最简单的方法可能是创建新的
POJO
,它表示您的树已准备好进行序列化并且没有循环。

您能在这里添加堆栈跟踪吗?现在将其添加到问题摘要中,而不是编写混用,我认为为
DefaultMutableTreeNode
编写
JsonSerializer
会容易得多。“getPreviousNode():在对该节点的树进行预排序遍历时返回该节点前面的节点。”()我确保所有方法在注释它们时都返回值