국비 93 - 공공데이터

냐아암·2023년 8월 27일
0

국비

목록 보기
108/114

📍 공공데이터(Open Data)

공공기관에서 사용할 목적으로 처리된 자료 또는 정보

🔑 OpenAPI 방식

  • HTTPRequest 요청을 보내면 서버가 데이터를 응답해주는 방식
  • 요청해야 하는 주소, 파라미터, 반환 데이터 등이 정해져있으므로 인증키를 발급받아야 한다.

🔑 데이터 포맷 종류

  • XML 형식 : 마크업 언어. 웹에서 구조화된 문서를 전송할 수 있게 설계되어 각 요소들의 독립성 보장 -> 문서의 호환성, 내용의 독립성, 요소 변경의 용이성
  • JSON 형식 : JS 구문 형식으로 프로그래밍 언어나 플랫폼에 독립적 -> C, C++, C#, Java, JS 등 많은 언어에서 이용 가능
  • 이 밖에도 CSV 형식, 엑셀 문서 형식이 있다.

🔑 공공데이터 OpenAPI를 사용하기 위한 절차
1. https://www.data.go.kr/ 로그인
2. 사용하고자 하는 공공데이터 조회 -> 신청 (참고자료 - 직업훈련)
3. 마이페이지 -> 데이터 활용 -> Open API -> 활용신청 현황!

  1. 인증키 : 마이페이지 -> 데이터 활용 -> Open API -> 인증키 발급 현황

  2. 상세설명 -> 요청변수 참고(필수)

  3. 미리보기(확인) -> 요청 주소 확인


📍 HttpUrlConnection 객체 사용 절차

  1. 요청할 주소를 전달해서 java.net.URL 객체 생성하기
  2. 생성된 URL 객체를 가지고 HttpUrlConnection 객체 얻어내기
  3. 요청 시 필요한 Header 설정하기
  4. 해당 OpenAPI 서버로 요청 보낸 후 입력 스트림을 통해 응답데이터 받기
  5. 다 사용한 스트림 객체 반납하기

🔑 JSON 형식

(gson 라이브러리 사용)

package com.kh.opendata.run;

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

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.kh.opendata.model.vo.Air;

public class AirPollutionJavaAppRun {
	
	// 발급받은 인증키 변수 처리
	public static final String SERVICEKEY ="인증키";
	
