먼저 API 활용을 위해 http://data.seoul.go.kr/dataList/OA-13122/S/1/datasetView.do 접속하여 API 키를 받아야 한다.
키를 받은 뒤 서울 열린 데이터 광장에서 제공하는 공영주차장 api의 리스트를 먼저 확인해보자.
모든 데이터를 사용하지 않고, 필요한 데이터만 추출하여 vo파일을 작성해보았다.
package vo;
public class ParkingVO {
private int parkingCount, parkingBaseCharge, parkingBaseTime,
parkingPlusCharge, parkingPlusTime;
private String parkingIdx, parkingName, parkingAddr, parkingTel,
parkingStartTimeWeekday, parkingEndTimeWeekday, parkingStartTimeWeekend, parkingMonthlyPass,
parkingEndTimeWeekend, parkingStartTimeHoliday, parkingEndTimeHoliday, parkingLat, parkingLon,
parkingSatPay, parkingHolidayPay;
public String getParkingSatPay() {
return parkingSatPay;
}
public void setParkingSatPay(String parkingSatPay) {
this.parkingSatPay = parkingSatPay;
}
public String getParkingHolidayPay() {
return parkingHolidayPay;
}
public void setParkingHolidayPay(String parkingHolidayPay) {
this.parkingHolidayPay = parkingHolidayPay;
}
public int getParkingCount() {
return parkingCount;
}
public void setParkingCount(int parkingCount) {
this.parkingCount = parkingCount;
}
public String getParkingMonthlyPass() {
return parkingMonthlyPass;
}
public void setParkingMonthlyPass(String parkingMonthlyPass) {
this.parkingMonthlyPass = parkingMonthlyPass;
}
public int getParkingBaseCharge() {
return parkingBaseCharge;
}
public void setParkingBaseCharge(int parkingBaseCharge) {
this.parkingBaseCharge = parkingBaseCharge;
}
public int getParkingBaseTime() {
return parkingBaseTime;
}
public void setParkingBaseTime(int parkingBaseTime) {
this.parkingBaseTime = parkingBaseTime;
}
public int getParkingPlusCharge() {
return parkingPlusCharge;
}
public void setParkingPlusCharge(int parkingPlusCharge) {
this.parkingPlusCharge = parkingPlusCharge;
}
public int getParkingPlusTime() {
return parkingPlusTime;
}
public void setParkingPlusTime(int parkingPlusTime) {
this.parkingPlusTime = parkingPlusTime;
}
public String getParkingIdx() {
return parkingIdx;
}
public void setParkingIdx(String parkingIdx) {
this.parkingIdx = parkingIdx;
}
public String getParkingName() {
return parkingName;
}
public void setParkingName(String parkingName) {
this.parkingName = parkingName;
}
public String getParkingAddr() {
return parkingAddr;
}
public void setParkingAddr(String parkingAddr) {
this.parkingAddr = parkingAddr;
}
public String getParkingTel() {
return parkingTel;
}
public void setParkingTel(String parkingTel) {
this.parkingTel = parkingTel;
}
public String getParkingStartTimeWeekday() {
return parkingStartTimeWeekday;
}
public void setParkingStartTimeWeekday(String parkingStartTimeWeekday) {
this.parkingStartTimeWeekday = parkingStartTimeWeekday;
}
public String getParkingEndTimeWeekday() {
return parkingEndTimeWeekday;
}
public void setParkingEndTimeWeekday(String parkingEndTimeWeekday) {
this.parkingEndTimeWeekday = parkingEndTimeWeekday;
}
public String getParkingStartTimeWeekend() {
return parkingStartTimeWeekend;
}
public void setParkingStartTimeWeekend(String parkingStartTimeWeekend) {
this.parkingStartTimeWeekend = parkingStartTimeWeekend;
}
public String getParkingEndTimeWeekend() {
return parkingEndTimeWeekend;
}
public void setParkingEndTimeWeekend(String parkingEndTimeWeekend) {
this.parkingEndTimeWeekend = parkingEndTimeWeekend;
}
public String getParkingStartTimeHoliday() {
return parkingStartTimeHoliday;
}
public void setParkingStartTimeHoliday(String parkingStartTimeHoliday) {
this.parkingStartTimeHoliday = parkingStartTimeHoliday;
}
public String getParkingEndTimeHoliday() {
return parkingEndTimeHoliday;
}
public void setParkingEndTimeHoliday(String parkingEndTimeHoliday) {
this.parkingEndTimeHoliday = parkingEndTimeHoliday;
}
public String getParkingLat() {
return parkingLat;
}
public void setParkingLat(String parkingLat) {
this.parkingLat = parkingLat;
}
public String getParkingLon() {
return parkingLon;
}
public void setParkingLon(String parkingLon) {
this.parkingLon = parkingLon;
}
}
이제 url를 통해 api에 접근을 해볼 건데, api 작성 형식은 홈페이지에 친절하게 나와있다.
서울시 전체 주차장 정보를 받아오기에는 자료 양이 너무 많아서 강남구 주차장 정보를 출력해보자.
샘플 URL대로 http://openapi.seoul.go.kr:8088/인증키/json/GetParkInfo/1/5/강남" URL을 작성하고,
코드에 넣기전에 주소창을 통해 확인해보았다.
{"GetParkInfo":
{"list_total_count":2715,
"RESULT":{"CODE":"INFO-000","MESSAGE":"정상 처리되었습니다"},
"row":[{"PARKING_NAME":"압구정 428 공영주차장(구)","ADDR":"강남구 압구정동 428-0",
"PARKING_CODE":"1033125","PARKING_TYPE":"NW","PARKING_TYPE_NM":"노외 주차장",
"OPERATION_RULE":"1","OPERATION_RULE_NM":"시간제 주차장","TEL":"02-2176-0971",
"CAPACITY":344.0,"PAY_YN":"Y","PAY_NM":"유료","NIGHT_FREE_OPEN":"N",
"NIGHT_FREE_OPEN_NM":"야간 미개방","WEEKDAY_BEGIN_TIME":"0900",
"WEEKDAY_END_TIME":"2100","WEEKEND_BEGIN_TIME":"0900","WEEKEND_END_TIME":"2100",
"HOLIDAY_BEGIN_TIME":"0900","HOLIDAY_END_TIME":"2100","SYNC_TIME":"2020-07-07 18:25:48",
"SATURDAY_PAY_YN":"N","SATURDAY_PAY_NM":"무료","HOLIDAY_PAY_YN":"N",
"HOLIDAY_PAY_NM":"무료","FULLTIME_MONTHLY":"200000","GRP_PARKNM":"","RATES":400.0,
"TIME_RATE":5.0,"ADD_RATES":400.0,"ADD_TIME_RATE":5.0,"BUS_RATES":0.0,
"BUS_TIME_RATE":0.0,"BUS_ADD_TIME_RATE":0.0,"BUS_ADD_RATES":0.0,"DAY_MAXIMUM":0.0,
"LAT":37.52701729,"LNG":127.02647115},
{"PARKING_NAME":"압구정 428 공영주차장(구)","ADDR":"강남구 압구정동 428-0",
"PARKING_CODE":"1033125","PARKING_TYPE":"NW","PARKING_TYPE_NM":"노외 주차장",
"OPERATION_RULE":"1","OPERATION_RULE_NM":"시간제 주차장","TEL":"02-2176-0971",
"CAPACITY":344.0,"PAY_YN":"Y","PAY_NM":"유료","NIGHT_FREE_OPEN":"N",
"NIGHT_FREE_OPEN_NM":"야간 미개방","WEEKDAY_BEGIN_TIME":"0900","WEEKDAY_END_TIME":"2100",
"WEEKEND_BEGIN_TIME":"0900","WEEKEND_END_TIME":"2100","HOLIDAY_BEGIN_TIME":"0900",
"HOLIDAY_END_TIME":"2100","SYNC_TIME":"2020-07-07 18:25:48","SATURDAY_PAY_YN":"N",
"SATURDAY_PAY_NM":"무료","HOLIDAY_PAY_YN":"N","HOLIDAY_PAY_NM":"무료",
"FULLTIME_MONTHLY":"200000","GRP_PARKNM":"","RATES":400.0,"TIME_RATE":5.0,"ADD_RATES":400.0,
"ADD_TIME_RATE":5.0,"BUS_RATES":0.0,"BUS_TIME_RATE":0.0,"BUS_ADD_TIME_RATE":0.0,
"BUS_ADD_RATES":0.0,"DAY_MAXIMUM":0.0,"LAT":37.52701729,"LNG":127.02647115}
]}
}
JSON파일은 위와 같은 형식으로 되어있다. 우리가 사용할 데이터는 row라는 배열 안에 들어있는 걸 확인했으니, 실질적으로 api를 연동하는 코드를 작성해보자.
// 1. URL을 만들기 위한 StringBuilder/ 오픈 API의요청 규격에 맞는 파라미터 생성, 발급받은 인증키.
StringBuilder urlBuilder = new StringBuilder(
"http://openapi.seoul.go.kr:8088/인증키/json/GetParkInfo/1/500/강남");
위처럼 URL을 만들기 위해 StringBuilder를 사용하여 인증키와 함께 URL을 작성해준다.
// 3. URL 객체 생성.
URL url = new URL(urlBuilder.toString());
// 4. 요청하고자 하는 URL과 통신하기 위한 Connection 객체 생성.
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 5. 통신을 위한 메소드 SET.
conn.setRequestMethod("GET");
// 6. 통신을 위한 Content-type SET.
conn.setRequestProperty("Content-type", "application/json");
// 7. 통신 응답 코드 확인.
System.out.println("Response code: " + conn.getResponseCode());
// 8. 전달받은 데이터를 BufferedReader 객체로 저장.
BufferedReader rd;
if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
// 9. 저장된 데이터를 라인별로 읽어 StringBuilder 객체로 저장.
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
// 10. 객체 해제.
rd.close();
conn.disconnect();
설명은 주석으로 작성해두었다. 메모리 낭비를 줄이기 위해 객체 해제는 꼭 해주어야 한다.
// 1. 문자열 형태의 JSON을 파싱하기 위한 JSONParser 객체 생성.
JSONParser parser = new JSONParser();
// 2. 문자열을 JSON 형태로 JSONObject 객체에 저장.
JSONObject obj = (JSONObject) parser.parse(sb.toString());
// 3. 필요한 리스트 데이터 부분만 가져와 JSONArray로 저장.
// JSON 형식에 따라 GetParkInfo 안에 row 안에 정보를 갖고오기
JSONObject obj2 = (JSONObject) obj.get("GetParkInfo");
JSONArray dataArr = (JSONArray) obj2.get("row");
StringBuilder 객체를 JSON형식으로 파싱을 한 뒤 필요한 데이터에 접근하기 위하여, JSON파일을 확인해보면, GetParkInfo라는 Object안에 row라는 이름의 Array형태로 데이터가 들어가 있는 것을 알 수 있다. 그러므로 row에 있는 배열을 JSONArray라는 dataArr를 만들어 데이터를 넣어주자.
list = new ArrayList<ParkingVO>();
for (int i = 0; i < dataArr.size(); i++) {
// 이런식으로 값을 하나씩 받아올 수 있음 JSONObject
JSONObject jsonObject = (JSONObject) dataArr.get(i);
ParkingVO vo = new ParkingVO();
vo.setParkingIdx(jsonObject.get("PARKING_CODE").toString());
vo.setParkingName(jsonObject.get("PARKING_NAME").toString());
vo.setParkingAddr(jsonObject.get("ADDR").toString());
vo.setParkingBaseCharge(Integer.parseInt(jsonObject.get("RATES").toString().substring(0, jsonObject.get("RATES").toString().lastIndexOf("."))));
vo.setParkingBaseTime(Integer.parseInt(jsonObject.get("TIME_RATE").toString().substring(0, jsonObject.get("TIME_RATE").toString().lastIndexOf("."))));
vo.setParkingCount(Integer.parseInt(jsonObject.get("CAPACITY").toString().substring(0, jsonObject.get("CAPACITY").toString().lastIndexOf("."))));
vo.setParkingEndTimeHoliday(holidayEndTime);
vo.setParkingEndTimeWeekday(weekdayEndTime);
vo.setParkingEndTimeWeekend(weekendEndTime);
vo.setParkingLat(jsonObject.get("LAT").toString());
vo.setParkingLon(jsonObject.get("LNG").toString());
vo.setParkingMonthlyPass(monthlyPass);
vo.setParkingPlusCharge(Integer.parseInt(jsonObject.get("ADD_RATES").toString().substring(0, jsonObject.get("ADD_RATES").toString().lastIndexOf("."))));
vo.setParkingPlusTime(Integer.parseInt(jsonObject.get("ADD_TIME_RATE").toString().substring(0, jsonObject.get("ADD_TIME_RATE").toString().lastIndexOf("."))));
vo.setParkingStartTimeHoliday(holidayBeginTime);
vo.setParkingStartTimeWeekday(weekdayBeginTime);
vo.setParkingStartTimeWeekend(weekendBeginTime);
vo.setParkingTel(jsonObject.get("TEL").toString());
vo.setParkingSatPay(jsonObject.get("SATURDAY_PAY_NM").toString());
vo.setParkingHolidayPay(jsonObject.get("HOLIDAY_PAY_NM").toString());
list.add(vo);
}
json형식의 데이터를 jsp화면에서 리스트 별로 하나씩 보여주기 위해 아까 만들어두었던 vo형식의 list안에 넣어주는 형식이다. 반복문을 통해 row 배열의 하나씩 접근하여 jsonObject.get("오브젝트명")을 활용하여 필요한 데이터를 vo에 저장하여 리스트에 담아준다. 이후 vo형식의 리스트로 jsp파일로 model이나 세션 등 다양한 방법으로 데이터를 전달하여 화면에 보여줄 수 있다.
이번엔 api 인증키를 받고 json형식의 데이터를 불러와 활용하는 방식으로 코드를 작성해보았다. 가장 어려웠던 부분은 사실 연동보다는 다른 클래스나, jsp폴더로의 데이터 이동이었고, json 구조 파악 정도였던 것 같다. 이번 api 연동을 공부하면서 json까지 추가로 공부하게 되었던 것 같다.