부동산통계정보시스템의 아키텍쳐가 변하면서 새로 개발을 해야 됬는데, 기존 코드는 XML형식으로 데이터를 받아와
개발을 했는데 이번에 코드를 뜯으면서 나는 JSON으로 받아오도록 코드를 수정했다.
XML보다는 JSON이 코드도 간결하고 구현하는 것도 더 쉬웠던 것 같다.. 이래서 개발자들이 JSON을 좋아하는 듯..
이 글에서는 JSON형식으로 받아온 데이터를 Object로 파싱하여 원하는 데이터를 추출하는 방법을 정리하려 한다.
혹시 XML로 받아온 데이터를 정제하려는 사람은 아래 링크를 보면 도움이 될 지도 모르겠다.
1) 자바(JAVA) : XML데이터에서 원하는 태그(Tag)의 데이터값을 추출하는 방법로 이동
2) 자바(JAVA) : XML데이터에서 name 속성값으로 원하는 데이터값을 추출하는 방법로 이동
JSONObject에서 원하는 key값의 value값을 추출하는 방법
실제 샘플URL을 통해 가져오는 JSON데이터
JSONObject와 JSONArray 및 JSONParser를 사용해야 하니 아래 라이브러리를 추가해주도록 하자.
json-simple 라이브러리
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
코드를 짜긴 했는데, 너무 길어지면 읽기 힘드니 필요한 사람은 아래의 getJsonArray함수 코드만 봐도 좋을 것 같다.
물론 전체코드는 아래에 작성해놓았으니, 실제로 인증키만 넣어서 돌려보면서 이해 해도 된다.
getJsonArray 함수는 JSON형식의 문자열을 파라메터로 넣으면 ArrayList를 반환해주는 함수이다.
물론 내가 공부하기 위해 만든 함수이므로, 필요한 사람이라면 하위요소 및 key값을 수정해주어야 한다.
getJsonArray 함수
public static ArrayList<Map<String, Object>> getJsonArray(String result) throws ParseException {
/**
* jsonParser : 문자열인 JSON을 JsonObject로 변환하기 위한 생성자
* response, body, items : 각 노드를 담기 위한 변수
* R1Array : item들을 담을 Array, item이 10개라면 길이는 10이다.
*/
JSONParser jsonParser = new JSONParser();
JSONObject R1Object = (JSONObject)jsonParser.parse(result);
JSONObject response = (JSONObject) R1Object.get("response");
JSONObject body = (JSONObject) response.get("body");
JSONObject items = (JSONObject) body.get("items");
JSONArray R1Array = (JSONArray) items.get("item");
/**
* R1Array의 길이만큼 반복문 수행
*/
for(int i=0; i<R1Array.size(); i++) {
/**
* jsonMap 초기화
* jsonObject : R1Array안에 있는 노드들을 담음 = item을 의미
*/
jsonMap = new HashMap<String, Object>();
JSONObject jsonObject = (JSONObject) R1Array.get(i);
/**
* stnNm : 지역명
* tm : 조사일자
* minTaHrmt : 최저기온
*/
String stnNm = (String) jsonObject.get("stnNm");
String tm = (String) jsonObject.get("tm");
String minTaHrmt = (String) jsonObject.get("minTaHrmt");
jsonMap.put("stnNm", stnNm);
jsonMap.put("tm", tm);
jsonMap.put("minTaHrmt", minTaHrmt);
resultList.add(jsonMap);
}
return resultList;
}
여기서 코드를 보면 다음와 같은 코드가 있다.
JSONObject R1Object = (JSONObject)jsonParser.parse(result);
JSONObject response = (JSONObject) R1Object.get("response");
JSONObject body = (JSONObject) response.get("body");
JSONObject items = (JSONObject) body.get("items");
JSONObject를 하나씩 계속 담아주고 있는데
java에서 JSONObject의 하위요소에 바로 접근 하는 방법은 없다는 것 같다.
그래서 이렇게 하나씩 넣어주었는데, 이 방법 말고도 JSONArray에 담아서 반복문을 수행해서 원하는
하위요소를 추출하는 방법도 있다. 나 같은 경우에는 그렇게 하위요소가 많지 않아 위와 같이 작성하였다.
전체코드
package app.model.com;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class JsonTest {
static HashMap<String, Object> jsonMap = new HashMap<String, Object>();
static ArrayList<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
public static void main(String[] args) throws IOException, ParseException {
/**
* testUrl : 공공데이터포털 기상청_지상(종관, ASOS) 일자료 조회서비스 샘플 URL
* result : 받아온 데이터(XML)를 문자열로 받을 변수
* line : 받아온 데이터값을 읽을 변수
* jsonMap : 추출한 문자열을 담을 Map
* resultList : jsonMap을 담을 List
*/
String testUrl = "http://apis.data.go.kr/1360000/AsosDalyInfoService/getWthrDataList?serviceKey=인증키&pageNo=1&numOfRows=10&dataType=JSON&dataCd=ASOS&dateCd=DAY&startDt=20210101&endDt=20220601&stnIds=108";
String result = "";
String line = "";
/**
* URL 생성 및 openStream()를 통해 서버통신
* bf에 공공데이터포털에서 받아온 데이터를 적재
* bf에서 데이터를 읽어들여 값이 null이 될때까지 반복하여
* line을 result에 concat해줌
*/
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(testUrl);
URL url = new URL(urlBuilder.toString());
BufferedReader bf;
bf = new BufferedReader(new InputStreamReader(url.openStream()));
while((line = bf.readLine())!=null) {
result = result.concat(line);
}
resultList = getJsonArray(result);
for(int i=0; i<resultList.size(); i++) {
S ystem.out.println(resultList.get(i).get("stnNm")+", " + resultList.get(i).get("tm")+", " + resultList.get(i).get("minTaHrmt"));
}
}
public static ArrayList<Map<String, Object>> getJsonArray(String result) throws ParseException {
/**
* jsonParser : 문자열인 JSON을 JsonObject로 변환하기 위한 생성자
* response, body, items : 각 노드를 담기 위한 변수
* R1Array : item들을 담을 Array, item이 10개라면 길이는 10이다.
*/
JSONParser jsonParser = new JSONParser();
JSONObject R1Object = (JSONObject)jsonParser.parse(result);
JSONObject response = (JSONObject) R1Object.get("response");
JSONObject body = (JSONObject) response.get("body");
JSONObject items = (JSONObject) body.get("items");
JSONArray R1Array = (JSONArray) items.get("item");
/**
* R1Array의 길이만큼 반복문 수행
*/
for(int i=0; i<R1Array.size(); i++) {
/**
* jsonMap 초기화
* jsonObject : R1Array안에 있는 노드들을 담음 = item을 의미
*/
jsonMap = new HashMap<String, Object>();
JSONObject jsonObject = (JSONObject) R1Array.get(i);
/**
* stnNm : 지역명
* tm : 조사일자
* minTaHrmt : 최저기온
*/
String stnNm = (String) jsonObject.get("stnNm");
String tm = (String) jsonObject.get("tm");
String minTaHrmt = (String) jsonObject.get("minTaHrmt");
jsonMap.put("stnNm", stnNm);
jsonMap.put("tm", tm);
jsonMap.put("minTaHrmt", minTaHrmt);
resultList.add(jsonMap);
}
return resultList;
}
}
결과화면