2

我需要将一些 JSON 反序列化为包含 TreeNodes 和 NodeData 的 Java 树结构。TreeNodes 是围绕 NodeData 的瘦包装器。我将提供 JSON 和下面的类。我查看了通常的 Gson 帮助资源,包括这里,但我似乎无法提出解决方案。

序列化适用于 Gson。下面的 JSON 由 Gson 生成。但是反序列化是我需要帮助的问题。有人可以告诉我如何编写反序列化器(或建议使用 Gson 最佳实践的替代方法)吗?

这是我的 JSON。“data”元素对应于类 NodeData,“subList”JSON 元素对应于 Java 类 TreeNode。

{
  "data": {
    "version": "032",
    "name": "root",
    "path": "/",
    "id": "1",
    "parentId": "0",
    "toolTipText": "rootNode"
  },
  "subList": [
    {
      "data": {
        "version": "032",
        "name": "level1",
        "labelText": "Some Label Text at Level1",
        "path": "/root",
        "id": "2",
        "parentId": "1",
        "toolTipText": "a tool tip for level1"
      },
      "subList": [
        {
          "data": {
            "version": "032",
            "name": "level1_1",
            "labelText": "Label level1_1",
            "path": "/root/level1",
            "id": "3",
            "parentId": "2",
            "toolTipText": "ToolTipText for level1_1"
          }
        },
        {
          "data": {
            "version": "032",
            "name": "level1_2",
            "labelText": "Label level1_2",
            "path": "/root/level1",
            "id": "4",
            "parentId": "2",
            "toolTipText": "ToolTipText for level1_2"
          }
        }
      ]
    },
    {
      "data": {
        "version": "032",
        "name": "level2",
        "path": "/root",
        "id": "5",
        "parentId": "1",
        "toolTipText": "ToolTipText for level2"
      },
      "subList": [
        {
          "data": {
            "version": "032",
            "name": "level2_1",
            "labelText": "Label level2_1",
            "path": "/root/level2",
            "id": "6",
            "parentId": "5",
            "toolTipText": "ToolTipText for level2_1"
          },
          "subList": [
            {
              "data": {
                "version": "032",
                "name": "level2_1_1",
                "labelText": "Label level2_1_1",
                "path": "/root/level2/level2_1",
                "id": "7",
                "parentId": "6",
                "toolTipText": "ToolTipText for level2_1_1"
              }
            }
          ]
        }
      ]
    }
  ]
}

以下是 Java 类:

public class Tree {

    private TreeNode rootElement;
    private HashMap<String, TreeNode> indexById;
    private HashMap<String, TreeNode> indexByKey;
    private long nextAvailableID = 0;

    public Tree() {
        indexById = new HashMap<String, TreeNode>();
        indexByKey = new HashMap<String, TreeNode>();
    }

    public long getNextAvailableID()
    {
        return this.nextAvailableID;
    }
    ...
    [snip]
    ...
}

public class TreeNode {

    private Tree tree;
    private NodeData data;
    public List<TreeNode> subList;
    private HashMap<String, TreeNode> indexById;
    private HashMap<String, TreeNode> indexByKey;

    //this default ctor is used only for Gson deserialization
    public TreeNode() {
        this.tree = new Tree();
        indexById = tree.getIdIndex();
        indexByKey = tree.getKeyIndex();
        this.makeRoot();
        tree.setRootElement(this);
    }

    //makes this node the root node. Calling this obviously has side effects.
    public NodeData makeRoot() {
        NodeData rootProp = new NodeData(TreeFactory.version, "example", "rootNode");

        String nextAvailableID = getNextAvailableID();
        if (!nextAvailableID.equals("1")) {
            throw new IllegalStateException();
        }

        rootProp.setId(nextAvailableID);
        rootProp.setParentId("0");
        rootProp.setKeyPathOnly("/");
        rootProp.setSchema(tree);
        this.data = rootProp;
        rootProp.setNode(this);
        indexById.put(rootProp.getId(), this);
        indexByKey.put(rootProp.getKeyFullName(), this);
        return rootProp;
    }

    ...
    [snip]
    ...
}

public class NodeData {

    protected static Tree tree;
    private LinkedHashMap<String, String> keyValMap;

    protected String version;
    protected String name;
    protected String labelText;
    protected String path;
    protected String id;
    protected String parentId;
    protected TreeNode node;
    protected String toolTipText;//tool tip or help string
    protected String imagePath;//for things like images; not persisted to properties
    protected static final String delimiter = "/";

    //this default ctor is used only for Gson deserialization
    public NodeData() {
        this("NOT_SET", "NOT_SET", "NOT_SET");
    }

    ...
    [snip]
    ...
}

旁注:树数据结构有点奇怪,因为它包含索引。显然,这不是典型的搜索树。实际上,树主要用于在每个 NodeData 元素中创建分层路径元素(String)。(例如:“path”:“/root/level2/level2_1”。)索引实际上用于 NodeData 检索。

4

0 回答 0