创建嵌套的JSON

问题描述 投票:0回答:2

我有像这样的mysql表

Parent | Child
LevelOne LevelTwo
LevelOne LevelThree
LevelTwo LevelFour
LevelTwo LevelFive
LevelFour LevelSix

我把它们存储在像这样的ArrayList中

LevelOne | LevelTwo
LevelOne |LevelThree
LevelTwo | LevelFour
LevelTwo |LevelFive
LevelFour |LevelSix

我试图将其转换为JSON。这是我到目前为止所尝试的 -

for(String v : values){
    String p = v.substring(0,v.indexOf("|"));//Parent
    String c = v.substring(v.indexOf("|")+1);//Child                        
    ObjectNode objectNode1 = mapper.createObjectNode();
    objectNode1.put("Parent", p);
    objectNode1.put("Children",c);
    arrayNode.add(objectNode1);
}
            System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(arrayNode));

然而这是错误的,因为它打印像这样

[ {
  "Folder" : "LevelOne",
  "Folder" : "LevelTwo"
}, {
  "Folder" : "LevelOne",
  "Folder" : "LevelThree"
}, {
  "Folder" : "LevelTwo",
  "Folder" : "LevelFour"
}, {
  "Folder" : "Horror",
  "Folder" : "Werewolf"
}, and so on.

代替

{
    "folder": "LevelOne",
    "subfolders": [
        {
            "folder": "LevelTwo",
            "subfolders": [
                {
                    "folder": "LevelFour",
                    "subfolders": [
                        {
                            "folder": "LevelSix"
                        }
                    ]
                },
                {
                    "folder": "LevelFive"
                }
            ]
        },
        {
            "folder": "LevelThree"
        }
    ]
}

请你就这样格式化建议吗?

java json jackson
2个回答
0
投票

所以这是您要解决的问题的解决方案。

它虽然没有经过优化,但可以重构。

此外,它不处理同一节点存在两个父项的用例。

 public static void main(String[] args) throws JsonProcessingException {
        ArrayList<String> values = new ArrayList<>();
        values.add("LevelOne | LevelTwo");
        values.add("LevelOne |LevelThree");
        values.add("LevelTwo | LevelFour");
        values.add("LevelTwo |LevelFive");
        values.add("LevelFour |LevelSix");

        ObjectMapper mapper = new ObjectMapper();

        ArrayNode arrayNode = new ArrayNode(JsonNodeFactory.instance);

        for(String value : values){
            String parent = value.substring(0,value.indexOf("|")).trim();

            if(!arrayNode.findValuesAsText("folder").contains(parent)) {
                buildNode(values, mapper, arrayNode, parent);
            }

        }
        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(arrayNode));
    }

//这将开始建立节点

     private static void buildNode(ArrayList<String> values, ObjectMapper mapper, ArrayNode arrayNode, String parent) {
            ObjectNode rootNode = mapper.createObjectNode();

            rootNode.put("folder", parent);
            ArrayNode arrayNodeSubFolder = getSubFolders(values, mapper, parent);
            if(arrayNodeSubFolder.size() != 0)
                rootNode.put("subfolders", arrayNodeSubFolder);

            arrayNode.add(rootNode);
        }

//这将扫描和触发添加子节点

    private static ArrayNode getSubFolders(ArrayList<String> values, ObjectMapper mapper, String parent) {
        ArrayNode arrayNode = new ArrayNode(JsonNodeFactory.instance);
        for (String val : values) {
            String currentParent = val.substring(0,val.indexOf("|")).trim();//Parent
            if(currentParent.equals(parent)) {
                String child = val.substring(val.indexOf("|") + 1).trim();//Child
                buildNode(values, mapper, arrayNode, child);
            }

        }
        return arrayNode;
    }

此外,我建议使用更好的数据结构来表示输入数据。但是,此代码特别根据您的用例


0
投票

首先,我建议在mysql中创建树结构,即在单独的列中保存父引用而不是子引用。这消除了冗余:

FolderName  | Parent
-------------------------
"LevelOne"  | null
"LevelTwo"  | "LevelOne"
"LevelThree"| "LevelOne"
"LevelFour" | "LevelTwo"
"LevelFive" | "LevelTwo"
"LevelSix"  | "LevelFour"

将实体加载到数组列表(6个元素)后,可以根据“父”字段对它们进行排序(顺序实际上与上表中的顺序相同。最后,当您遍历集合时,迭代树从上到下,所以在每次迭代中,创建一个节点并将其添加到相应的父对象。我强烈建议使用Objects而不是字符串作为元组的表示。

© www.soinside.com 2019 - 2024. All rights reserved.