DEV/Java

[java 기초] json.simple 활용 JSON 데이터 저장, 불러오기

Bi3a 2023. 10. 25. 17:23

728x90

java 기초 깨부시기

 

 

 

Table of Contents

     

     


    누군가 java 기초가 어디까지냐고 물으면, 내가 모르는 부분까지라고 답할 것이다

     

     

     

    JSON의 이해

    JSON은 `JavaScript Object Notation` 의 약자로, 자바 스크립트 객체 표기법입니다.
    서버와 클라이언트간 데이터를 보낼 때 쉽게 교환하고 저장하는 텍스트 기반의 양식입니다.
    자바스크립트의 일부로 등장했으나 2000년대를 넘어가며 데이터 기술 교환의 보편 매체로 발전했습니다.

     

     

    JSON이 각광받는 이유

    • 기존의 데이터 교환의 지배적 양식인 XML의 대안으로 적합하였습니다.
      • 가독성의 향상, 텍스트 형식의 교환 용이
    • 자바스크립트의 구문을 따르나 언어 독립형 데이터 포맷으로 언어나 플랫폼의 구애를 받지 않습니다.

     

     

    JSON 코드 읽는 법

    { key1 : value1, key2 : value2, key3 : [value4, value5, value6] }
    • JSON의 형태는 `key : value` 의 구조입니다. 
    • 여러 데이터는 객체 안에서 쉼표로 나열됩니다.
    • 객체는 `{ 중괄호 }` 로 묶어서 표현되며, 배열은 `[ 대괄호 ]` 로 묶어서 표현됩니다.

     

     

    java로 JSON 데이터 만들고 저장하기, JSON 데이터 불러오기

    JSON 데이터 저장, 불러오기를 위해 JSON.simple 라이브러리를 활용하겠습니다.

     

     

    0. JSON.simple 라이브러리 적용(intellij 기준)

    • maven 빌드 : 이하의 코드를 maven dependency에 삽입
    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1.1</version>
    </dependency>

    1. `Files` → `View All` → 가장 최상단 `json-simple-1.1.1-javadoc.jar` 다운로드

    2. IntelliJ Project structure `(Ctrl + Shift + Alt + S)` → `Project Settings` → `Modules` 클릭

    3. `Module SDK` 아래의 + 클릭 → `JARs or Directories` 클릭

     

     

    4. 다운받은 .jar 파일 지정 후 `OK` → 다시 `Modules`로 돌아가 `Apply`

     

     

    * 번외 : .jar 파일로 라이브러리 import이 정상적으로 안될 경우(gradle)

    아래 코드를 `build.gradle` 파일의 dependency 에 직접 추가해봅니다.

     

    implementation 'com.googlecode.json-simple:json-simple:1.1.1'

     


     

    1. java 출력 → JSON 데이터로 파일 저장하기

     

    1. 필요 라이브러리

    import org.json.simple.JSONArray; // JSON 데이터 → JSON 데이터 배열(객체)로
    import org.json.simple.JSONObject; // java 데이터 → JSON 데이터
    
    import java.io.FileWriter; // 파일을 write, 저장용

     

     

    2. JSON 데이터로 저장할 객체 데이터

    class Player {
        int sales; // 연봉
        String name; // 이름
        String sport; // 종목
    
        // 생성자 선언
        Player(int sales, String name, String sport){
            this.sales = sales;
            this.name = name;
            this.sport = sport;
        }
    }

     

     

    3. java 데이터를 JSON 데이터로 변환, 파일 저장하 메소드 구현

    // list에 있는 Player 객체를 JSON 데이터로 저장해 PATH 경로의 파일로 Write 하는 메소드
    public void writeJSON(ArrayList<Player> list, String PATH) throws Exception {
        JSONArray jsonArray = new JSONArray();
    
        // 1. java 객체를 JSON 데이터로 가공
        try {
            for(Player player : list){
                JSONObject jsonObject = new JSONObject();
                // 한 개의 객체 필드를 다 집어넣은 뒤 루프마다 초기화
                jsonObject.put("sales", String.valueOf(player.sales));
                jsonObject.put("name", player.name);
                jsonObject.put("sport", player.sport);
                // jsonobject를 통해 객체 단위로 jsonArray에 add
                jsonArray.add(jsonObject);
            }
            // 2. Filewriter를 통해 JSON 데이터를 JSONString으로 캐스팅 후 파일 저장
            FileWriter fw = new FileWriter(PATH);
            fw.write(jsonArray.toJSONString());
            fw.flush();
            // fw.close() : try catch로 close 생략(자동 닫힘)
        } catch (Exception e) {
            throw new Exception(e);
    }
    1. 클래스 객체 생성 : `FileWriter, JSONObject, JSONArray`
    2. java 객체 → JSON 데이터로 가공 `(객체 → JSONObject → JSONArray)`
      1. 객체의 리스트를 for loop하며 객체의 필드를 `JSONObject` 에 집어넣습니다.
      2. loop의 끝에 한 객체의 모든 필드를 가지고 있는 `JSONObject`를 `JSONArray` 로 넣습니다.
      3. `JSONObject` 를 초기화하며, 1~3단계를 반복합니다.
    3. 가공한 JSON 데이터를 파일로 Write
      1. `FileWriter.write(JSONArray.toJSONString)` : JSON 배열을 `JSONString` 으로 바꿔 저장합니다.
      2. `fw.flush()`로 `FileWriter` 에 저장되어 있는 버퍼를 내리며 외부 파일을 생성합니다.

     

    4. java → JSON 파일 저장 코드 전체 구현

    import java.io.FileWriter;
    import java.util.ArrayList;
    import org.json.simple.JSONArray;
    import org.json.simple.JSONObject;
    
    // JSON 데이터에 넣을 객체
    class Player {
        int sales; // 연봉
        String name; // 이름
        String sport; // 종목
    
        // 생성자 선언
        Player(int sales, String name, String sport) {
            this.sales = sales;
            this.name = name;
            this.sport = sport;
        }
    }
    
    public class JSONTest {
        // list에 있는 Player 객체를 JSON 데이터로 저장해 PATH 경로의 파일로 Write 하는 메소드
        public void writeJSON(ArrayList<Player> list, String PATH) throws Exception {
            JSONArray jsonArray = new JSONArray();
    
            // 1. java 객체를 JSON 데이터로 가공
            try {
                for (Player player : list) {
                    JSONObject jsonObject = new JSONObject();
                    // 한 개의 객체 필드를 다 집어넣은 뒤 루프마다 초기화
                    jsonObject.put("sales", String.valueOf(player.sales));
                    jsonObject.put("name", player.name);
                    jsonObject.put("sport", player.sport);
                    // jsonobject를 통해 객체 단위로 jsonArray에 add
                    jsonArray.add(jsonObject);
                }
                // 2. Filewriter를 통해 JSON 데이터를 JSONString으로 캐스팅 후 파일 저장
                FileWriter fw = new FileWriter(PATH);
                fw.write(jsonArray.toJSONString());
                fw.flush();
                // fw.close() : try catch로 close 생략(자동 닫힘)
            } catch (Exception e) {
                throw new Exception(e);
            }
        }
    
        public static void main(String[] args) throws Exception {
            // 초기 값 세팅
            ArrayList<Player> list = new ArrayList<>();
            list.add(new Player(1000, "Faker", "Esports"));
            list.add(new Player(2000, "Messi", "Football"));
            list.add(new Player(3000, "Jordan", "Basketball"));
            String PATH = "data.json";
    
            JSONTest jsonTest = new JSONTest();
            jsonTest.writeJSON(list, PATH); // 파일 저장하기 실행
        }
    }

     

    5. 구현 결과

    [
      {
        "name": "Faker",
        "sport": "Esports",
        "sales": "1000"
      },
      {
        "name": "Messi",
        "sport": "Football",
        "sales": "2000"
      },
      {
        "name": "Jordan",
        "sport": "Basketball",
        "sales": "3000"
      }
    ]

     

     

     

    2. JSON 데이터 → java로 읽어 값 출력하기

    1. 필요 라이브러리

    import org.json.simple.parser.JSONParser; // JSON 데이터 파싱용
    import org.json.simple.JSONArray; // JSON 데이터 → JSON 데이터 배열(객체)로
    import org.json.simple.JSONObject; // java 데이터 → JSON 데이터
    
    import java.io.FileReader; // 파일을 read, 불러오기용

     

    2. 읽어올 JSON 데이터 : `data.json`

    [
      {
        "name": "Faker",
        "sport": "Esports",
        "sales": "1000"
      },
      {
        "name": "Messi",
        "sport": "Football",
        "sales": "2000"
      },
      {
        "name": "Jordan",
        "sport": "Basketball",
        "sales": "3000"
      }
    ]

     

     

    3. JSON 데이터를 읽어와 파싱 후, java 객체 데이터로 저장하는 메소드 구현

    // 경로에 있는 json 파일을 불러와서 파싱 후 java 객체 데이터로 저장하는 메소드
    public void readJson(ArrayList<Player> list, String PATH) throws Exception {
        // 1. JSON 데이터 불러오기 후 데이터 타입 변환
        // 파싱할 Parser 선언
        JSONParser jsonParser = new JSONParser();
        // FileReader(경로) → Parser 통해 파싱 → java Object 객체로 변환
        try {
            Object object = jsonParser.parse(new FileReader(PATH));
            // Object 객체를 JSONArray 객체(배열)로 형변환
            JSONArray jsonArray = (JSONArray) object;
    
            // JSONArray 배열 내부에서 필드값 가져오기
            if (!jsonArray.isEmpty()) {
                for (int i = 0; i < jsonArray.size(); i++) {
                    // JSONArray 객체를 JSONObject로 형변환하며 배열에서 각 객체를 가져옴
                    JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                    // JSONObject 객체에 있는 객체의 필드값을 매핑하여 가져옴
                    int sales = Integer.valueOf((String) jsonObject.get("sales"));
                    String name = (String) jsonObject.get("name");
                    String sport = (String) jsonObject.get("sport");
                    // 생성자를 통해 list로 add
                    list.add(new Player(sales, name, sport));
                }
            }
        } catch (Exception e) {
            throw new Exception(e);
        }
    }
    1. 클래스 객체 생성 : `JSONParser, FileReader, JSONArray, JSONObject`
    2. JSON 데이터 파일을 불러온 후 데이터 타입 변환
      1. `FileReader` 객체를 통해 경로의 파일을 불러옵니다.
      2. 불러온 `FileReader` 객체를 `JSONParser` 로 파싱합니다.
      3. 파싱한 `JSONParser` 를 `Object` →  `JSONArray` 로 캐스팅합니다.
    3. for loop를 돌며 `JSONArray`의 내부 원소를 get하여 `JsonObject` 객체로 반환합니다.
      1. `JSONArray` 는 `{중괄호로 매핑된 원소들}` 을 get 매핑해 `JSONObject` 로 반환 가능합니다.
      2. 객체 단위로 쪼갠 `JSONObject` 를 통해 기존의 `Player` 의 필드로 get 매핑해 접근합니다.
    4. 매핑한 필드 값을 토대로 객체를 생성해 새로운 리스트에 집어넣습니다.

     

     

    4. JSON → Java 파일 읽어오기 코드 전체 구현

    import java.io.FileReader;
    import java.util.ArrayList;
    import org.json.simple.JSONArray;
    import org.json.simple.JSONObject;
    import org.json.simple.parser.JSONParser;
    
    // JSON 데이터에 넣을 객체
    class Player {
        // ... 생략
        }
    }
    
    public class JSONTest {
        public void writeJSON(ArrayList<Player> list, String PATH) throws Exception {
            // ... 생략
        }
    
        // 경로에 있는 json 파일을 불러와서 파싱 후 java 객체 데이터로 저장하는 메소드
        public void readJson(ArrayList<Player> list, String PATH) throws Exception {
            // 1. JSON 데이터 불러오기 후 데이터 타입 변환
            // 파싱할 Parser 선언
            JSONParser jsonParser = new JSONParser();
            // FileReader(경로) → Parser 통해 파싱 → java Object 객체로 변환
            try {
                Object object = jsonParser.parse(new FileReader(PATH));
                // Object 객체를 JSONArray 객체(배열)로 형변환
                JSONArray jsonArray = (JSONArray) object;
    
                // JSONArray 배열 내부에서 필드값 가져오기
                if (!jsonArray.isEmpty()) {
                    for (int i = 0; i < jsonArray.size(); i++) {
                        // JSONArray 객체를 JSONObject로 형변환하며 배열에서ㅁ 각 객체를 가져옴
                        JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                        // JSONObject 객체에 있는 객체의 필드값을 매핑하여 가져옴
                        int sales = Integer.valueOf((String) jsonObject.get("sales"));
                        String name = (String) jsonObject.get("name");
                        String sport = (String) jsonObject.get("sport");
                        // 생성자를 통해 list로 add
                        list.add(new Player(sales, name, sport));
                    }
                }
            } catch (Exception e) {
                throw new Exception(e);
            }
        }
    
        public static void main(String[] args) throws Exception {
            // 초기 값 세팅
            ArrayList<Player> list = new ArrayList<>();
            list.add(new Player(1000, "Faker", "Esports"));
            list.add(new Player(2000, "Messi", "Football"));
            list.add(new Player(3000, "Jordan", "Basketball"));
            String PATH = "data.json";
    
            JSONTest jsonTest = new JSONTest();
            jsonTest.writeJSON(list, PATH); // 파일 저장하기
    
            ArrayList<Player> list2 = new ArrayList<>();
            jsonTest.readJson(list2, PATH); // 파일 불러오기
            for (Player p : list2) {
                System.out.println("name: " + p.name + " sales: " + p.sales + " sport: " + p.sport);
            }
            /* out :
            name: Faker sales: 1000 sport: Esports
            name: Messi sales: 2000 sport: Football
            name: Jordan sales: 3000 sport: Basketball
            */
        }
    }

     

    5. 구현 결과

    name: Faker sales: 1000 sport: Esports
    name: Messi sales: 2000 sport: Football
    name: Jordan sales: 3000 sport: Basketball

     

     

     


    # 구현 코드

    깃허브로 이동합니다.