프로그래밍/JAVA & SPRING

[JAVA][API] 공공데이터 API를 DB에 저장

나의 개발자 2022. 12. 22. 11:30

경기도 약국 현황 API

 

약국 현황 | 데이터셋 상세 Open API | 경기데이터드림

경기도 내 약국 현황입니다. 약사가 의약품을 조제 또는 판매를 주목적으로 하는 업체(소)의 정보를 제공합니다. ※경기도 31개 시군의 인ㆍ허가 데이터입니다.

data.gg.go.kr


 

전체 Code
@GetMapping("/apiTest")
    public void apiTest() throws IOException, ParserConfigurationException, SAXException {
        String ServiceKey = "b3983c9e6d30497585f21dd3fad84058"; //발급받은 key
        String type="xml"; // 리턴 데이터 타입
        String apiUrl = "https://openapi.gg.go.kr/Parmacy?KEY="+ServiceKey+"&pIndex=1&pSize=100"+"&Type="+type; //api 요청 url

        //URL 객체 생성
        URL url = new URL(apiUrl); //URL 객체 생성

        //url.openConnection() : URLConnection 클래스 얻기
        // URL 객체가 http://로 시작하는 경우, url.openConnection()메소드가 리턴하는 URLConnection 객체는 HttpURLConnection의 인스턴스가 될 수 있기 때문에
        // 리턴된 URLConnection을 HttpURLConnection으로 캐스팅해서 사용
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        //urlConnection 객체 요청 방식 설정
        urlConnection.setRequestMethod("GET");

        //버퍼를 이용한 입력
        //BufferedReader br 선언
        BufferedReader br;

        // getInputStream() : 입력 스트림 가져오는 메소드
        // new InputStreamReader() : InputStreamReader 객체 생성
        // new BufferedReader() : BufferedReader 객체 생성
        // Stream : 문자 단위 ex) h, e, l, l, o, , w, o, r, l, d, !
        // Buffer : 문자열 단위 ex) hello world!
        // urlConnection.getInputStream()을 UTF-8로 문자 단위로 받아서 InputStreamReader 객체를 생성한 후
        // InputStreamReader 객체로 BufferedReader 객체 생성 ( 데이터를 문자열로 읽기 위해 BufferedReader로 래핑함)
        br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),"UTF-8"));

        System.out.println("BufferedReader : "+br.readLine());

        // DocumentBuilderFactory : XML 문서로부터 DOM 오브젝트 트리를 생성하는 parser를 얻을 수 있도록 하는 API를 정의하는 클래스
        // DocumentBuilderFactory 객체 생성
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();

        // DocumentBuilder : XML문서로부터 document instance를 얻을 수 있도록 API를 정의하는 클래스
        // DocumentBuilder의 인스턴스를 할당하기 위해서 documentBuilderFactory.newDocumentBuilder() 메소드를 사용
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

        //Document : HTML, XML을 표현하는 클래스, 개념적 트리구조의 root(파싱된 XML문서에 대한 접근 방법을 제공하는 클래스)
        Document doc1 = documentBuilder.parse(apiUrl);
        doc1.getDocumentElement().normalize(); // 문서 구조 안정화

        //NodeList : 태그이름으로 정보를 읽어와서 저장(노드형태)
        // head 태그를 가져와 NodeList 타입으로 저장
        NodeList nodes1 = doc1.getElementsByTagName("head");
        Node node1 = nodes1.item(0);
        Integer pageNo = 1;
        Element element = (Element) node1;
        System.out.println("list_total_count : "+getValue("list_total_count",element));
        if((Integer.valueOf(getValue("list_total_count", element))/100)>1){
            pageNo = (int)Math.ceil(Float.parseFloat(getValue("list_total_count",element))/100);
            System.out.println("list_total_count 1보다 큼 : "+pageNo);
        }else{
            pageNo = (int)Math.ceil(Float.parseFloat(getValue("list_total_count",element))/100);
            System.out.println("liat_total_count 1보다 작음 : "+pageNo);
        }

        // ArrayList 배열 생성
        List<Pharmacy> pharmacyList = new ArrayList<>();
        for(int i = 1; i<=pageNo;i++){
            String apiUrl2 = "https://openapi.gg.go.kr/Parmacy?KEY="+ServiceKey+"&pIndex="+i+"&Type="+type; //api의 페이지 위치를 변경하여 모든 데이터를 가져옴

            DocumentBuilderFactory documentBuilderFactory1 = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder1 = documentBuilderFactory1.newDocumentBuilder();
            Document doc = documentBuilder1.parse(apiUrl2);
            doc.getDocumentElement().normalize();

            System.out.println("========================("+i+"/"+pageNo+")========================");

            NodeList nodes = doc.getElementsByTagName("row"); // row 태그를 nodes에 저장
            for(int j = 0; j<nodes.getLength(); j++){ //nodes의 개수만큼 for문을 실행
                System.out.println("nodes.getLength() : "+nodes.getLength());
                Node node = nodes.item(j);//nodes에 저장된 값을 node에 저장
//                System.out.println("i : "+i+" , "+node.getNodeType()+","+Node.ELEMENT_NODE);
                if(node.getNodeType()==Node.ELEMENT_NODE){
                    Element element1 = (Element) node;
                    pharmacyList.add(new Pharmacy(getValue("SIGUN_CD", element1), getDoubleValue("REFINE_WGS84_LAT",element1)
                                                , getValue("LICENSG_DE",element1), getValue("LICENSG_CANCL_DE",element1)
                                                , getValue("BSN_STATE_DIV_CD",element1), getValue("UNITY_BSN_STATE_DIV_CD",element1)
                                                , getValue("UNITY_BSN_STATE_NM",element1), getValue("BSN_STATE_NM",element1)
                                                , getValue("CLSBIZ_DE",element1), getValue("SUSPNBIZ_BEGIN_DE",element1)
                                                , getValue("SUSPNBIZ_END_DE",element1), getValue("REOPENBIZ_DE",element1)
                                                , getValue("LOCPLC_FACLT_TELNO",element1), getValue("LOCPLC_AR_INFO",element1)
                                                , getValue("BIZPLC_NM",element1), getValue("BIZCOND_DIV_NM_INFO",element1)
                                                , getDoubleValue("X_CRDNT_VL",element1), getDoubleValue("Y_CRDNT_VL",element1)
                                                , getValue("PARMACY_BSN_AR",element1), getValue("APPONT_DE",element1)
                                                , getValue("REFINE_LOTNO_ADDR",element1), getValue("REFINE_ROADNM_ADDR",element1)
                                                , getValue("REFINE_ZIP_CD",element1),  getDoubleValue("REFINE_WGS84_LOGT",element1)
                                                , getValue("SIGUN_NM",element1)));
                }
            }
        }

        pharmacyRepository.saveAll(pharmacyList);

        urlConnection.disconnect();

    }