	public static void main(String[] args) throws IOException { 
										// UnsupportedEncodingException의 부모로 예외처리
		
		// OpenAPI 서버로 요청하고자 하는 url 작성
		String url = "http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getCtprvnRltmMesureDnsty";
		
		url += "?serviceKey=" + SERVICEKEY; // 서비스키가 제대로 부여되지 않았을 경우 => SERVICE_KEY_IS_NOT_REGISTERED_ERROR
		url += "&sidoName=" + URLEncoder.encode("서울", "UTF-8");
		url += "&returnType=json";
		
		// System.out.println(url);
		
		// ** HTTPURLConnection 객체를 활용해서 OpenAPI 요청 절차 **
		// 1. 요청할 주소를 전달해서 java.net.URL 객체 생성하기
		URL requestUrl = new URL(url);
		
		// 2. 생성된 URL 객체를가지고 HttpUrlConnection 객체 얻어내기
		HttpURLConnection urlConn = (HttpURLConnection)requestUrl.openConnection(); // 다운캐스팅
		
		// 3. 요청 시 필요한 Header 설정하기
		urlConn.setRequestMethod("GET");
		
		// 4. 해당 OpenAPI 서버로 요청 보낸 후 입력 스트림을 통해 응답데이터 받기
		BufferedReader br = new BufferedReader(new InputStreamReader( urlConn.getInputStream() ));
		
		String responseText="";
		String line;
		while((line=br.readLine()) != null) { // 한 줄씩 읽어 올 데이터가 있는 동안 반복
			
			// System.out.println(line);
			responseText += line;
			
		}
		
		// System.out.println(responseText);
		
		/* JSON 형태
	      {
	         "response":
	            {
	               "body":
	            {
	               "totalCount":40,
	               "items":
	                  [
	                      {
	                         "so2Grade":"1",
	                         "coFlag":null,
	                         "khaiValue":"52",
	                         "so2Value":"0.003",
	                         "coValue":"0.5",
	                         "pm10Flag":null,
	                         "o3Grade":"1",
	                         "pm10Value":"15",
	                         "khaiGrade":"2",
	                         "sidoName":"서울",
	                         "no2Flag":null,
	                         "no2Grade":"2",
	                         "o3Flag":null,
	                         "so2Flag":null,
	                         "dataTime":"2023-08-23 14:00",
	                         "coGrade":"1",
	                         "no2Value":"0.032",
	                         "stationName":"정릉로",
	                         "pm10Grade":"1",
	                         "o3Value":"0.029"
	                      },
	                      {
	                         "so2Grade":"1",
	                         "coFlag":null,
	                         "khaiValue":"-",
	                         "so2Value":"0.002",
	                         "coValue":"0.5",
	                         "pm10Flag":null,
	                         "o3Grade":"2",
	                         "pm10Value":"3",
	                         "khaiGrade":null,
	                         "sidoName":"서울",
	                         "no2Flag":null,
	                         "no2Grade":"1",
	                         "o3Flag":null,
	                         "so2Flag":null,
	                         "dataTime":"2023-08-23 14:00",
	                         "coGrade":"1",
	                         "no2Value":"0.013",
	                         "stationName":"도봉구",
	                         "pm10Grade":"1",
	                         "o3Value":"0.039"
	                         }, ...
	                      ]
	               }
	            }
	      }
	      */
		
		// JSONObject, JsonArray 이용해서 파싱할 수 있음(gson 라이브러리)
		
		// json 데이터를 원하는 데이터만 추출하여 VO에 담기
		// 응답 데이터 text를 JsonObject화 시키는 작업(파싱)
		JsonObject totalObj = JsonParser.parseString(responseText).getAsJsonObject();
		
		// System.out.println("total : " + totalObj);
		
		// response 속성에 접근
		JsonObject responseObj = totalObj.getAsJsonObject("response");
		// System.out.println("responseObj : " + responseObj);
		
		// body 속성 접근
		JsonObject bodyObj = responseObj.getAsJsonObject("body");
		
		// System.out.println("bodyObj : " + bodyObj);
		
		// totalCount 속성 접근
		int totalCount = bodyObj.get("totalCount").getAsInt();
		// System.out.println("totalCount : " + totalCount);
		
		// items(JsonArray 형태) 속성 접근
		JsonArray itemArr = bodyObj.getAsJsonArray("items");
		// System.out.println("itemArr : " + itemArr);
		
		// items에 담겨있는 item 객체 하나씩 추출
		
		ArrayList<Air> list = new ArrayList<Air>();
		
					// length 아니고 size
		for(int i = 0; i<itemArr.size(); i++) {
			JsonObject item = itemArr.get(i).getAsJsonObject(); // 배열이 아니라 객체라서 get 사용 !! itemArr[i] 사용 불가
			// System.out.println(item);
			
			Air air = new Air();
			air.setStationName(item.get("stationName").getAsString());
			air.setDataTime(item.get("dataTime").getAsString());
			air.setKhaiValue(item.get("khaiValue").getAsString());
			air.setPm10Value(item.get("pm10Value").getAsString());
			air.setSo2Value(item.get("so2Value").getAsString());
			air.setCoValue(item.get("coValue").getAsString());
			air.setNo2Value(item.get("no2Value").getAsString());
			air.setO3Value(item.get("o3Value").getAsString());
			
			list.add(air);
			
		}
		
		// System.out.println("list : "+list);
		
		// list에 담긴 VO 객체 확인
		for(Air a : list) {
			System.out.println(a);
		}
		
		// 5. 다 사용한 스트림 객체 반납하기
		br.close();
		urlConn.disconnect();
	}

}

📍 비동기식으로 웹 애플리케이션에 적용하고자 할 때의 절차

  1. Jsp에서 현재 웹 애플리케이션 서버로 ajax 요청
  2. Controller에서 요청 받기 (이때 요청 시 전달값이 있다면 기록)
  3. HttpURLConnection 객체 활용해서 OpenAPI서버에 요청하여 응답데이터 받기
  4. 3번 과정에서의 응답데이터를 Client에게 다시 응답
  5. Client측에서 돌려받은 응답데이터를 가지고 파싱 작업 후 웹 페이지에 시각화 하기

🔑 JSON 형식

html + JS

