본문 바로가기

JAVA

[JAVA] 공공데이터 오픈 API 사용하기

반응형

공공데이터포털은 정부에서 운영하는 오픈 API 서비스로 정부의 공공기관에서 수집된 다양한 종류의 데이터들을 일반 기업들 및 국민 모두가 무료로 자유롭게 사용할 수 있도록 제공하는 서비스이다. 

실제로 개발 학원에서도 공공데이터 포털의 데이터를 활용한 프로젝트도 진행하고 공모전 같은 곳에서도 많이 사용하는 사이트이다.

 

나 역시 공공데이터 포털에 있는 데이터를 하나 활용하여 월마다 데이터를 갱신하는 방식을 통해 간단한 서비스를 제공하는 프로젝트를 구현하려고 한다. 

 

 

 

 

1. 공공데이터 API 신청

우선 공공데이터포털로 가서 회원가입 및 로그인을 해주자

https://www.data.go.kr/

 

공공데이터 포털

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

www.data.go.kr

 

 

 

 

그리고 원하는 데이터를 하나 찾아서 들어가면 된다.

나는 출산율에 대한 데이터가 필요하기에 아래와 같이 검색하여 찾아들어 갔다.

 

 

 

내가 원하는 데이터들이 들어있는지 확인하려면 CSV 파일을 통해 먼저 확인해 볼 수 있다.

오픈 API를 활용하고자 한다면 위 이미지에서 빨간 박스로 표시한 '오픈 API' 탭으로 이동을 한 뒤 아래의 이미지에서 활용 신청을 눌러준다.

 

 

 

 

 

원하는 대로 활용 목적과 내용을 입력한 뒤 동의에 체크를 하고 활용 신청을 하면 바로 승인이 된다.

 

 

 

 

그리고 마이페이지에서 아래 이미지와 같이 활용신청 현황에서 자신이 신청한 공공 API 확인이 가능하다.

 

728x90

 

 

 

 

 

 

 

 

 

2. API 통신 구현하기

우선 활용 신청이 완료된 API 페이지로 들어가서 사용 방법을 확인해본다.

 

Base URL을 확인하고 아래 API 목록에서 API를 확인해 준다.

이외 필요한 쿼리스트링 값들은 Open API 명세 확인 가이드에서 확인이 가능하다.

 

 

필요한 정보들을 확인 해준 다음 코드를 작성해 보자

// PopulationMainService.java

@RequiredArgsConstructor
@Service
public class PopulationMainService {

