gson을 활용하여 디렉토리구조 Json형식으로 출력하기

Juseong Han·2023년 2월 2일
1

개요

문득 시간나는 김에 특정 Tree구조를 Json형식으로 parsing하는 유틸을 만들고 싶어졌다.

기본적으로 JsonObject를 사용한 트리구조 출력방식은 다음과 같다.

Gson?

Gson(구글 Gson, Google Gson)은 JSON의 자바 오브젝트의 직렬화, 역직렬화를 해주는 오픈 소스 자바 라이브러리이다.
출처 : https://ko.wikipedia.org/wiki/Gson

데이터 넣기

1. property가 일반적인값을 갖는 경우

ex) { data : 1 } 또는 { data : 'hello' } 의 형식을 의미한다.
이 때는 addProperty(String key, Type value)를 사용한다.
Type에는 String, Boolean, Number, Character가 올 수 있다.

JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("myBrain", "코딩개꿀잼");
// jsonObject = { 'myBrain' : '코딩개꿀잼' }

2. property가 Array일 경우

ex) { data : [1, 2, ...] } 의 형식을 의미한다.
기본적으로 대상이되는 key에 JsonElement중 하나인 JsonArray를 넣어야한다.
JsonArray, JsonObject는 모두 JsonElement 추상클래스의 자식클래스이다.
JsonObject에 JsonElement를 넣을 떄는 add(String key, JsonElement element)를 사용한다.

JsonObject jsonObject = new JsonObject();
jsonObject.add("data", new JsonArray());

여기까지 진행하면 jsonObject는 { data : [] }가 된다.

JsonArray dataArray = jsonObject.get("data").getAsJsonArray();
// 간소화
JsonArray dataArraySimple = jsonObject.getAsJsonArray("data");

위의 방법으로 key값에 해당하는 Array객체를 뽑아올 수 있다. 이후 add(Type item)를 사용하여 값을 추가한다. 별도로 바뀐 Array의 값을 저장하거나 할 필요없다.

이는 감사하게도 GSON생님이 내부적으로 리플렉션을 사용하기 때문이다.

덧붙이자면 reflection을 사용하기 때문에 미리 빈 Object를 지정하지않으면 오류가 발생한다.

하지만 특정 프로퍼티가 Json값을 가질것이라는걸 알고 작업하는 입장에선느 그렇게 불편한점은 아니다. 혹시나 Exception, because of property = "" is not JsonElement 이런식의 예외가 발생한다면 부모 JsonObject에서 자식 JsonElement가 생성되었는지 확인하고 디버깅을 하길 바란다.... 이건 경험담임 진짜로

dataArray.add("코");
dataArray.add("딩");
dataArray.add("맨");
// jsonObject = { data : ['코', '딩', '맨'] }

3. property가 Json인 경우

JsonObject jsonObject = new JsonObject();
jsonObject.add("data", new JsonObject());

JsonObject childJson = jsonObject.getAsJsonObject("data");
childJson.addProperty("myBrain", "개발개꿀잼");

코드작성

위의 내용을 바탕으로 재귀로 구현했다.
줄줄이 소세지 아시죠?

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import java.io.File;
import java.util.Objects;

public class Main {
    public static void main(String[] args) {
        String rootPath = System.getProperty("user.dir");
        File rootFile = new File(rootPath);
        JsonObject jsonObject = new JsonObject();
        jsonObject.add(rootFile.getName(), new JsonObject());
        JsonObject rootObject = jsonObject.getAsJsonObject(rootFile.getName());
        rootObject.add("files", new JsonArray());
        for(File file : Objects.requireNonNull(rootFile.listFiles())) {
            getFiles(jsonObject, file, rootFile);
        }
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        System.out.println(gson.toJson(jsonObject));
    }

    public static void getFiles(JsonObject parent, File file, File parentFile) {
        if(file.isDirectory()) {
            JsonObject thisFolderJsonObj = parent.get(parentFile.getName()).getAsJsonObject();

            thisFolderJsonObj.add(file.getName(), new JsonObject());
            JsonObject childFolder = thisFolderJsonObj.get(file.getName()).getAsJsonObject();
            childFolder.add("files", new JsonArray());

            for (File childFile : Objects.requireNonNull(file.listFiles())) {
                getFiles(thisFolderJsonObj, childFile, file);
            }
        } else {
            JsonObject thisFolderJsonObj = parent.getAsJsonObject(parentFile.getName());
            JsonArray thisFileJsonObj = thisFolderJsonObj.getAsJsonArray("files");
            if(thisFileJsonObj != null) {
                thisFileJsonObj.add(file.getName());
            }
        }
    }
}


코딩시점에는 변수네이밍을 거지같이해놔서 마지막에 수정했다.. 변수이름이 안맞는게 있을 수 있다..

감사합니다.

profile
개발이 하고 싶어요💻 개발이 너무 재밌는 Juseong입니다.🖐

0개의 댓글