Gson,序列化树结构

时间:2011-11-16 22:24:51

标签: tree gson

我正在尝试使用GSon序列化树。这是我要序列化的TreeNode的类:

public class TreeNode {
private TreeNode parent;
private ArrayList<TreeNode> children;
private Object value;
    //methods
}

我的GSon电话看起来像这样:

    TreeNode headNode = getHeadNode();
    Gson gson = new Gson();
    Type typeOfSrc = new TypeToken<TreeNode>(){}.getType();
    String gsonTreeString = gson.toJson(headNode,typeOfSrc);

一旦headNode至少有一个孩子,就会发生堆栈溢出,我不明白为什么。有人能告诉我我做错了吗?

3 个答案:

答案 0 :(得分:1)

成员父指向其父级,其父级指向一个子级,该子级的父级指向父级...

答案 1 :(得分:1)

Will是对的,问题是,存在无限的保存路径。您可以通过不保存父级来解决此问题。您可以在从JSON对象读取时设置父级。为避免保存父级,只需将其设置为瞬态。

public class TreeNode {
private transient TreeNode parent;
private ArrayList<TreeNode> children;
private Object value;
    //methods
}

转换回POJO时,请调用下面的setParent-method。

TreeNode newRoot = gson.fromJson(treeJson, TreeNode.class);
setParents(newRoot);

setParents-method只遍历节点的所有子节点,并将其父节点设置为节点为子节点的节点。

private void setParents(TreeNode root) {
        for (TreeNode  node : root.getChildren()) {
            node.setParent(root);
            setParents(node);
        }
    }

答案 2 :(得分:0)

在Gson中,您可以创建一个自定义适配器来序列化表示树的数据结构。您要序列化节点及其所有子节点。这样做的技巧是递归调用write方法以填充JsonWriter。以下代码适用于您的示例:

public class TreeNodeAdapter extends TypeAdapter<TreeNode> {

    @Override
    public void write(JsonWriter jsonWriter, TreeNode node) throws IOException {
        jsonWriter.beginObject()
                .name("coordinates")
                .jsonValue("\"" + node.getValue + "\"")
                .name("children")
                .beginArray();
        // Recursive call to the children nodes
        for (Node c : node.getChildren()) {
            this.write(jsonWriter, c);
        }
        jsonWriter.endArray()
                .endObject();
    }

    @Override
    public Node read(JsonReader jsonReader) throws IOException {
        return null;
    }
}

然后,要使用TreeNodeAdapter仅使NodeTree无效,并在自定义适配器中使用GsonBuilder来序列化对象。

 NodeTree tree = new NodeTree(...);
        NodeAdapter nodeAdapter = new NodeAdapter();
        GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapter(NodeTree.class, nodeAdapter);
        Gson gson = gsonBuilder.create();
        gson.toJson(tree); // JSON string