• 递归解析Json,实现生成可视化Tree+快速获取JsonPath | 京东云技术团队


    内部平台的一个小功能点的实现过程,分享给大家:

    递归解析Json,可以实现生成可视化Tree+快速获取JsonPath

    步骤:

    1.利用JsonPath读取根,获取JsonObject

    2.递归层次遍历JsonObjec,保存结点信息

    3.利用zTree展示结点为可视化树,点击对应树的结点即可获取对应结点的JsonPath

    1.利用JsonPath读取根,获取JsonObject

    示例Json:

    {
      "errorMessage": null,
      "errorCode": null,
      "dates": {
        "tradeAmt": null,
        "riskLevel": "LEVEL30",
        "optSelected": {
          "77": [
            {
              "optionContent": "20-50万元",
              "productCode": null,
              "created": null,
              "optionOrder": null,
              "modified": null,
              "id": 361,
              "optionScore": 8,
              "isInvalid": 1
            }
          ],
          "78": [
            {
              "optionContent": "资产50-500万元,无债务或债务较轻",
              "productCode": null,
              "created": null,
              "optionOrder": null,
              "modified": null,
              "id": 365,
              "optionScore": 6,
              "isInvalid": 1
            }
          ]
        },
        "riskInfoResult": {
          "optLetter": "A",
          "mqOrder": "1",
          "residenceCountryCode": null,
          "taxReason": null,
          "residenceCountryName": null,
          "residenceCountryNameEn": null,
          "countryNameEn": null,
          "taxInfoCode": null,
          "taxInfoIsCompleted": true,
          "taxInfoIsRight": true,
          "countryCode": null,
          "taxId": null,
          "countryName": null,
          "taxReasonInt": null
        },
        "created": 1565654328000,
        "questions": [
          {
            "questionContent": "您的职业?",
            "productCode": null,
            "created": 1498630051000,
            "options": null,
            "questionSource": "BUSINESS",
            "modified": 1498630051000,
            "id": 75,
            "isInvalid": 1,
            "questionType": 1,
            "order": 1
          },
          {
            "questionContent": "您的主要收入来源是?",
            "productCode": null,
            "created": 1498630051000,
            "options": null,
            "questionSource": "BUSINESS",
            "modified": 1498630051000,
            "id": 76,
            "isInvalid": 1,
            "questionType": 1,
            "order": 2
          }
        ],
        "serialCode": "123",
        "isInvalid": 1,
        "expireTime": 1628783999000,
        "productCode": null,
        "modified": 1565654328000,
        "examScore": 56,
        "id": 4564568,
        "results": {
          "77": "361",
          "78": "365"
        },
        "account": "test"
      },
      "status": "SUCCESS"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    Java代码:

    String jsonStr = "";
    Object rootJson = JsonPath.read(jsonStr, "$");
    
    • 1
    • 2

    2.递归层次遍历JsonObjec,保存结点信息

    Java代码

    ZTreeNode zTreeNode = new ZTreeNode();
    zTreeNode.setId("$");
    zTreeNode.setpId("root");
    zTreeNode.setName("root");
    zTreeNode.setDepth(0);
    zTreeNode.setPath("$");
    traverseTree(rootJson, zTreeNode, zTreeNodes);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
        public static void traverseTree(Object rootJson, ZTreeNode zTreeNode, List zTreeNodes) {
            if (rootJson instanceof Map) {
                for (Map.Entry stringObjectEntry : ((Map) rootJson).entrySet()) {
                    ZTreeNode zTreeNodeTemp = new ZTreeNode();
                    zTreeNodeTemp.setDepth(zTreeNode.getDepth() + 1);
                    zTreeNodeTemp.setPath(zTreeNode.getPath() + "." + stringObjectEntry.getKey());
                    zTreeNodeTemp.setId(zTreeNodeTemp.getPath());
                    zTreeNodeTemp.setName(stringObjectEntry.getKey());
                    zTreeNodeTemp.setpId(zTreeNode.getPath());
                    zTreeNodes.add(zTreeNodeTemp);
                    traverseTree(stringObjectEntry.getValue(), zTreeNodeTemp, zTreeNodes);
                }
            } else if (rootJson instanceof List) {
                List json = (List) rootJson;
                for (int i = 0; i < json.size(); i++) {
                    Object obj = json.get(i);
                    ZTreeNode zTreeNodeTemp = new ZTreeNode();
                    zTreeNodeTemp.setDepth(zTreeNode.getDepth() + 1);
                    zTreeNodeTemp.setPath(zTreeNode.getPath() + "[" + i + "]");
                    zTreeNodeTemp.setId(zTreeNodeTemp.getPath());
                    zTreeNodeTemp.setName(zTreeNode.getName() + "[" + i + "]");
                    zTreeNodeTemp.setpId(zTreeNode.getPath());
                    zTreeNodes.add(zTreeNodeTemp);
                    traverseTree(obj, zTreeNodeTemp, zTreeNodes);
                }
            } else {
                // do nothing
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    3.利用zTree展示结点为可视化树,点击对应树的结点即可获取对应结点的JsonPath

    前端代码:

    let zTreeObj;
    // zTree 的参数配置
    let setting = {
        data: {
            simpleData: {
                enable: true
            }
        },
        callback: {
            onClick: zTreeOnClick
        }
    };
    zTreeObj = $.fn.zTree.init($("#using_json"), setting, zNodes);
    zTreeObj.expandAll(true);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    4.扩展:将结点信息反向解析

    递归解析zNodes+利用nestable插件可视化展示,效果如下:

    前端代码:

            let detailResult = JSON.parse(zNodes);
            let nestableContent = $('
      '); let dataId = 0; // 遍历解析Json function parseJson(jsonObj, nestableContent, dataId) { for (let key in jsonObj) { let element = jsonObj[key]; if (element === null) { element = "null"; } if (element.length > 0 && typeof (element) == "object" || typeof (element) == "object") { var li = $('
    1. '); $(li).append('
      ' + ' ' + key + '' + '
      ').append('
        ').appendTo(nestableContent); parseJson(element, $(li).children().eq(1), dataId); } else { dataId++; $('
      1. ').append('
        ' + ' ' + key + '' + element + '
        ').appendTo(nestableContent); } } }
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27

        作者:京东科技 周波

        来源:京东云开发者社区 转载请注明来源

      2. 相关阅读:
        基于Kylin Server V10制作Kylin 4.0.2 server sp2虚拟机镜像
        全新整合热搜榜单热门榜单内容系统聚合源码/带教程安装
        分布式锁的实现原理
        【Rust日报】2022-07-23 ​用 Rust 编写的强类型 Elasticsearch DSL
        PAT 1003 Emergency
        JAVA设计模式-备忘录模式
        sqlmap 攻击
        华为OD机试 - 单词接龙 - 数据结构map、list (Java 2023 B卷 100分)
        题目0155-特异性双端队列
        平台H5对接支付宝支付接口(含分布式源码)
      3. 原文地址:https://blog.csdn.net/JDDTechTalk/article/details/133635720