[SpringBoot + JPA]공공데이터 API를 DB에 저장해보자 - 2

·5일 전
0
post-thumbnail

💡API 데이터를 JAVA로 가져와서 바꿔보자

📌API는 보통 JSON 또는 XML형태로 제공하기 때문에 활용하려면 API데이터를 파싱하여 JAVA데이터로 받아야한다.
내가 원하는 대로 사용하기 위해 차근차근 API를 JSON형태로 JAVA로 가져오고, 그걸 파싱하고 마지막으로 JPA를 이용하여 DB에 저장해 보도록 하겠다.

📗1. API데이터를 JSON형태로 JAVA로 가져오자

  • 내가 사용하려는 공공데이터 API는 예시 코드가 없어서 다른 데이터들의 예시 코드를 나에게 맞게 수정했다.
public class test {
    public static void main(String[] args) throws IOException {
        // 1. URL을 만들기 위한 StringBuilder.
        StringBuilder urlBuilder = new StringBuilder("https://api.odcloud.kr/api/15136373/v1/uddi:84f86747-7012-4d74-b4c6-9d5068312ac4"); /*URL*/
        // 2. 오픈 API의요청 규격에 맞는 파라미터 생성, 발급받은 인증키.
        urlBuilder.append("?").append(URLEncoder.encode("page", StandardCharsets.UTF_8)).append("=").append(URLEncoder.encode("1", StandardCharsets.UTF_8)); /*페이지 번호*/
        urlBuilder.append("&").append(URLEncoder.encode("perPage", StandardCharsets.UTF_8)).append("=").append(URLEncoder.encode("1", StandardCharsets.UTF_8)); /*한 페이지 결과 수*/
        urlBuilder.append("&").append(URLEncoder.encode("returnType", StandardCharsets.UTF_8)).append("=").append(URLEncoder.encode("JSON", StandardCharsets.UTF_8)); /*XML 또는 JSON*/
        urlBuilder.append("&").append(URLEncoder.encode("serviceKey", StandardCharsets.UTF_8)).append("=서비스키"); /*Service Key*/
        // 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.println("Response code: " + conn.getResponseCode());
        // 8. 응답코드가 정상(200~300)이면 전달받은 데이터를 BufferedReader 객체로 저장.
        BufferedReader rd;
        if(conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
            rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        } else {
            rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
        }
        // 9. 저장된 데이터를 라인별로 읽어 StringBuilder 객체로 저장.
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = rd.readLine()) != null) {
            sb.append(line);
        }
        // 10. 객체 해제.
        rd.close();
        conn.disconnect();
        // 11. 전달받은 데이터 확인.
        System.out.println(sb.toString());
        System.out.println(url);
    }
}
  • 이전 1편에서 테스트했던 URL을 확인해보면

https://api.odcloud.kr/api/15136373/v1/uddi:84f86747-7012-4d74-b4c6-9d5068312ac4?page=1&perPage=1&returnType=JSON&serviceKey=서비스키

  • 이렇게 구성되어 있는데, 이를 토대로 코드 2번처럼 url을 구현해준다.
  • Parameters는 page가 1이고, Perpage가 1, returnTtype이 JSON이므로
    ➡️JSON 형태로 각 페이지마다 1개의 데이터를 출력하며, 첫번째 페이지 데이터를 가져온다. 라는 뜻이 된다.
  • 응답코드는 200~300 즉, 정상일때만 객체를 저장한다.
  • 출력 결과를 보면 응답코드가 출력되고 1페이지에 1개의 데이터가 출력된다. 출력된 url을 보면 url이 잘 전달된것도 확인할 수 있다.

📗2. API데이터를 JSON으로 전체 데이터 출력을 해보자.

위에서는 필수 Parameter로 pageperPage가 들어간다. 즉, 한번 출력할때 한 페이지 씩만 출력 된다는건데, API데이터에서 내가 원하는 데이터들을 찾으려면 전체 데이터 출력을 해야하므로 While문을 이용해서 전체 데이터 출력을 해보자