<h1>실시간 대기오염 정보</h1>

	지역 :
	<select id="location">
		<option>서울</option>
		<option>부산</option>
		<option>대전</option>
	</select>

	<button id="btn1">해당 지역 대기 오염 정보</button>
	<br>
	<br>

	<table border="1" id="result1">
		<thead>
			<tr>
				<th>측정소명</th>
				<th>측정일시</th>
				<th>통합대기환경수치</th>
				<th>미세먼지농도</th>
				<th>아황산가스농도</th>
				<th>일산화탄소농도</th>
				<th>이산화탄소농도</th>
				<th>오존농도</th>
			</tr>
		</thead>
		<tbody></tbody>
	</table>

	<script>

      $(function(){
         $("#btn1").click(function(){
        	 /* JSON 형식으로 응답받을 떄
            $.ajax({
               url : "air",
               data : {location : $("#location").val()},
               success : function(data){
                  // console.log(data);
                  // console.log(data.response.body.items);

                  const itemArr = data.response.body.items;
                  
                  let value = "";
                  for(let item of itemArr){
                     console.log(item);
                     value += "<tr>"
                           + "<td>" + item.stationName + "</td>"
                           + "<td>" + item.dataTime + "</td>"
                           + "<td>" + item.khaiValue + "</td>"
                           + "<td>" + item.pm10Value + "</td>"
                           + "<td>" + item.so2Value + "</td>"
                           + "<td>" + item.coValue + "</td>"
                           + "<td>" + item.no2Value + "</td>"
                           + "<td>" + item.o3Value + "</td>"
                          +"</tr>"   
                  }

                  $("#result1 > tbody").html(value);


               }, error : function(){
                  console.log("통신실패");
               }
            })
            */
      

Controller

// @RequestMapping(value = "air", produces = "application/json; charset=UTF-8")
	@ResponseBody
	public String airMethod(String location) throws IOException {

		String url = "http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getCtprvnRltmMesureDnsty";

		url += "?serviceKey=" + SERVICEKEY; // 서비스키 추가
		url += "&sidoName=" + URLEncoder.encode( location , "UTF-8"); // 지역명 추가(한글이 들어가면 인코딩 처리해야 함)
		url += "&returnType=json"; // 리턴타입
		url += "&numOfRows=2";
		
		// 1. 작성된 url 정보를 넣어서 URL 객체 생성
		URL requestUrl = new URL(url);
		
		// 2. 생성된 URL 객체로 URLConnection 생성
		HttpURLConnection urlConn = (HttpURLConnection)requestUrl.openConnection();
		
		// 3. 요청 시 필요한 Header 생성
		urlConn.setRequestMethod("GET");
		
		// 4. 해당 OpenAPI 서버로 요청 후 입력스트림을 통해서 응답데이터 읽어오기
		BufferedReader br = new BufferedReader( new InputStreamReader( urlConn.getInputStream()));
		
		String line;
		String responseText="";
		while((line = br.readLine()) != null) {
			responseText += line;
		}
		
		// 5. 다 사용한 스트림 반납 및 연결 해제
		
		br.close();
		urlConn.disconnect();
		
		System.out.println(responseText);
		
		return responseText;
	}
    

🔑 XML 형식

html + JS

$.ajax({
            	url : "air",
            	data : {location : $("#location").val()},
				success : function(result){

					console.log(result);

					// $("요소명").find(매개변수)
					// - 기준이 되는 요소의 하위 요소들 중 특정 요소를 찾을 때 사용
					// - html, xml은 같은 markup language이기 때문에 사용 가능하다
					// console.log($(result).find("item"));

					// xml 형식의 응답데이터를 받았을 때
					// 1. 넘겨받은 데이터를 $() 제이쿼리화 시킨 후
					//	  응답데이터 안에 실제 데이터가 담겨있는 요소 선택
					const itemArr = $(result).find("item");

					// 2. 반복문을 통해 실제 데이터가 담긴 요소들에 접근해서 동적으로 요소 만들기
					let value;
					itemArr.each(function(index, item){
						// console.log(item);
						console.log($(item).find("o3Value").text());

						
						console.log(item);
						value += "<tr>"
							+ "<td>" + $(item).find("stationName").text() + "</td>"
							+ "<td>" + $(item).find("dataTime").text() + "</td>"
							+ "<td>" + $(item).find("khaiValue").text() + "</td>"
							+ "<td>" + $(item).find("pm10Value").text() + "</td>"
							+ "<td>" + $(item).find("so2Value").text() + "</td>"
							+ "<td>" + $(item).find("coValue").text() + "</td>"
							+ "<td>" + $(item).find("no2Value").text() + "</td>"
							+ "<td>" + $(item).find("o3Value").text() + "</td>"
							+"</tr>"   
					
					});

					// 3. 동적으로 만들어낸 요소를 화면에 출력
                	$("#result1 > tbody").html(value);

					

				}, 
				error : function(){console.log("통신 실패")}
            })
            
         })
      })

Controller

@GetMapping(value="air", produces = "text/xml; charset=UTF-8")
	@ResponseBody
	public String airPollution(String location) throws IOException {
		
		// 필요한 url 가져오기
		String url = "http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getCtprvnRltmMesureDnsty";

		url += "?serviceKey=" + SERVICEKEY; 
		url += "&sidoName=" + URLEncoder.encode( location , "UTF-8"); 
		url += "&returnType=xml"; 
		url += "&numOfRows=5";
		
		// URL 객체 생성
		URL requestUrl = new URL(url);
		
		// URL Connection 생성
		HttpURLConnection urlConn = (HttpURLConnection)requestUrl.openConnection();
		
		// Header 생성
		urlConn.setRequestMethod("GET");
		
		// 스트림 생성
		BufferedReader br = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
		
		// 데이터 읽어서 저장
		String responseText = "";
		String line;
		
		while((line=br.readLine()) != null) {
			responseText += line;
		}
		
		// 자원 반납
		br.close();
		urlConn.disconnect();
		
		System.out.println(responseText);
		
		return responseText;
	}
	

html + JS

<h1>실시간 지진해일 긴급 대피장소</h1>
   
   <button id="btn2">실시간 지진해일 긴급 대피장소 정보</button>
   <br><br>
   
   <table border="1" id="result2">
      <thead>
         <tr>
            <th>시도명</th>
            <th>시군구명</th>
            <th>대피지구명</th>
            <th>대피장소명</th>
            <th>주소</th>
            <th>경도</th>
            <th>위도</th>
            <th>수용가능인원수</th>
            <th>대피소 분류명</th>
         </tr>
      </thead>
      <tbody></tbody>
   </table>

   <script>
   
	$(function(){

		$("#btn2").click(function(){

			$.ajax({
	
				url : "shelter",
				success : function(data){
					console.log(data);

					const list = $(data).find("row");

					// console.log(list)

					let value;

					list.each(function(index, item){


						
						value += "<tr>"
							+ "<td>" + $(item).find("sido_name").text() + "</td>"
							+ "<td>" + $(item).find("sigungu_name").text() + "</td>"
							+ "<td>" + $(item).find("remarks").text() + "</td>"
							+ "<td>" + $(item).find("shel_nm").text() + "</td>"
							+ "<td>" + $(item).find("address").text() + "</td>"
							+ "<td>" + $(item).find("lon").text() + "</td>"
							+ "<td>" + $(item).find("lat").text() + "</td>"
							+ "<td>" + $(item).find("shel_av").text() + "</td>"
							+ "<td>" + $(item).find("shel_div_type").text() + "</td>"
							+"</tr>"   
						
					})

					$("#result2 > tbody").html(value);



				},
				error : function(){
					console.log("통신 장애")
				}
	
	
			})
		})



	})
   
   
   
   </script>

Controller

// xml형식으로 지진해일 대피소 OpenAPI 활용하기
	@GetMapping(value="shelter", produces = "text/xml; charset=UTF-8")
	@ResponseBody
	public String shelterList() throws IOException {
		
		String url = "https://apis.data.go.kr/1741000/TsunamiShelter3/getTsunamiShelter1List";
		
		url += "?ServiceKey=" + SERVICEKEY;
		url += "&pageNo=2";
		url += "&numOfRows=100";
		url += "&type=xml";
		
		URL requestUrl = new URL(url);
		
		HttpURLConnection urlConn = (HttpURLConnection)requestUrl.openConnection();
		
		urlConn.setRequestMethod("GET");
		
		BufferedReader br = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
		
		String responseText = "";
		String line;
		
		while((line=br.readLine()) != null) {
			responseText += line;
		}
		
		br.close();
		urlConn.disconnect();
		
		System.out.println(responseText);
		
		
		return responseText;
	}
    
profile
개발 일지

0개의 댓글