JavaScript 활용팁
2019.05.29 / 24:28

[파싱] 3. JSON Array 파싱

탁돌이개발자
추천 수 77

이전번에는 간단한 예제를 통해 JSON을 이용한 파싱 방법에 대해 알아보았다.

예제에서는 1명의 교수와 1명의 학생만 가지고 예를 들어 봤었다.

{univ:{"professor":"김교수","student":"이학생"}}

그런데 현실적으로 대학에 교수와 학생이 1명만 있을리는 없다. 따라서 여러명의 교수와 여러명의 학생을 포함하고자 한다. 어떻게 하면 좋을까?

저번에 강조했던 내용을 기억해보자 "JSON은 Map구조이다." 그렇다. JSON은 맵 구조이다. 따라서 key와 value가 쌍으로 저장되는데 여기서 중요한건 key값이 중복되면 안된다는 것이다. (마지막 값만 저장된다.)
즉, professor나 student라는 key값이 중복될 수 없다는 얘기이다. 그런데 우리는 여러명의 교수와 학생을 저장해야 하는데 어떻게 해야 할까?

이때 필요한게 바로 JSON Array이다. JSON을 배열 형태로 나타내여 인덱스별로 나누어 저장하면 중복 문제를 피할 수 있는 것이다.

배열 형태로 나타내어진 JSON 예제를 살펴보자

{univ:[{"professor":"김교수","student":"이학생"},{"professor":"박교수", "student":"최학생"},{"professor":"한교수", "student":"황학생"}]}

여전히 한줄로 나타내면 복잡하다. 좀더 알기 쉽게 줄바꿈을 해보자

{ univ: [ { "professor":"김교수", "student":"이학생" }, { "professor":"박교수", "student":"최학생" }, { "professor":"한교수", "student":"황학생" } ] }

한결 나아졌다. 여기서 볼 수 있듯이 [ ]로 묶인 부분이 배열이 되는 것이다. 따라서 김교수와 이학생은 0번인덱스, 박교수와 최학생은 1번인덱스, 나머지는 2번인덱스가 되는것이다.

이제 이를 바탕으로 파싱을 시작해보자.

import org.json.simple.JSONObject; import org.json.simple.JSONArray; //JSON배열 사용 import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; class JSONAdd{ static String json; //파싱할 최종 데이터 담아주기 위한 문자열 //생성자 통해 JSON생성 public JSONAdd(){ //JSON생성시 언제나 내부부터 채워나가기 //JSONObject 3개에 각각 데이터 저장 JSONObject data1 = new JSONObject(); data1.put("professor", "김교수"); data1.put("student", "이학생"); JSONObject data2 = new JSONObject(); data2.put("professor", "박교수"); data2.put("student", "최학생"); JSONObject data3 = new JSONObject(); data3.put("professor", "한교수"); data3.put("student", "황학생"); //위에서 만든 3개의 오브젝트 데이터를 JSONArray에 순서대로 저장 JSONArray arr = new JSONArray(); arr.add(data1);//0번인덱스 arr.add(data2);//1번인덱스 arr.add(data3);//2번인덱스 //최종적으로 univ오브젝트에 JSON배열 저장 JSONObject univ = new JSONObject(); univ.put("univ", arr); //파싱할 데이터 저장 json = univ.toJSONString(); //테스트용 출력 System.out.println(json); } }

이 부분은 파싱에 사용할 예제를 만들어주는 코드이다. 전번에는 메소드를 이용했지만 편의를 위해 생성자를 이용해 만들었다. 
클래스 객체 생성을 하면 언제나 자동으로 기본 생성자가 호출되는데 기본 생성자에 JSON을 만드는 코드를 넣어 Instantiation될때마다 자동으로 JSON이 생성되게 하였다. 까먹었을지도 몰라서 설명하였다.

이 코드를 메인메소드에서 Instantiation하여 실행시켜보면 출력 결과는 역시 잘 나온다.


이제 이를 파싱해보도록 한다. 목표는 전번과 동일하게 이름들만 받아오는 것이다.