public class ApITest {
    public static void main(String[] args) throws IOException, IOException {
        int page = 1;
        boolean hasMoreData = true;
        ObjectMapper objectMapper = new ObjectMapper(); // JSON 파싱용

        System.out.println("🚀 ApiExplorer started!");

        while (hasMoreData) {
            // 1. URL 생성
            StringBuilder urlBuilder = new StringBuilder("https://api.odcloud.kr/api/15136373/v1/uddi:84f86747-7012-4d74-b4c6-9d5068312ac4");
            urlBuilder.append("?").append(URLEncoder.encode("page", StandardCharsets.UTF_8)).append("=").append(page);
            urlBuilder.append("&").append(URLEncoder.encode("perPage", StandardCharsets.UTF_8)).append("=").append("5"); // perPage 값 증가
            urlBuilder.append("&").append(URLEncoder.encode("returnType", StandardCharsets.UTF_8)).append("=").append("JSON");
            urlBuilder.append("&").append(URLEncoder.encode("serviceKey", StandardCharsets.UTF_8))
                    .append("=taoPZY395PqfMgnAZMcUnm/fxpYemRwZ8E30EfFyoDRAaQwbmou/fcvoq6DpixOwN0WGOBUrEdxCnk1gO17RAQ==");

            URL url = new URL(urlBuilder.toString());
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Content-type", "application/json");

            System.out.println("Response code: " + conn.getResponseCode());

            BufferedReader rd = (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300)
                    ? new BufferedReader(new InputStreamReader(conn.getInputStream()))
                    : new BufferedReader(new InputStreamReader(conn.getErrorStream()));

            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = rd.readLine()) != null) {
                sb.append(line);
            }
            rd.close();
            conn.disconnect();

            // JSON 파싱
            JsonNode jsonNode = objectMapper.readTree(sb.toString()); //JSON문자열을 JsonNode로 구문분석
            JsonNode dataArray = jsonNode.get("data"); //구문 분석된 JSON문자열에서 data필드를 추출하여 jsonNode로 저장

            //모든 페이지 출력시에는 dataArray == null || !dataArray.isArray() || dataArray.isEmpty()로 조건문 주기
            if (page == 4) {
                hasMoreData = false; // 더 이상 데이터가 없으면 종료
                System.out.println("✅ All data fetched.");
            } else {
                // 데이터 처리 (여기서 필터링 및 중복 제거 가능)
                System.out.println("Fetched page: " + page + ", Records: " + dataArray.size());
                System.out.println("==================================================");
                System.out.println(dataArray);
                page++; // 다음 페이지로
            }
        }
    }
}
  • 1번의 코드와 달라진건 ObjectMapper를 사용한다는 것과 API 처리 코드가 while문으로 감싸져 있다는 것이다.

  • ObjectMapper란 JAVA의 jackson라이브러리에서 제공하는 클래스로, JSON데이터 변환을 처리하여 JSON객체를 java변수로 쉽게 바꾸고(역직렬화) 그 반대로도(직렬화)바꿀수 있게 해준다.

  • JsonNode dataArray = jsonNode.get("data"); 여기서말하는 data필드는 아래의 JSON 결과에서 되는 data를 말한다. API의 구문에 따라 변경하면 된다.

  • true로 값을 준 hasMoreData를 이용하여 while문을 실행 시키고, 데이터가 있다면 page의 값만 1씩 증가시킨 채 계속 반복문을 돌린다.

  • 모든 페이지 출력 시에는 주석처럼 dataArray == null || !dataArray.isArray() || dataArray.isEmpty()를 조건문으로 주면 되는데, 가져온 API의 데이터가 너무 많아서 3페이지까지만 출력하도록 설정해 놓았다.

  • 출력 결과를 확인하면 3페이지 까지 모든 데이터가 출력된다.

  • 다음 편에서는 드디어 JPA를 이용하여 API를 DB에 넣는 것 까지 해보도록 하겠다.

profile
백엔드 개발자를 꿈꿉니다 / 이전 블로그 : https://po-dadak.tistory.com/category

0개의 댓글

관련 채용 정보