Сопоставить объекты JSON с классами Java - PullRequest
0 голосов
/ 22 мая 2019

У меня есть структура файловой системы, проанализированная как 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"
}

Как видно children типа system (обозначает корневую папку) и типа folder (обозначает суб-файл).папки корневой папки) могут содержать другие папки и / или файл.children типа file содержит содержимое файла.

Позже мне потребуется доступ к отдельным объектам типа folder и типа file.Что было бы наиболее эффективным способом сопоставить это с объектами Java и как я могу получить к ним доступ по отдельности?

Изначально я пытался использовать GSON для сопоставления его с тремя классами, System.java, Folder.java и File.java, в которых они содержали private List<Folder> children, private List<File> children и private List<String> children соответственно.Это работает только тогда, когда у меня есть определенная структура JSON (RootFolder-> Sub-Folder-> File).Можно ли как-нибудь сделать отображение более обобщенным, чтобы оно включало условие, что System может содержать Folder и File и, аналогично, Folder может содержать Folder и File?

Ответы [ 2 ]

0 голосов
/ 23 мая 2019

Был один улов в JSON, что содержимое было представлено как children, если его файл или папка, поэтому я попробовал подход, при котором я заменил ключ children JSON на file, если у него есть коллекциястрока без любого объекта 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]

теперь у вас есть иерархия, т.е. система в корне с папками и файлом внутри нее.

0 голосов
/ 22 мая 2019

Ваша первоначальная идея казалась прекрасной, если вы просто расширили объект Folder, чтобы иметь и private List<Folder> subfolders, и private List<File> files, и сделали объект System специальным объектом Folder. Это позволит вам представить макет ваших данных и что-нибудь подобное. Единственное ограничение заключается в том, что только папки могут содержать файлы и другие папки в качестве дочерних, а файлы могут содержать только строки в качестве дочерних.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...