    public void schedulerPopulationUpdate() {
        try {
            for(int i=1; i<=4; i++) {
                // 1. URL 설정
                StringBuilder urlBuilder = new StringBuilder("https://api.odcloud.kr/api/15097972/v1/uddi:780a2373-bf11-4fb6-b3e4-ed4119571817");
                // 2. 오픈 API의요청 규격에 맞는 파라미터 생성, 발급받은 인증키.
                urlBuilder.append("?" + URLEncoder.encode("page","UTF-8") + "=" + URLEncoder.encode(String.valueOf(i), "UTF-8"));
                urlBuilder.append("&" + URLEncoder.encode("perPage","UTF-8") + "=" + URLEncoder.encode("1000", "UTF-8"));
                urlBuilder.append("&" + URLEncoder.encode("serviceKey","UTF-8") + "=" + ${인증키});
                // 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.print(i + "번째 통신 결과 : ");
                if(conn.getResponseCode() == 200) {
                    System.out.println("성공");
                } else {
                    System.out.println("실패");
                }
                // 8. 전달받은 데이터를 BufferedReader 객체로 저장.
                BufferedReader br;
                if(conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
                    br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                } else {
                    br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
                }
                // 9. 저장된 데이터를 라인별로 읽어 StringBuilder 객체로 저장.
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                // 10. 객체 해제.
                br.close();
                conn.disconnect();
                
                System.out.println(sb.toString());
            }

        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

 

나 같은 경우 가져올 데이터가 많기에 반복문을 사용하였다. 한 번에 많은 데이터를 호출하니 통신은 성공해도 데이터가 null로 들어와 지기에 최대 단위로 나뉘어 반복문을 돌렸다.

 

JAVA에서는 위 형태로 구성해 주면 웬만한 통신은 다 될 것이다.

포털에서 확인한 정보들로 URL을 구성하고 필요한 쿼리스트링 값들을 추가해 준다. 그리고 오픈 API는 GET 형태로 데이터 통신을 하기에 GET으로 지정해 주고 통신이 잘 되는지 체크를 해주고 최종적으로 StringBuilder에 값이 잘 담기는지 확인해 주면 된다.

 

추가로 인증키는 내가 직접 해본 결과 서버단에서 진행 시엔 인코딩된 인증키 값을 보내주어야 하고 클라이언트단에서 진행시엔 디코딩된 인증키 값을 보내주니 진행이 되었다. 이 부분은 직접 진행을 해보면서 확인해 주면 되겠다.

 

HttpURLConnection 관련 포스팅

2024.07.08 - [JAVA] - [JAVA] HttpURLConnection, HttpClient 사용하기

 

[JAVA] HttpURLConnection, HttpClient 사용하기

우선 JDK 1.8 환경에선 HttpClient가 import 되지 않는다. 이유는 모르겠지만 JDK 1.6, 1.7, 11, 17 버전 등에선 잘 동작하니 1.8를 피해서 진행해주면 된다. HttpURLConnection, HttpClient를 사용해서 서버간 통신을

rlawo32.tistory.com

 

반응형

 

 

 

 

 

 

 

 

 

3. JSON 데이터 DTO에 매핑하기

이제 데이터는 잘 가져와진다. 하지만 이 많은 데이터들을 효율적으로 사용하기 위해 DTO에 담아 List 형태로 활용을 하려 한다. 데이터가 JSON 형태로 전달이 되기에 활용이 쉽지만 JSON key 값이 한글로 되어있기에 DTO에 어떻게 담을지 고민하게 되었다. 

찾아보니 Jackson을 활용해서 JSON 데이터를 다루면 한글로 된 JSON key 값을 DTO에 맞게 매핑하여 다룰 수 있는 것을 알게 되었다.

 

우선 build.gradle에 Jackson을 추가해 주자

implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.15.2'

 

 

 

그리고 사용할 DTO를 작성해 주자

아래와 같이 Jackson annotation의 JsonProperty를 사용하면 한글로 된 JSON key 값을 DTO에 매핑하여 사용할 수 있다.

// PopulationResultDto.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PopulationResultDto {

    @JsonProperty("행정기관코드")
    private Long adminCode;

    @JsonProperty("기준연월")
    private String standardDate;

    @JsonProperty("시도명")
    private String nameCity;

    @JsonProperty("시군구명")
    private String nameWard;

    @JsonProperty("읍면동명")
    private String nameTown;

    @JsonProperty("계")
    private Long popTotal;

    @JsonProperty("남자")
    private Long popMTotal;

    @JsonProperty("여자")
    private Long popWTotal;
}

 

 

 

 

통신 성공으로 생성된 String 값을 JSON 형태로 변환 후 매핑을 하여 DTO List에 넣어준다.

// PopulationMainService.java

@RequiredArgsConstructor
@Service
public class PopulationMainService {

    public void schedulerPopulationUpdate() {
        try {
            for(int i=1; i<=4; i++) {
               	
                ...
                
                // 10. 객체 해제.
                br.close();
                conn.disconnect();

                ObjectMapper objectMapper = new ObjectMapper();

		// String -> JSON 변환
                JsonNode node1 = objectMapper.readTree(sb.toString());
                // JSON 안의 'data' 객체 추출
                JsonNode node2 = node1.findValue("data");

		// JSON엔 존재하나 DTO에는 존재하지 않는 매핑 값에 대해 처리
                objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                // DTO List 생성
                List<PopulationResultDto> list = Arrays.asList(objectMapper.treeToValue(node2, PopulationResultDto[].class));
                
                // List 값 확인
                for(int n=0; n<list.size(); n++) {
                    System.out.print(list.get(n).getNameCity());
                    System.out.print(list.get(n).getNameWard());
                    System.out.println(list.get(n).getNameTown());
                }
            }

        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

 

 

 

 

아래와 같이 list.get으로 가져온 DTO 값이 잘 들어간 것을 확인할 수 있다.

 

 

 

 

 

 

728x90
반응형

'JAVA' 카테고리의 다른 글

[JAVA] 이메일 인증 구현하기  (0) 2024.07.19
[JAVA] HttpURLConnection, HttpClient 사용하기  (0) 2024.07.08