DEV/Java

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

Bi3a 2023. 10. 25. 17:23

728x90

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

 

 

 


# 구현 코드

깃허브로 이동합니다.