简体   繁体   English

为什么即使使用@JsonIgnoreProperties,在使用杰克逊时也会出现stackoverflow错误

[英]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.

相关问题 为什么即使使用锁,也会出现ConcurrentModificationException? - Why I get ConcurrentModificationException even though I am using locks? 为什么会出现Stackoverflow错误? - Why do I get a Stackoverflow Error? 为什么我会收到此递归 stackoverflow 错误? - Why do I get this recursion stackoverflow error? 为什么在使用Spring HATEOAS Jackson序列化器时收到警告 - Why do I get warnings when using Spring HATEOAS Jackson serializers 当我使用“n--”而不是“n-1”时,为什么会出现 stackoverflow 错误? - When I use "n--" instead of "n-1" why do I get stackoverflow error? 即使我的 for 循环中有一个 return 语句,为什么我会因为没有 return 语句而收到错误消息? - Why do I get an error for not having a return statement even though I have one in my for loop? 为什么即使文件存在,我也会收到“java.nio.file.NoSuchFileException”错误? - Why do I get an “java.nio.file.NoSuchFileException” error even though the file exists? 即使实现了Iterable,为什么也会出现foreach编译器错误? - Why do I get a foreach compiler error even though Iterable is implemented? StackOverflow使用.setValue时出错 - StackOverflow Error when using .setValue 为什么即使 MethodHandle 没问题,在 invokeExact 上也会得到 WrongMethodTypeException - Why do I get a WrongMethodTypeException on invokeExact even though MethodHandle is OK
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM