java - 为什么我在使用 jackson 时会收到 stackoverflow 错误,即使使用 @JsonIgnoreProperties

标签 java jackson stack-overflow mixins self-reference

我正在尝试使用 jackson 将 DefaultMutableTreeNode 对象序列化为 json 字符串。因此,我需要使用一个混合抽象类,它是 DefaultMutableTreeNode 类的代理。这可能是因为 self 引用字段,但我无法识别它们。

混合类:

@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

最佳答案

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

但最好和最OOP的方法可能是创建新的POJO,它代表你的树准备好序列化并且没有循环。

关于java - 为什么我在使用 jackson 时会收到 stackoverflow 错误,即使使用 @JsonIgnoreProperties,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55008630/

相关文章:

java - 在 jfilechooser 中包含图像缩略图

java - 在 sshj 中处理带有指纹的 "[HOST_KEY_NOT_VERIFIABLE] Could not verify ` ssh-rsa` 主机 key

JavaCC 初学者 - 如何使程序仅接受没有重复项的情况?

java - jackson 在python中的替代品是什么?

java - 如何停止 Spring Boot 将字符串 "2020-02-05 14:20:00"转换为时间戳格式?

c# - Unity Networking : Unity crashes when I call the NetworkManager. singleton.StopClient() 函数

mysql - 嵌套模型的新建和创建操作不保存 user_id

java - 程序终止时如何关闭端口?

java - 使用 Spring @Retryable 和 Jackson json 反序列化

recursion - 为什么永远的循环不会崩溃?为什么无限递归会崩溃?