【问题标题】:Map JSON objects to Java Classes将 JSON 对象映射到 Java 类
【发布时间】:2019-05-21 22:52:29
【问题描述】:

我有一个解析为 JSON 的文件系统结构:

{
    "name": "rootf",
    "type": "system",
    "path": "Parsing/rootf",
    "children": [{
        "name": "f1",
        "type": "folder",
        "path": "Parsing/rootf/f1",
        "children": [{
            "name": "subf1",
            "type": "folder",
            "path": "Parsing/rootf/f1/subf1",
            "children": [{
                "name": "text1.txt",
                "type": "file",
                "path": "Parsing/rootf/folder1/subf1/text1.txt",
                "children": ["a", "b", "c"]
            }]
        }, {
            "name": "subf2",
            "type": "folder",
            "path": "Parsing/rootf/f1/subf2",
            "children": []
        }, {
            "name": "text2.txt",
            "type": "file",
            "path": "TParsing/rootf/f1/text2.txt",
            "children": ["d", "e", "f"]
        }]
    }, {
        "name": "text1.txt",
        "type": "file",
        "path": "Parsing/rootd/text1.txt",
        "children": ["aa", "bb"]
    }],
    "_id": "5ce47292d866fc2f40037a56"
}

可以看出system 类型的children(表示根文件夹)和folder 类型(表示根文件夹的子文件夹)可以包含其他文件夹和/或文件。 children 类型为 file 包含文件的内容。

我稍后需要访问 folder 类型和 file 类型的单个对象。将其映射到 Java 对象的最有效方法是什么?如何单独访问它们?

我最初尝试使用 GSON 将其映射到三个类,System.javaFolder.javaFile.java,它们分别包含 private List<Folder> childrenprivate List<File> childrenprivate List<String> children。这仅在我具有特定的 JSON 结构(RootFolder->Sub-Folder->File)时才有效。有什么方法可以使映射更通用,以便它包含System 可以包含FolderFile 的条件,同样,Folder 可以包含FolderFile

【问题讨论】:

  • 为什么你不能有一个System 类和List<Children> 并且一个孩子可以是一个文件夹或文件,因为它有一个类型参数?如果真的要多态的话可以参考这些链接stackoverflow.com/questions/30362446/…stackoverflow.com/questions/5800433/polymorphism-with-gsonstackoverflow.com/questions/15736654/…
  • @AbhijithNagarajan,您能告诉我如何从中访问单个 filefolder 对象吗?实际上,对于System,我需要构建一组components 对象。此components 集应包含System 内的文件和文件夹对象。我对如何做到这一点有点困惑。
  • 你能用这个创建一个树结构吗?
  • @Hades,对不起,我不明白。我应该从什么创建树结构,为什么需要它?你能澄清一下吗?
  • 一棵树将包含根文件夹作为其节点,并包含进一步的子节点作为其子节点,stackoverflow.com/questions/19330731/…

标签: java json gson


【解决方案1】:

JSON 中有一个问题,如果它的文件或文件夹内容表示为 children,因此我尝试了一种方法,如果它有集合使用正则表达式的字符串,其中没有任何 JSON 对象。完成后,我只需要一个类,即在我的情况下的文件夹,将其解析为 JSON 到 java 类。
所以我的课如下。

class Folder{  //Can be either system or folder
    private String name;
    private String type;
    private String path;
    private List<Folder> children; //To contain subFolder
    private List<String> file; //To contain list of files
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getPath() {
        return path;
    }
    public void setPath(String path) {
        this.path = path;
    }
    public List<Folder> getChildren() {
        return children;
    }
    public void setChildren(List<Folder> children) {
        this.children = children;
    }
    public List<String> getFile() {
        return file;
    }
    public void setFile(List<String> file) {
        this.file = file;
    }
    @Override
    public String toString() {
        return "Folder [name=" + name + ", type=" + type + ", path=" + path + "\n, children=" + children + ", file="
                + file + "]";
    }
}

转换密钥然后将其解析为此类的代码

public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        String contents = new String(Files.readAllBytes(Paths.get("C:\\Users\\Sample.json"))); //Java 7 to read JSON into String from file

        Pattern pattern = Pattern.compile("\"children\":\\s*\\[\\s*[\"a-zA-Z\",\\s*]*]",Pattern.MULTILINE); //Pattren to find list of file i.e. content
        Matcher matcher = pattern.matcher(contents);
        while(matcher.find()) {
            String group = matcher.group();
            String newGroup = matcher.group().replaceAll("\"children\"", "\"file\"");
            contents = contents.replace(group, newGroup);
        }
        Folder folder = objectMapper.readValue(contents, Folder.class);
        System.out.println(folder);

    }

输出

Folder [name=rootf, type=system, path=Parsing/rootf
, children=[Folder [name=f1, type=folder, path=Parsing/rootf/f1
, children=[Folder [name=subf1, type=folder, path=Parsing/rootf/f1/subf1
, children=[Folder [name=text1.txt, type=file, path=Parsing/rootf/folder1/subf1/text1.txt
, children=null, file=[a, b, c]]], file=null], Folder [name=subf2, type=folder, path=Parsing/rootf/f1/subf2
, children=null, file=[]], Folder [name=text2.txt, type=file, path=TParsing/rootf/f1/text2.txt
, children=null, file=[d, e, f]]], file=null], Folder [name=text1.txt, type=file, path=Parsing/rootd/text1.txt
, children=null, file=[aa, bb]]], file=null]

现在您有了一个层次结构,即根目录下的系统,其中包含文件夹和文件。

【讨论】:

    【解决方案2】:

    如果您将Folder 对象扩展为同时具有private List&lt;Folder&gt; subfoldersprivate List&lt;File&gt; files,并让System 对象成为一个特殊的Folder 对象,那么您最初的想法似乎很好。这将允许您表示数据的布局和任何类似的东西。唯一的限制是只有文件夹可以包含文件和其他文件夹作为子项,文件只能包含字符串作为子项。

    【讨论】:

    • 限制没问题,因为文件夹对象将只包含文件和其他文件夹,我需要文件的内容作为字符串。 “使系统对象成为一个特殊的文件夹对象。” - 这是什么意思?另外,我需要访问单个对象,因为我的System.java 扩展了一个抽象类,并且我有一个方法可以为system 返回一组components(所有嵌套文件和文件夹)。类似地,Folder.javaFile.java 扩展了一个抽象类,我有一个方法可以返回特定的 component 所属的 system
    • 另一个问题是 GSON 如何将文件映射到 private List&lt;File&gt; files 并将子文件夹映射到 private List&lt;Folder&gt; subfolders,因为在 JSON 中它位于 children 数组中?你能否提供一个具体的例子来说明我如何做到这一点?
    猜你喜欢
    • 2013-04-17
    • 2017-12-24
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 2014-08-03
    • 2012-04-23
    • 2014-11-02
    • 2013-01-26
    相关资源
    最近更新 更多