본문 바로가기
프로그래밍/API

[JAVA] 기상청 날씨 API - 중기예보(중기육상예보조회)

by 밍구몬 2019. 8. 27.

기존 (신)동네예보정보조회서비스 중기예보정보조회서비스는 2020년 4월 28일 폐기.

기상청 API는 아래의 링크 확인

https://ming9mon.tistory.com/151https://ming9mon.tistory.com/151

 

 

[JAVA]변경된 기상청 날씨 API (동네예보, 중기예보)

기존에 사용하던 (신)동네예보정보조회서비스와 중기예보정보조회서비스는 2020년 4월 28일 완전히 폐기된다고 합니다. 새로운 API는 https://www.data.go.kr/dataset/15000099/openapi.do 에서 동네예보 조회서비..

ming9mon.tistory.com

 

이번 글에서는 기상청 API인 공공데이터 포털의 중기예보정보서비스를 이용할 것이다.

만약 API 사용 신청을 안했다면 다른글에 포스팅한것과 API키를 발급받는 방법은 똑같다.

 

중기예보는 동네예보와 다르게 x, y값으로 조회하는 것이 아니라 regId라는 예보구역코드로 조회를 한다.

기상청 API는 값을 항상 사용하기 불편하게 주는거 같다 ..

같은 형식으로 데이터를 주면 파싱해서 사용하기 편할텐데 ......

 

동네예보에서는 key값이 고정이라 key에 대한 값을 가져오면 됐었지만 중기육상예보조회는 key값이 다 다르다. (왼쪽이 키값, 오른쪽이 value)

key 값이 다 달라서 먼저 key값을 얻고 key값에 해당하는 value를 추출하였다.

wf로 시작하는건 날씨, rnSt로 시작하는건 강수량, Am과 Pm은 오전 강수확률과 오후 강수확률을 나타낸다.

8, 9, 10일은 오전 오후 없이 하루 평균 강수확률과 날씨만 리턴해 준다.

 

이번 예제에서는 이대로 사용하기 불편하니 hashmap을 이용하여 N일 후 날씨와 강수확률을 출력하도록 만들어 주었다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;


public class Test {
	public static void main(String[] args) throws IOException, ParseException {
		
		String apiUrl = "http://newsky2.kma.go.kr/service/MiddleFrcstInfoService/getMiddleLandWeather";
		// 홈페이지에서 받은 키
		String serviceKey = "홈페이지에서 받은 키";
		String regId = "11B00000";	//예보 구역 코드
		String tmFc = "201908270600";	//발표시간 입력
		String numOfRows = "1";	//한 페이지 결과 수
		String type = "json";	//타입 xml, json 등등 ..
		HashMap<String, HashMap<String,String>> rst = new HashMap<>();
		HashMap<String, String> sky = new HashMap<>();
		HashMap<String, String> tpt = new HashMap<>();
		
		StringBuilder urlBuilder = new StringBuilder(apiUrl);
		urlBuilder.append("?" + URLEncoder.encode("ServiceKey","UTF-8") + "="+serviceKey);
		urlBuilder.append("&" + URLEncoder.encode("regId","UTF-8") + "=" + URLEncoder.encode(regId, "UTF-8"));
		urlBuilder.append("&" + URLEncoder.encode("tmFc","UTF-8") + "=" + URLEncoder.encode(tmFc, "UTF-8")); /* 조회하고싶은 날짜*/
		urlBuilder.append("&" + URLEncoder.encode("numOfRows","UTF-8") + "=" + URLEncoder.encode(numOfRows, "UTF-8")); /* 조회하고싶은 시간 AM 02시부터 3시간 단위 */
		urlBuilder.append("&" + URLEncoder.encode("_type","UTF-8") + "=" + URLEncoder.encode(type, "UTF-8"));	/* 타입 */
		
		/*
		 * GET방식으로 전송해서 파라미터 받아오기
		 */
		URL url = new URL(urlBuilder.toString());
		//어떻게 넘어가는지 확인하고 싶으면 아래 출력분 주석 해제
		//System.out.println(url);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod("GET");
		conn.setRequestProperty("Content-type", "application/json");
		
		BufferedReader rd;
		if(conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
			rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		} else {
			rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
		}
		StringBuilder sb = new StringBuilder();
		String line;
		while ((line = rd.readLine()) != null) {
			sb.append(line);
		}
		rd.close();
		conn.disconnect();
		String result= sb.toString();
		
	 	// Json parser를 만들어 만들어진 문자열 데이터를 객체화 
 		JSONParser parser = new JSONParser(); 
 		JSONObject obj = (JSONObject) parser.parse(result); 
 		// response 키를 가지고 데이터를 파싱 
 		JSONObject parse_response = (JSONObject) obj.get("response"); 
 		// response 로 부터 body 찾기
 		JSONObject parse_body = (JSONObject) parse_response.get("body"); 
 		// body 로 부터 items 찾기 
 		JSONObject parse_items = (JSONObject) parse_body.get("items");
 		// items로 부터 itemlist 를 받기 
 		JSONObject parse_item = (JSONObject) parse_items.get("item");
 		
		Object[] keyObj = parse_item.keySet().toArray();
		String day = null;
 		for(int i = 0 ; i < keyObj.length; i++) {
 			String key = keyObj[i].toString();
 			String str="";		//오전인지 오후인지 저장하는 변수 변수
 			
 			if(key.substring(0,2).equals("wf")) {	//하늘 상태
 				try {	//key에서 숫자만 추출
 	 				day = key.substring(2,key.lastIndexOf("m")-1);
 	 				str = key.substring(key.lastIndexOf("m")-1);
 				}catch(Exception e){
 					day = key.substring(2);
 				}
 				
 				sky.put(day+str, parse_item.get(key).toString());
 			}
 			else if(key.substring(0,4).equals("rnSt")) {	//강수확률
 				try {	//key에서 숫자만 추출
 	 				day = key.substring(4,key.lastIndexOf("m")-1);
 	 				str = key.substring(key.lastIndexOf("m")-1);
 				}catch(Exception e){
 					day = key.substring(4);
 				}
 				
 				tpt.put(day+str, parse_item.get(key).toString());
 			}
 			
		}

 		Iterator<String> skyKeys = sky.keySet().iterator();
 		Iterator<String> tptKeys = tpt.keySet().iterator();
 		while( skyKeys.hasNext() ){
			String skyKey = skyKeys.next();
			String tptKey = tptKeys.next();
			System.out.println(skyKey+"\t하늘 : "+sky.get(skyKey) +", 강수확률 : "+tpt.get(tptKey)+"%");
		}
 		
	}
}