HOWTO · Java

Java에서 JSON 배열 다루기

이 기사에서는 JSON 프레임워크, 구조, 데이터 유형 및 Java에서의 사용에 대해 설명합니다.

이 페이지의 내용

Java에서 파일의 JSON 배열을 읽으려면 JSON.simple 같은 JSON 파서를 프로젝트에 추가하고, 파일을 파싱한 뒤 결과 배열을 순회하면 됩니다. Java 표준 라이브러리에는 범용 JSON 파서가 포함되어 있지 않습니다. JSON.simple은 외부 의존성이므로 프로젝트의 빌드 도구나 의존성 관리자를 사용해 추가해야 합니다.

JSON.simple에는 여러 릴리스와 API 계열이 있습니다. 아래 예제는 org.json.simple API 계열을 사용합니다. 사용하기 전에 릴리스를 선택하고 해당 릴리스 문서에서 의존성 좌표, 파서 API, 값 유형을 확인하세요. 여기서는 특정 릴리스나 빌드 도구를 가정하지 않습니다. 선택한 릴리스의 패키지나 메서드 시그니처가 다르면 관련 없는 의존성 선언을 그대로 복사하지 말고 해당 릴리스 문서에 맞게 예제를 조정하세요.

Java에서 JSON 배열 다루기

JSON(JavaScript Object Notation)은 객체, 배열, 문자열, 숫자, 불리언, null을 사용해 데이터를 표현합니다. Java 코드에서 JSON 텍스트를 사용할 수 있는 값으로 바꾸려면 파서가 필요합니다. JSON.simple은 이 파싱 단계에 사용할 수 있는 라이브러리 중 하나입니다.

배열은 대괄호로 묶인 순서가 있는 값의 나열입니다. 객체는 중괄호로 묶인 이름이 지정된 값의 모음입니다. 배열과 객체는 서로 중첩될 수 있으므로, 파일은 객체를 요소로 포함하는 배열로 시작하고 각 객체 안에 다시 배열이나 객체가 들어갈 수 있습니다.

Java의 JSON 객체와 JSON 배열

객체는 문자열 키에 값을 연결하며, 각 키와 값 사이는 콜론으로 구분하고 항목 사이는 쉼표로 구분합니다. 배열은 값의 위치를 기준으로 저장하고 쉼표로 구분합니다. 예를 들어 인라인 JSON 값 [1, "abc", {"name":"xyz"}]는 숫자, 문자열, 객체를 포함하는 배열입니다. 객체에는 값이 문자열인 name 키가 있습니다.

예제에서 사용할 파일은 객체 하나를 포함하는 최상위 배열로 이루어져 있습니다. 그 객체에는 문자열과 숫자, 중첩 배열 두 개, 중첩 객체 하나가 들어 있습니다.

[{"name":"MMN","roll":24,"marks":[91,95,97,97,94],"parents":{"name":"IMT","mobile":"1234567890"},"hobbies":["sports","reading","music"],"others":["A",1]}]

값을 추출할 때는 데이터 구조가 중요합니다. name, roll, parents를 읽는 코드는 해당 키가 존재하고 예상한 JSON 유형의 값을 가진다고 가정합니다. 입력을 직접 통제할 수 없다면 값을 특정 Java 유형으로 취급하기 전에 각각 검증하세요.

JSON.simple을 사용해 Java에서 파일의 JSON 배열 읽기

프로젝트의 의존성 관리자를 통해 JSON.simple을 추가하세요. 선택한 정확한 릴리스의 문서에 나온 아티팩트 좌표를 사용해야 합니다. 특정 릴리스나 빌드 도구가 정해져 있지 않으므로 이 글에서는 좌표를 지정하지 않습니다. org.json.simple 패키지 계열은 외부 라이브러리이므로, 해당 라이브러리가 클래스 경로에 없으면 Java만 설치된 환경에서는 관련 import와 파서 호출을 실행할 수 없습니다.

호환되는 JSON.simple 릴리스를 사용하는 프로젝트라면 파싱 단계는 개념적으로 new JSONParser().parse(reader)와 같습니다. 정확한 파서 API와 반환되는 컬렉션 유형은 해당 릴리스의 문서에서 확인하세요. 아래 예제는 파서가 결과를 만든 다음 단계, 즉 Java 컬렉션 구조를 순회하는 방법에 초점을 둡니다. 값은 앞서 제시한 샘플 파일에 맞춰져 있으며, 예제 자체는 Java 표준 라이브러리의 컬렉션만 사용하므로 별도로 실행할 수 있습니다.

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class JSONArrayTraversal {
  public static void main(String[] args) {
    Map<String, Object> parents = new LinkedHashMap<>();
    parents.put("name", "IMT");
    parents.put("mobile", "1234567890");

    Map<String, Object> record = new LinkedHashMap<>();
    record.put("name", "MMN");
    record.put("roll", 24);
    record.put("marks", Arrays.asList(91, 95, 97, 97, 94));
    record.put("parents", parents);
    record.put("hobbies", Arrays.asList("sports", "reading", "music"));
    record.put("others", Arrays.asList("A", 1));
    List<Map<String, Object>> records = Arrays.asList(record);

    for (Map<String, Object> item : records) {
      System.out.println("Name: " + item.get("name"));
      System.out.println("Roll: " + item.get("roll"));
      System.out.println("Marks: " + item.get("marks"));
      System.out.println("Hobbies: " + item.get("hobbies"));
      Map<?, ?> parent = (Map<?, ?>) item.get("parents");
      System.out.println("Parent's Name: " + parent.get("name")
          + ", Mobile: " + parent.get("mobile"));
      System.out.println("Others: " + item.get("others"));
    }
  }
}
Name: MMN
Roll: 24
Marks: [91, 95, 97, 97, 94]
Hobbies: [sports, reading, music]
Parent's Name: IMT, Mobile: 1234567890
Others: [A, 1]

애플리케이션에서는 선택한 JSON.simple 파서가 반환한 값을 해당 릴리스의 컬렉션 유형에 맞춘 순회 코드에 전달하세요. 여기서 records는 파싱된 최상위 배열을 나타냅니다. 형변환과 필드 조회는 샘플의 스키마에 따라 달라지므로, 입력이 달라질 수 있다면 유형을 전제로 하기 전에 배열의 각 요소와 필드를 검증하세요. 파싱하는 동안 리더를 열어 두고, 파싱이 실패하는 경우를 포함해 작업이 끝나면 닫으세요. 파일 접근 및 파싱 오류는 선택한 릴리스의 문서에 나온 동작과 애플리케이션의 요구사항에 따라 처리하세요. 순회 코드를 파일 입력과 연결할 때는 현재 환경에서 실제로 존재하고 읽을 수 있는 경로를 제공해야 합니다.

결론

JSON 배열은 순서가 있는 값의 나열이고, JSON 객체는 이름이 지정된 값을 키와 연결합니다. Java에서 파일의 JSON 배열을 읽으려면 JSON.simple 같은 외부 파서를 사용하고, 프로젝트에 해당 릴리스의 문서에 나온 의존성을 추가한 다음 입력 스키마에 따라 파싱된 구조를 순회하세요. 형변환이나 변환을 사용하기 전에 선택한 릴리스의 API와 숫자 값 유형을 확인하세요.