Java - 15. JSON

갓김치·2020년 10월 16일
0

고급자바

목록 보기
38/47
post-custom-banner

XML vs. JSON

XML

<person>
  <name>a</name>
  <age>1</age>
  <hobby></hobby>
</person>

단점

  • 실제 데이터크기보다 태그와 같은 부수적인 내용이 용량이 너무 큼

JSON

{name: a, age:1, hobby:}
  • MDN JSON
  • JavaScript Object Notation (자바스크립트 객체 표기)
    • 자바스크립트 오브젝트 형식으로 표현된 텍스트
  • a syntax for serializing objects, arrays, numbers, strings, booleans, and null.

value값으로 가능한 type

  • String
  • number
  • Object (JSON Object, not Java Object)
  • Array
  • boolean
  • null

Static Methods

  • JSON.parse(text[, reviver])
    • Parse the string text as JSON
  • JSON.stringify(value[, replacer[, space]])
    • Return a JSON string corresponding to the specified value
    • all instances of undefined are replaced with null

JSON

  • 파싱을 위해 json-simple-1.1.1.jar 필요

예제1

JsonSimpleWriterTest.java

public class JsonSimpleWriterTest {
  public static void main(String[] args) throws IOException {
    //1. JSON 데이터 생성
    JSONObject jsonObj = new JSONObject();

    jsonObj.put("name", "홍길동");
    jsonObj.put("job", "학생");
    jsonObj.put("age", 30);
    jsonObj.put("addr", "율도국");


    // 2. JSONArray 데이터 생성
    JSONArray singerList = new JSONArray();
    singer.put("name", "싸이");
    singer.put("gender", "남자");
    singer.put("age", 40); // long
    singerList.add(singer);

    singer = new JSONObject();
    singer.put("name", "비욘세");
    singer.put("gender", "여자");
    singer.put("age", 33);
    singerList.add(singer);

    singer = new JSONObject();
    singer.put("name", "오혁");
    singer.put("gender", "남자");
    singer.put("age", 28);
    singerList.add(singer);

    jsonObj.put("singerList", singerList);

    FileWriter fw = new FileWriter("d:/D_Other/myJsonFile.txt");
    fw.write(jsonObj.toString());
    fw.flush();
    fw.close();
  } // main()
} // class

myJsonFile.txt

{"name":"홍길동","job":"학생","addr":"율도국","singerList":[{"gender":"남자","name":"싸이","age":40},{"gender":"여자","name":"비욘세","age":33},{"gender":"남자","name":"오혁","age":28}],"age":30}

JsonSimpleReadTest.java

public class JsonSimpleReadTest {
public static void main(String[] args) throws IOException, ParseException {

  // 파일 읽기 및 JSON으로 parsing
  FileReader fr = new FileReader("d:/D_Other/myJsonFile.txt");
  JSONParser parser = new JSONparser();

  // 1. JSON 객체
  Object obj = parser.parse(fr); // ParseException 발생시킴
  JSONObject jsonFile = (JSONObject) obj;

  String name = (String) jsonFile.get("name");
  String job = (String) jsonFile.get("job");
  long age = (long) jsonFile.get("age");
  String addr = (String) jsonFile.get("addr");

  System.out.println("name : " + name);
  System.out.println("job : " + job);
  System.out.println("age : " + age);
  System.out.println("addr : " + addr);

  // 2. JSON 배열
  JSONArray list = (JSONArray) jsonFile.get("singerList");

  Iterator<JSONObject> it = list.iterator();

  JSONObject singer;
  while (it.hasNext()){
    singer = it.next();
    System.out.printf("이름: %s, \t성별: %s, \t나이: %d\n"
        ,singer.get("name"), singer.get("gender"), singer.get("age");
  }
} // main
} // class
  • JSON 표기 방식에 따른 text파일을 parse할 경우에도 잘 작동된다.
    • yourJsonFile.txt

예제2: API 읽어오기

전체갯수 알기 전 1~5로 진행하고 전체갯수 구하기

{"Grid_20150827000000000227_1":{"totalCnt":14,"startRow":1,"endRow":5,"result":{"code":"INFO-000","message":"정상 처리되었습니다."},"row":[{"ROW_NUM":1,"RECIPE_ID":195428,"IRDNT_SN":195429,"IRDNT_NM":"밥","IRDNT_CPCTY":"3공기","IRDNT_TY_CODE":"3060001","IRDNT_TY_NM":"주재료"},{"ROW_NUM":2,"RECIPE_ID":195428,"IRDNT_SN":195430,"IRDNT_NM":"오이","IRDNT_CPCTY":"1/2개","IRDNT_TY_CODE":"3060001","IRDNT_TY_NM":"주재료"},{"ROW_NUM":3,"RECIPE_ID":195428,"IRDNT_SN":195431,"IRDNT_NM":"당근","IRDNT_CPCTY":"1/2개","IRDNT_TY_CODE":"3060001","IRDNT_TY_NM":"주재료"},{"ROW_NUM":4,"RECIPE_ID":195428,"IRDNT_SN":195432,"IRDNT_NM":"가지","IRDNT_CPCTY":"1/2개","IRDNT_TY_CODE":"3060001","IRDNT_TY_NM":"주재료"},{"ROW_NUM":5,"RECIPE_ID":195428,"IRDNT_SN":195433,"IRDNT_NM":"어린잎채소","IRDNT_CPCTY":"약간","IRDNT_TY_CODE":"3060001","IRDNT_TY_NM":"주재료"}]}}

public class JsonAPISimpleReadTest {
  public static void main(String[] args) throws IOException, ParseException {
    String svcKey = "Grid_20150827000000000227_1";  // 레시피 재료 정보 조회 서비스 
    String apiKey = "1df7e8571e8df3f8cbc9b87691ca7d3e4d04f03c593d477e52bf67b03f0b6e1c"; // 개인별 발급.
    String startIdx = "1";  	// 레시피 재료 시작 순번
    String endIdx = "5";		// 레시피 재료 종료 순번 - 전체 순번 몰라서 일단 5로
    String recipeId = "195428";	// 래시피가 궁금한 음식 ID 
    }

