本文介绍了为什么即使使用@JsonIgnoreProperties,在使用杰克逊时也会出现stackoverflow错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将带有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错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 09:35