최원종의 개발 블로그

공공데이터 API 실습 - HTTP - 4 본문

Java/JAVA 유용한 클래스

공공데이터 API 실습 - HTTP - 4

chl6698 2026. 4. 1. 16:40

API

API(Application Programming Interface)는 는 외부에서 데이터를 요청할 수 있도록 열어둔 창구

우리 프로그램 ── HTTP 요청 ──► 공공데이터 서버
              ◄── JSON 응답── (미세먼지, 날씨, 버스 등 실제 데이터)

API 키

공공 API는 무제한으로 사용하면 서버에 부하가 생김.

그래서 사용자를 식별하는 API 키(Key) 를 발급받아서 요청에 포함함.

요청 URL:
http://apis.data.go.kr/서비스주소?serviceKey=내API키&파라미터=값
                                  ↑
                              여기에 포함

실습 API 키 발급받기

공공데이터 포털 사이트 (https://www.data.go.kr/)

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

 

  1. 로그인 / 회원가입
  2. 한국환경공단 에어코리아 미세먼지 경보 발령 현황 검색
  3. 활용신청 -> API키 발급

 


URL Encoder 가 필요한 이유

URL 에는 특수문자나 한글을 그대로 넣을 수 없다

인코딩 전: 미세먼지
인코딩 후: %EB%AF%B8%EC%84%B8%EB%A8%BC%EC%A7%80

인코딩 전: API 키 (/ + = 같은 특수문자 포함)
인코딩 후: %2F6V2ib...

URLEncoder.encode("값", "UTF-8") 으로 변환합니다.

 


실습 코드

package http.api;

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

public class ApiExplorer {
    public static void main(String[] args) throws IOException {
        //요청할 URL 만들기
        StringBuilder urlBuilder = new StringBuilder("http://apis.data.go.kr/B552584/UlfptcaAlarmInqireSvc/getUlfptcaAlarmInfo"); /*URL*/
        urlBuilder.append("?" + URLEncoder.encode("serviceKey", "UTF-8") + "=" + "vrBoYA%2BMQvPHugV9ZdXZHMhQ5qKM2cGSNOmpqtYgizv2aU6tX7C2Mhpug5Qf%2F7a2X6F%2FL2w2jm%2FCbJ5%2Fyzifug%3D%3D"); /*Service Key*/
        urlBuilder.append("&" + URLEncoder.encode("returnType", "UTF-8") + "=" + URLEncoder.encode("JSON", "UTF-8")); /*xml 또는 json*/
        urlBuilder.append("&" + URLEncoder.encode("numOfRows", "UTF-8") + "=" + URLEncoder.encode("2", "UTF-8")); /*한 페이지 결과 수*/
        urlBuilder.append("&" + URLEncoder.encode("pageNo", "UTF-8") + "=" + URLEncoder.encode("1", "UTF-8")); /*페이지번호*/
        urlBuilder.append("&" + URLEncoder.encode("year", "UTF-8") + "=" + URLEncoder.encode("2025", "UTF-8")); /*측정 연도*/
        urlBuilder.append("&" + URLEncoder.encode("itemCode", "UTF-8") + "=" + URLEncoder.encode("PM10", "UTF-8")); /*미세먼지 항목 구분(PM10, PM25), PM10/PM25 모두 조회할 경우 파라미터 생략*/
       //URL을 HTTP로 연결
        URL url = new URL(urlBuilder.toString()); //문자열 URL을 실제URL객체로 바꿈
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        //GET방식으로 요청
        conn.setRequestMethod("GET");

        //요청 헤더 설정하는 코드, JSON관련 내용을 다루고 있다는 정도
        conn.setRequestProperty("Content-type", "application/json");
        System.out.println("요청 상태 : " + conn.getResponseCode());

        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(); // sb는 서버가 준 응답 내용을 누적해서 저장할 변수
        String line;//한 줄씩 읽을 때 임시로담는 변수
        while ((line = rd.readLine()) != null) { //rd.readLine()로 한 줄씩 읽고 더이상 읽을 줄이 없으면 종료
            sb.append(line);//읽은 줄을 sb에 계속 이어붙여 전체 응답 문자열 생성
        }
        rd.close();//입력 스트림 닫기
        conn.disconnect();//서버 연결 종료
        System.out.println(sb.toString());//결과 출력
    }
}
더보기

출력 결과

"C:\Program Files\Amazon Corretto\jdk21.0.10_7\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2025.3.3\lib\idea_rt.jar=65470" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\chl\work_space\java_oop3\out\production\java_oop3;C:\chl\work_space\java_oop3\lib\lombok.jar;C:\chl\work_space\java_oop3\lib\gson-2.10.1.jar http.api.ApiExplorer
요청 상태 : 200
{"response":{"body":{"totalCount":58,"items":[{"clearVal":"73","sn":"160","districtName":"충북","dataDate":"2025-12-18","issueVal":"170","issueTime":"15:00","clearDate":"2025-12-18","issueDate":"2025-12-18","moveName":"북부권역","clearTime":"17:00","issueGbn":"주의보","itemCode":"PM10"},{"clearVal":"79","sn":"149","districtName":"전북","dataDate":"2025-12-01","issueVal":"154","issueTime":"08:00","clearDate":"2025-12-01","issueDate":"2025-12-01","moveName":"동부권역","clearTime":"10:00","issueGbn":"주의보","itemCode":"PM10"}],"pageNo":1,"numOfRows":2},"header":{"resultMsg":"NORMAL_CODE","resultCode":"00"}}}

종료 코드 0(으)로 완료된 프로세스

DTO 클래스

package http.api;

import lombok.Data;

import java.util.List;

@Data
public class AirQualityDto {

    private Response response;

    @Data
    public static class Response {
        private Header header;
        private Body body;
    }

    @Data
    public static class Header {
        private String resultMsg;
        private String resultCode;
    }

    @Data
    public static class Body {
        private int totalCount;
        private List<Item> items; // JSON Array 대응
        private int pageNo;
        private int numOfRows;
    }

    @Data
    public static class Item {
        private String clearVal;
        private String sn;
        private String districtName;
        private String dataDate;
        private String issueVal;
        private String issueTime;
        private String clearDate;
        private String issueDate;
        private String moveName;
        private String clearTime;
        private String issueGbn;
        private String itemCode;
    }
}

실시간 날씨 정보 API - 해외(openweathermap api)

package http.api;

import com.google.gson.Gson;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class OpenWeather {

    public static void main(String[] args) {
        String apiKey = "f9ee3f4e5fd02643fc39cb4a264ba57e"; // 발급받은 API 키 입력
        String city = "Seoul";
        String urlString = "https://api.openweathermap.org/data/2.5/weather?q=" + city +
                "&appid=" + apiKey + "&units=metric&lang=kr";

        try {
            // 1. URL 객체 생성 및 연결 설정
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000); // 연결 타임아웃 5초
            conn.setReadTimeout(5000);    // 읽기 타임아웃 5초
            System.out.println(urlString.toString());

            // 2. 응답 코드 확인 (200 OK 인지 체크)
            int responseCode = conn.getResponseCode();

            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();

            //System.out.println(sb.toString());
            String jsonString = sb.toString();
            //System.out.println("JSON 응답 : " + sb);

            //도전 문제 1 - 파싱 처리 직접
            //출력 값
            //상태: 맑음
            //기온 : 18,5
            //습도 42%
            //풍속2.1m/s
            Gson gson = new Gson();
            OpenWeatherDTO weatherDTO = gson.fromJson(jsonString.toString(), OpenWeatherDTO.class);
            System.out.println("도시 이름 : " + weatherDTO.getName());
            System.out.println("상태 : " + weatherDTO.getWeather().get(0).getDescription());
            System.out.println("기온 : " + weatherDTO.getMain().getTemp());
            System.out.println("습도 : " + weatherDTO.getMain().getHumidity());
            System.out.println("풍속 : " + weatherDTO.getWind().getSpeed());

            //ㅏ---간단한 날씨 알림 로직 --
            //만약 25도 보다 크다면 오늘 덥다
            //그 이하라면 날씨가 쌀쌀합니다
            //오늘은 날씨가 따뜻하네요.산책하기

            if (weatherDTO.getMain().getTemp() > 25) {
                System.out.println("오늘 덥다");
            } else if (weatherDTO.getMain().getTemp() <= 25) {
                System.out.println("날씨가 쌀쌀합니다");
            }

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
더보기

출력결과

"C:\Program Files\Amazon Corretto\jdk21.0.10_7\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2025.3.3\lib\idea_rt.jar=62579" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\chl\work_space\java_oop3\out\production\java_oop3;C:\chl\work_space\java_oop3\lib\lombok.jar;C:\chl\work_space\java_oop3\lib\gson-2.10.1.jar http.api.OpenWeather
https://api.openweathermap.org/data/2.5/weather?q=Seoul&appid=f9ee3f4e5fd02643fc39cb4a264ba57e&units=metric&lang=kr
도시 이름 : Seoul
상태 : 튼구름
기온 : 17.76
습도 : 55
풍속 : 1.03
날씨가 쌀쌀합니다

종료 코드 0(으)로 완료된 프로세스

 

'Java > JAVA 유용한 클래스' 카테고리의 다른 글

JDBC(Java Database Connectivity)  (1) 2026.04.10
HTTP Client 연습 - 5  (0) 2026.04.01
JSON 파싱 - HTTP-3  (0) 2026.04.01
JSON - HTTP - 2  (0) 2026.03.31
HTTP- 1  (0) 2026.03.31