public class Main{ public static void main(String[] args) throws ParseException { JSONAdd jsonAdd = new JSONAdd(); //전체 파싱 정보가 저장된 jsonAdd의 json을 자체 String을 생성하여 옮겨 담음 String json = jsonAdd.json; JSONParser parser = new JSONParser(); JSONObject univ = (JSONObject)parser.parse(json); //테스트출력 //System.out.println(univ.toJSONString()); JSONArray arr = (JSONArray)univ.get("univ"); //테스트출력 //System.out.println(arr.toJSONString()); for(int i=0;i<arr.size();i++){ JSONObject tmp = (JSONObject)arr.get(i);//인덱스 번호로 접근해서 가져온다. String professor = (String)tmp.get("professor"); String student = (String)tmp.get("student"); System.out.println("----- "+i+"번째 인덱스 값 -----"); System.out.println("교수 : "+professor); System.out.println("학생 : "+student); } } }

언제나 그렇듯 JSONParser를 먼저 만들어준다. 그리고 제일 바깥고리인 univ부터 접근해 받아온다. 그런데 배열 형태로 저장되어있기 때문에 JSONArray형태로 형변환 하여 받아와야 한다.(Exception처리 또한 잊지 말자)

이후 배열이기때문에 for문을 이용해 인덱스로 접근을 하였다. for문 첫째줄에 tmp라는 임시 JSON오브젝트를 선언하고, arr.get(i)를 통해 i번째 값을 가져오게 하였다. 그리고 professor와 student를 각각 형변환하여 출력시켜준다. for문의 반복횟수는 0번 ~ arr.size()이기 때문에 자연스럽게 배열의 길이 만큼만 반복출력된다.

결과값은 다음과 같다.

완성된 코드 전문은 아래와 같다.

코드 구성 :

import org.json.simple.JSONObject; import org.json.simple.JSONArray; //JSON배열 사용 import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; class JSONAdd{ String json; //파싱할 최종 데이터 담아주기 위한 문자열 //생성자 통해 JSON생성 public JSONAdd(){ //JSON생성시 언제나 내부부터 채워나가기 //JSONObject 3개에 각각 데이터 저장 JSONObject data1 = new JSONObject(); data1.put("professor", "김교수"); data1.put("student", "이학생"); JSONObject data2 = new JSONObject(); data2.put("professor", "박교수"); data2.put("student", "최학생"); JSONObject data3 = new JSONObject(); data3.put("professor", "한교수"); data3.put("student", "황학생"); //위에서 만든 3개의 오브젝트 데이터를 JSONArray에 순서대로 저장 JSONArray arr = new JSONArray(); arr.add(data1);//0번인덱스 arr.add(data2);//1번인덱스 arr.add(data3);//2번인덱스 //최종적으로 univ오브젝트에 JSON배열 저장 JSONObject univ = new JSONObject(); univ.put("univ", arr); //파싱할 데이터 저장 json = univ.toJSONString(); //테스트용 출력 //System.out.println(json); } } public class Main{ public static void main(String[] args) throws ParseException { JSONAdd jsonAdd = new JSONAdd(); //전체 파싱 정보가 저장된 jsonAdd의 json을 자체 String을 생성하여 옮겨 담음 String json = jsonAdd.json; JSONParser parser = new JSONParser(); JSONObject univ = (JSONObject)parser.parse(json); //테스트출력 //System.out.println(univ.toJSONString()); JSONArray arr = (JSONArray)univ.get("univ"); //테스트출력 //System.out.println(arr.toJSONString()); for(int i=0;i<arr.size();i++){ JSONObject tmp = (JSONObject)arr.get(i);//인덱스 번호로 접근해서 가져온다. String professor = (String)tmp.get("professor"); String student = (String)tmp.get("student"); System.out.println("----- "+i+"번째 인덱스 값 -----"); System.out.println("교수 : "+professor); System.out.println("학생 : "+student); } } }

여기까지 해서 JSON Array에 대해 알아보았다. 사실상 제공되는 대부분의 JSON은 이러한 배열 형태로 주어지기 때문에 JSONArray 파싱을 익히는 것은 필수적이다. 

다음 시간에는 JSON을 받는데 필요한 API키를 발급받는 방법을 알아보고 본격적으로 웹을 통한 JSON파싱에 대해 살펴보겠다.