    URL url = new URL("http://211.237.50.150:7080/openapi/"+ apiKey 
            + "/json/"+ svcKey + "/"+startIdx +"/" + endIdx 
            +"?RECIPE_ID=" +  recipeId);
            // startIdx, endIdx를 몰라도 넣어줘야하도록 url이 설계되어있음

    // 1. URLConnection 객체 생성
    URLConnection urlConnection = url.openConnection();

    // 2. Parsing을 위한 Parser객체 생성
    JSONParser paser = new JSONParser();

    // 3. JSON 문자열 데이터를 읽어오려고 보조스트림 InputStreamReader 활용
    Object obj = parser.parse( /*매개변수로 Reader 요구*/
            new InputStreamReader( /*getInputStream으로 얻는 바이트 기반을 문자 기반으로 변환*/
                urlConnection.getInputStream())); /*바이트기반 스트림 리턴*/

    // 4. 읽어온 Object를 JSONObject로 캐스팅
    JSONObject jsonFile = (JSONObject) obj;

    // 5. 전체 레시피 재료수를 얻기 위해 객체 얻어오기 (위의 샘플데이터 내용 참조)
    JSONObject rootObj = (JSONObject) jsonFile.get(svcKey);

    // 6. 전체 레시피 재료 수
    long totalCnt = (long) rootObj.get("totalCnt");

    // 7. 레시지 재료 마지막 순번 설정
    endIndx = totalCnt+"";
    // 이제 전체 데이터를 얻어올 준비 완료 ★
    • 5) JSONObject rootObj = (JSONObject) jsonFile.get(svcKey);
      에 해당하는 밸류
    • 6) long totalCnt = (long) rootObj.get("totalCnt"); 전체 갯수 구하기

전체 데이터 불러오기

  • 위의 파일과 이어짐
    // 1. 새로 설정한 endIdx로 데이터 불러오기
    url = new URL("http://211.237.50.150:7080/openapi/"+ apiKey 
                    + "/json/"+ svcKey + "/"+startIdx +"/" + endIdx
                    +"?RECIPE_ID=" +  recipeId);

    // 2. URLConncetion 객체 생성
    urlConnection = url.openConnection();

    // 3. obj에 전체 데이터 담기 (startIdx ~ endIdx)
    Object obj = parser.parse( /*매개변수로 Reader 요구*/
            new InputStreamReader( /*getInputStream으로 얻는 바이트 기반을 문자 기반으로 변환*/
                urlConnection.getInputStream())); /*바이트기반 스트림 리턴*/

    // 4. 읽어온 Object를 JSONObject로 캐스팅
    jsonFile = (JSONObject) obj;

    // 5. 전체 레시피 재료 수를 얻기위해 객체 얻어오기
    rootObj = (JSONObject) jsonFile.get(svcKey);

    // 6. result 가져와서 코드값을 비교하여 정상 데이터인지 확인
    JSONObject result = (JSONObject) jsonFile.get("result");
    String code = (String) result.get("code");
    if(code.equals("INFO-000")) { // 정상 결과 (이 코드는 우리가 문서 읽어보고 확인해야함)
      JSONArray list = (JSONArray) rootObj.get("row");

      for (Object tempObj : list) { // 배열도 foreach 사용 가능
        JSONObject tempJson = (JSONObject) tempObj;

        tempJson.get("ROW_NUM"));
        System.out.println("레시피ID : " + tempJson.get("RECIPE_ID"));
        System.out.println("재료명 : " + tempJson.get("IRDNT_NM"));
        System.out.println("용량 : " + tempJson.get("IRDNT_CPCTY"));
        System.out.println("재료구분 : " + tempJson.get("IRDNT_TY_NM"));
        System.out.println("----------------------------------------");
      }
    }
  } // main
} // class

{"Grid_20150827000000000227_1":

{"totalCnt":14,
"startRow":1,
"endRow":5,
"result":{"code":"INFO-000","message":"정상 처리되었습니다."},
"row":

[{"ROW_NUM":1,"RECIPE_ID":195428,"IRDNT_SN":195429,"IRDNT_NM":"밥","IRDNT_CPCTY":"3공기","IRDNT_TY_CODE":"3060001","IRDNT_TY_NM":"주재료"},{"ROW_NUM":2,"RECIPE_ID":195428,"IRDNT_SN":195430,"IRDNT_NM":"오이","IRDNT_CPCTY":"1/2개","IRDNT_TY_CODE":"3060001","IRDNT_TY_NM":"주재료"},{"ROW_NUM":3,"RECIPE_ID":195428,"IRDNT_SN":195431,"IRDNT_NM":"당근","IRDNT_CPCTY":"1/2개","IRDNT_TY_CODE":"3060001","IRDNT_TY_NM":"주재료"},{"ROW_NUM":4,"RECIPE_ID":195428,"IRDNT_SN":195432,"IRDNT_NM":"가지","IRDNT_CPCTY":"1/2개","IRDNT_TY_CODE":"3060001","IRDNT_TY_NM":"주재료"},{"ROW_NUM":5,"RECIPE_ID":195428,"IRDNT_SN":195433,"IRDNT_NM":"어린잎채소","IRDNT_CPCTY":"약간","IRDNT_TY_CODE":"3060001","IRDNT_TY_NM":"주재료"}]}}

profile
갈 길이 멀다
post-custom-banner

0개의 댓글