Getting stackoverflowerror from Gson while converting hashmap to JSON object

前端 未结 1 1739
栀梦
栀梦 2021-01-20 18:11

I want to represent data in tree structure as java object then I want to convert it to JSON object.

With the help of stackoverflow entries:

Convert java arr

相关标签:
1条回答
  • 2021-01-20 18:52

    You didn't include your Node class definition, but I'm guessing it looks something like this:

    public class Node {
      public final String id;
      public Node parent;
      public final ArrayList<Node> children = new ArrayList<>();
    
      public Node(String id) {
        this.id = id;
      }
    }
    

    This is a fine way to represent a tree data structure in memory (ignoring some unrelated style issues like using public fields), but it's impossible to serialize. Why? Because any Node with a non-null parent has a cyclical relationship - a child contains a reference to its parent, which in turn contains a reference to the child, which in turn contains a reference to the parent, which in turn contains .....

    From the user guide:

    Note that you can not serialize objects with circular references since that will result in infinite recursion.

    We can trigger the same error with this simpler example:

    Node root = new Node("A");
    Node child = new Node("B");
    root.children.add(child);
    child.parent = root;
    System.out.println(new Gson().toJson(root)); // passing in child would similarly fail
    

    So how can we fix this? It depends on what behavior you want. One easy option is to prevent Gson from attempting to serialize the parent field (we don't need it, as we can reconstruct it from the children list). To do this just mark parent as transient and Gson will not include it in the result. You could similarly make children the transient field if explicitly recording the parent relationship is more helpful. A benefit of serializing the children field however is that you can just pass in the root node and the whole tree will be traversed.

    Another option is to serialize a different data structure than Map<String, Node> - you're currently mapping each node ID to its Node object (which, transitively, contains a reference to every other node), meaning that even if you fix the cyclical relationship you're still going to get some odd JSON as a result. It seems like what you'd really want is to just serialize the ID -> parent or ID -> children relationships, which would be a Map<String, String> or Map<String, List<String>> data structure which Gson will have no trouble serializing. If that's the structure you want you could simply traverse your tree and construct such a data structure first, or define a custom deserializer which converts a Node into the exact JSON structure you want.

    0 讨论(0)
提交回复
热议问题