Today
-
Yesterday
-
Total
-

ABOUT ME

-

  • JAVA | 기상청 동네예보, 공공 데이터 Open API 구현하기
    API (Application Programing Interface) 2021. 5. 17. 12:17
    반응형

    ▶ 기존 동네예보 조회서비스는 서비스 종료(2021.10.01.)

    기상청 단기예보 조회서비스로 반드시 활용신청을 해주시기 바랍니다.
    변경내용: 초단기 예보기간 확장, 단기 예보 단위 상세화(3시간 1시간) 등

    # API 호출 URL 변경

    기존)
    http://apis.data.go.kr/1360000/VilageFcstInfoService

    변경)
    http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0

     

     


     

    1. 공공데이터 포털(https://data.go.kr/index.do)에 접속해서 단기예보를 검색한다.

     

     

     

    2. 오픈 API 탭 기상청_단기예보 조회서비스를 활용신청 한다.

     

     

     

    3. 활용 목적 선택, 상세 기능정보 선택, 라이선스 표시 선택 후 활용신청

     

     

     

    4. API 호출 및 데이터 확인에 사용될 참고 문서를 다운로드한다.
    일반 인증키는 API 조회 시 사용될 serviceKey 다.

     

     

     

    5. API 신청이 완료되었으니, 코드를 작성하여 호출해본다.

    JAVASCRIPT

    function weather() {
        jQuery.ajax({
            url : "/api/weather",
            type : "get",
            timeout: 30000,
            contentType: "application/json",
            dataType : "json",
            success : function(data, status, xhr) {
    
                let dataHeader = data.result.response.header.resultCode;
    
                if (dataHeader == "00") {
                   console.log("success == >");
                   console.log(data);
                } else {
                   console.log("fail == >");
                   console.log(data);               
                }
            },
            error : function(e, status, xhr, data) {
                console.log("error == >");
                console.log(e);
            }
        });
    }

     

     

     

    JAVA

    serviceKey=일반 인증키 부분에 발급받은 일반 인증키를 넣어준다.

    호출 시 발표일자(base_date)를 현재일자로 변경 후 확인한다.  
    (포스팅 후 날짜가 계속 지날 것이기 때문에 꼭 확인하여 변경해준다.)
     

    *동네예보(getVilageFcst)는 최근 1일간의 자료만 제공한다.

     

    package com.podo.sample.web;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.HashMap;
    
    import org.json.JSONObject;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    /*
        @RestController : 기본으로 하위에 있는 메소드들은 모두 @ResponseBody를 가지게 된다.
        @RequestBody : 클라이언트가 요청한 XML/JSON을 자바 객체로 변환해서 전달 받을 수 있다.
        @ResponseBody : 자바 객체를 XML/JSON으로 변환해서 응답 객체의 Body에 실어 전송할 수 있다.
                클라이언트에게 JSON 객체를 받아야 할 경우는 @RequestBody, 자바 객체를 클라이언트에게 JSON으로 전달해야할 경우에는 @ResponseBody 어노테이션을 붙여주면 된다. 
        @ResponseBody를 사용한 경우 View가 아닌 자바 객체를 리턴해주면 된다.
    */
    @RestController
    @RequestMapping("/api")
    public class WeatherApiController {
        
        @GetMapping("/weather")
        public String restApiGetWeather() throws Exception {
            /* 
                @ API LIST ~
                
                getUltraSrtNcst 초단기실황조회 
                getUltraSrtFcst 초단기예보조회 
                getVilageFcst 동네예보조회 
                getFcstVersion 예보버전조회
            */
            String url = "http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getVilageFcst"
                + "?serviceKey=일반인증키"
                + "&dataType=JSON"            // JSON, XML
                + "&numOfRows=10"             // 페이지 ROWS
                + "&pageNo=1"                 // 페이지 번호
                + "&base_date=20210517"       // 발표일자
                + "&base_time=0800"           // 발표시각
                + "&nx=60"                    // 예보지점 X 좌표
                + "&ny=127";                  // 예보지점 Y 좌표
            
            HashMap<String, Object> resultMap = getDataFromJson(url, "UTF-8", "get", "");
            
            System.out.println("# RESULT : " + resultMap);
    
            JSONObject jsonObj = new JSONObject();
            
            jsonObj.put("result", resultMap);
            
            return jsonObj.toString();
        }
        
        public HashMap<String, Object> getDataFromJson(String url, String encoding, String type, String jsonStr) throws Exception {
            boolean isPost = false;
    
            if ("post".equals(type)) {
                isPost = true;
            } else {
                url = "".equals(jsonStr) ? url : url + "?request=" + jsonStr;
            }
    
            return getStringFromURL(url, encoding, isPost, jsonStr, "application/json");
        }
        
        public HashMap<String, Object> getStringFromURL(String url, String encoding, boolean isPost, String parameter, String contentType) throws Exception {
            URL apiURL = new URL(url);
    
            HttpURLConnection conn = null;
            BufferedReader br = null;
            BufferedWriter bw = null;
    
            HashMap<String, Object> resultMap = new HashMap<String, Object>();
    
            try {
                conn = (HttpURLConnection) apiURL.openConnection();
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(5000);
                conn.setDoOutput(true);
    
                if (isPost) {
                    conn.setRequestMethod("POST");
                    conn.setRequestProperty("Content-Type", contentType);
                    conn.setRequestProperty("Accept", "*/*");
                } else {
                    conn.setRequestMethod("GET");
                }
    
                conn.connect();
    
                if (isPost) {
                    bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
                    bw.write(parameter);
                    bw.flush();
                    bw = null;
                }
    
                br = new BufferedReader(new InputStreamReader(conn.getInputStream(), encoding));
    
                String line = null;
    
                StringBuffer result = new StringBuffer();
    
                while ((line=br.readLine()) != null) result.append(line);
    
                ObjectMapper mapper = new ObjectMapper();
    
                resultMap = mapper.readValue(result.toString(), HashMap.class);
            } catch (Exception e) {
                e.printStackTrace();
                throw new Exception(url + " interface failed" + e.toString());
            } finally {
                if (conn != null) conn.disconnect();
                if (br != null) br.close();
                if (bw != null) bw.close();
            }
    
            return resultMap;
        }
    }

     

    6. 호출 결과 확인

     

     

     


     

    ※ 참고 문서 데이터 확인 (API 상세 페이지에서 참고 문서 다운로드 가능)

    기상청41_단기예보 조회서비스_오픈API활용가이드_최종.docx

    문서를 참고하여 위의 호출 결과 첫 번째 데이터를 정리해보면

     

    2021년 5월 17일 12:00시 강수확률은 60% 인 것을 알 수 있다.

     

     

    *기상청 18_단기예보 조회서비스_오픈 API 활용 가이드_격자_위경도.xlsx 에는
    API 호출 시 사용될 지역별 nx, ny(위/경도)가 정리되어있다.

    WeatherApiController.zip
    0.00MB

    반응형

    댓글

Designed by Tistory.