공공데이터는 국가에서 제공하는 데이터들이다. 이 데이터는 다음에서 찾을 수 있다.
이곳에서 항공데이터를 조회하여 가져올 것이다.
데이터는 다음과 같은 형태로 조회된다.
이 데이터를 주소로 나타내보면 다음과 같다.
위의 주소는 End Point이다. 즉, 데이터의 입구까지만 접근하는 주소이다.
? 이후에 나타나는 주소를 쿼리 스트링이라고 하는데, 이 쿼리 스트링은 일종의 질의문이다. 이 질의를 통해 데이터베이스에 상세히 접근할 수 있도록 한다.
또한, 이 데이터는 XML 형태로 제공된다.
따라서, 이 데이터를 자바에서 이용하려고 하면 Json 형태로 만들어주어야 한다. 쿼리 스트링 뒤에 타입을 붙여주자.
Json의 형태로 변화된 것이 보인다(객체의 형태)
이 주소 속 데이터를 자바 클래스로 변환하고, 값을 도출할 예정이다.
먼저, 이 Json 데이터의 클래스 원형을 만들어보자.
http://www.jsonschema2pojo.org/
이 코드를 자바 새 파일로 만들어 원형 클래스로 만들어둔다.
이제, 항공데이터를 조회하도록 할 것이다.
package airplane;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import com.google.gson.Gson;
public class FlightApp {
public static AirLineList getFlightInfo(String depAirportId, String arrAirportId, Integer depPlandTime){
try {
URL url=new URL("http://openapi.tago.go.kr/openapi/service/DmstcFlightNvgInfoService/getFlightOpratInfoList?serviceKey=uaLnSRJvnuUZqahDeBOz%2FK8rf4DSXtNmqWkueOzLButZOzzIfz4mHqWuLXwbVzwPSZ2BE736J6cX1uttigP9RA%3D%3D&numOfRows=50&depAirportId="+depAirportId+"&arrAirportId="+arrAirportId+"&depPlandTime="+depPlandTime+"&airlineId=AAR&_type=json");
HttpURLConnection con =(HttpURLConnection)url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
StringBuilder sb=new StringBuilder();
String input="";
while((input=br.readLine())!=null) {
System.out.println(input);
sb.append(input);
}
br.close();
con.disconnect();
Gson gson=new Gson();
AirLineList flightInfo=gson.fromJson(sb.toString(), AirLineList.class);
return flightInfo;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String depAirportId="NAARKJJ";
String arrAirportId="NAARKPC";
Integer depPlandTime=20200407;
AirLineList flightInfo=getFlightInfo(depAirportId, arrAirportId, depPlandTime);
//List<Item> myItem = flightInfo.getResponse().getBody().getItems().getItem();
// forEach 문 : 첨부터 끝까지 돌릴 때
for(Item item:flightInfo.getResponse().getBody().getItems().getItem()) {
System.out.println("항공사 : " +item.getAirlineNm());
System.out.println("출발지 : " +item.getArrAirportNm());
System.out.println("도착지 : " +item.getDepAirportNm());
System.out.println("출발일시 : "+item.getArrPlandTime());
System.out.println("이코노미 금액 : "+item.getEconomyCharge());
System.out.println("특등석 금액 : "+item.getPrestigeCharge());
System.out.println();
}
}
}
최종적으로는 매서드로 변수를 받아 변수값에 따라 쿼리값의 변화를 줄 것이기 때문에, 먼저 쿼리값에 따라 불러오는 Json 값이 변화할 수 있는 매서드, getFlightInfo를 만든다.
URL 매서드를 통해 자바에 웹페이지를 불러오고, HttpURLConnection을 이용해 웹페이지와 자바를 연결한다.
연결된 웹페이지를 BufferReader을 통해 불러온다.
while문을 통해 더이상 웹페이지에 불러올 데이터가 없을 때 까지의 반복문을 사용해 웹페이지 전체 데이터를 불러오고, BufferReader과 웹페이지와의 연결을 끊는다.
불러온 Json 데이터를 Gson을 이용해 AirLineList 내의 클래스 내의 원형 클래스 속에 넣는다. 이 때, 통신을 통해 들어오는 데이터는 반드시 String이기 때문에, 받아오는 데이터를 toString을 통해 문자열로 만든다.
메인 매서드에서는 변수를 넣고 데이터타입과 함수를 불러온다.
이 때 item이 배열문이기 때문에, forEach문을 통해 배열의 반복문을 사용한다.
이 코드는 실용성에 문제가 있다.
사용자는 공항의 포트 번호와 비행기의 일련번호를 모르고, 검색기능이 없다.
따라서, 먼저 포트번호와 비행기 번호가 입력된 데이터 파일을 만든다
-데이터 파일
package airplane;
import java.util.HashMap;
public class FlightInfoService {
public static HashMap<String, String> airLineId=
new HashMap<>();
public static HashMap<String, String> airPortId=
new HashMap<>();
public static void setAirLineId() {
airLineId.put("아시아나항공", "AAR");
airLineId.put("에어부산", "ABL");
airLineId.put("이스타항공", "ESR");
airLineId.put("제주항공", "JJA");
airLineId.put("진 에어", "JNA");
airLineId.put("대한항공", "KAL");
airLineId.put("티웨이항공", "TWB");
// 추가 필요
}
public static void setAirPortId() {
airPortId.put("무안", "NAARKJB");
airPortId.put("광주", "NAARKJJ");
airPortId.put("군산", "NAARKJK");
airPortId.put("여수", "NAARKJY");
airPortId.put("원주", "NAARKNW");
airPortId.put("양양", "NAARKNY");
airPortId.put("제주", "NAARKPC");
airPortId.put("김해", "NAARKPK");
airPortId.put("사천", "NAARKPS");
airPortId.put("울산", "NAARKPU");
airPortId.put("인천", "NAARKSI");
airPortId.put("김포", "NAARKSS");
airPortId.put("포항", "NAARKTH");
airPortId.put("대구", "NAARKTN");
airPortId.put("청주", "NAARKTN");
}
}
HashMap는 key:value 한 쌍으로 엔트리에 저장한다. 따라서 데이터를 저장하는데 유용하다. 이 때, key는 중복할 수 없으니 유의하기.
또한 페이지가 1페이지를 넘어가면 그 값이 다 출력되지 않으므로, 값을 전체적으로 출력하는 작업도 필요하다.
이제 이것을 다시 System.in까지 받는 코드로 다시 만들어보자.
package airplane;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Scanner;
import com.google.gson.Gson;
public class FlightApp {
public static int getTotalCount(String depAirportId, String arrAirportId, Long depPlandTime) {
try {
URL url=new URL("http://openapi.tago.go.kr/openapi/service/DmstcFlightNvgInfoService/getFlightOpratInfoList?serviceKey=uaLnSRJvnuUZqahDeBOz%2FK8rf4DSXtNmqWkueOzLButZOzzIfz4mHqWuLXwbVzwPSZ2BE736J6cX1uttigP9RA%3D%3D&numOfRows=50&pageNo=1&depAirportId="+FlightInfoService.airPortId.get(depAirportId)+"&arrAirportId="+FlightInfoService.airPortId.get(arrAirportId)+"&depPlandTime="+depPlandTime+"&airlineId=AAR&_type=json");
HttpURLConnection con =(HttpURLConnection)url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
StringBuilder sb=new StringBuilder();
String input="";
while((input=br.readLine())!=null) {
sb.append(input);
System.out.println(input);
}
br.close();
con.disconnect();
Gson gson=new Gson();
AirLineList flightInfo=gson.fromJson(sb.toString(), AirLineList.class);
return flightInfo.getResponse().getBody().getTotalCount();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 0;
}
public static AirLineList getFlightInfo(String depAirportId, String arrAirportId, Long depPlandTime, int page){
try {
URL url=new URL("http://openapi.tago.go.kr/openapi/service/DmstcFlightNvgInfoService/getFlightOpratInfoList?serviceKey=uaLnSRJvnuUZqahDeBOz%2FK8rf4DSXtNmqWkueOzLButZOzzIfz4mHqWuLXwbVzwPSZ2BE736J6cX1uttigP9RA%3D%3D&numOfRows=50&pageNo="+page+"&depAirportId="+FlightInfoService.airPortId.get(depAirportId)+"&arrAirportId="+FlightInfoService.airPortId.get(arrAirportId)+"&depPlandTime="+depPlandTime+"&airlineId=AAR&_type=json");
HttpURLConnection con =(HttpURLConnection)url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
StringBuilder sb=new StringBuilder();
String input="";
while((input=br.readLine())!=null) {
sb.append(input);
System.out.println(input);
}
br.close();
con.disconnect();
Gson gson=new Gson();
AirLineList flightInfo=gson.fromJson(sb.toString(), AirLineList.class);
return flightInfo;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
FlightInfoService.setAirLineId();
FlightInfoService.setAirPortId();
for(String key : FlightInfoService.airPortId.keySet()) {
System.out.print(key+" ");
}
System.out.println();
System.out.println("출발지를 입력하세요.");
Scanner sc=new Scanner(System.in);
String depAirportId=sc.next();
System.out.println("도착지를 입력하세요.");
String arrAirportId=sc.next();
System.out.println("출발일을 입력하세요.");
Long depPlandTime=sc.nextLong();
int page=1;
int totalCount=getTotalCount(depAirportId, arrAirportId, depPlandTime);
int count=0;
if(totalCount%50==0) {
count=totalCount/50;
}else {
count=totalCount/50+1;
}
ArrayList<AirLineList>flightInfos=new ArrayList<>();
for (int i = 0; i < count; i++) {
AirLineList flightInfo=getFlightInfo(depAirportId, arrAirportId, depPlandTime,page++);
flightInfos.add(flightInfo);
}
for (AirLineList flightInfo : flightInfos) { // 3번 돌기
//List<Item> myItem = flightInfo.getResponse().getBody().getItems().getItem();
//iterable(반복)
// forEach 문 : 첨부터 끝까지 돌릴 때
for(Item item:flightInfo.getResponse().getBody().getItems().getItem()) {
System.out.println("항공사 : " +item.getAirlineNm());
System.out.println("출발지 : " +item.getArrAirportNm());
System.out.println("도착지 : " +item.getDepAirportNm());
System.out.println("출발일시 : "+item.getArrPlandTime());
System.out.println("이코노미 금액 : "+item.getEconomyCharge());
System.out.println("특등석 금액 : "+item.getPrestigeCharge());
System.out.println();
}
sc.close();
}
}
}
getTotalCount 매서드를 통해 전체 페이지 역시 변수로 받는다.
정보값이 있는 배열이 2개이므로, foreach 문을 두 번 돌려 값을 받는다. 첫 번재 foreach문은 페이지마다 회전하는 반복문, 두 번째 foreach문은 페이지 내의 데이터를 배열마다 돌리는 매서드이다.
'JAVA' 카테고리의 다른 글
16. 익명 클래스 (0) | 2020.04.13 |
---|---|
JAVA 실습 10. 공공데이터를 이용하여 코로나 공공마스크 지원 약국 주소찾기. (0) | 2020.04.10 |
웹과 OSI 7계층 (0) | 2020.04.07 |
14. Json (0) | 2020.04.06 |
13. 입출력 (0) | 2020.04.06 |