📗 self-study/📗 KH정보교육원 당산지원

[OpenAPI] 가지고 온 공공 데이터를 화면에 뿌려 주기

천재강쥐 2022. 11. 30. 14:38

 

 

 

RestAPI

 

 

 

⌨️ index.jsp 생성 및 기본 틀 만들기

👉🏻 taglib 지시어는 사용하지 않을 것이므로 삭제해 줌

👉🏻 jQuery방식으로 ajax 요청을 보내기 위해 jQuery 라이브러리 추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- jQuery 라이브러리 -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>

</body>
</html>

 

 

 

📍 OpenData_Project 서버에 올리기

👉🏻 많은 프로젝트가 서버에 올라갈수록 구동 속도가 느려지기 때문에 필요없는 Ajax_Project는 내려 줌

 

 

 

⌨️ APIController 클래스 생성

👉🏻 controller 패키지를 경로에 추가 후 생성할 것

package com.kh.opendata.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class APIController {
	
	@RequestMapping("air.do")
	public void airPollution(String location) throws IOException { // 부모 타입인 IOException으로 바꿔 줬음
		
		System.out.println(location);
		
	}

}

 

 

 

📍 No mapping found for HTTP request with URI 오류

opendata/air.do를 못 찾는다고 콘솔에 떠서 고생했는데

@Controller 어노테이션을 안 붙여 줘서였음 ^^...

 

 

 

📌 현재 상황

👉🏻 서버 리스타트 후 select 태그의 지역 선택

 

👉🏻 해당 지역 대기오염정보 보기 버튼을 클릭하면 콘솔에 지역명이 잘 넘어옴

 

 

 

💻 APIController

package com.kh.opendata.controller;

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 org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class APIController {
	
	public static final String SERVICEKEY = "알려줄수없는나만의인증키입니다";
	
	@ResponseBody
	@RequestMapping(value="air.do", produces="application/json; charset=UTF-8")
	public String airPollution(String location) throws IOException { // 부모 타입인 IOException으로 바꿔 줬음
		
		// System.out.println(location);

		 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=50"; // 결과의 개수
		 		
		 URL requestUrl = new URL(url); // java.net.URL로 import
		 
		 HttpURLConnection urlConnection = (HttpURLConnection)requestUrl.openConnection();
		 
		 urlConnection.setRequestMethod("GET");
		 
		 BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
		 
		 String responseText = "";
		 String line; // null
		 
		 while((line = br.readLine()) != null) {
			 
			 responseText += line;
			 
		 }

		 // 응답 데이터를 보내 주고자 한다면 굳이 ArrayList로 파싱할 필요가 없음!
		 // String을 리턴하되, @ResponseBody 추가, produces 설정 추가!
		 
		 br.close();
		 urlConnection.disconnect();
		 
		 return responseText;
		
	}

}

 

⌨️ 넘어온 값을 확인하기 위해 콘솔에 찍어 본 index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- jQuery 라이브러리 -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>

	<h2>실시간 대기 오염 정보</h2>
	
	지역: 
	<select id="location">
		<option>서울</option>
		<option>부산</option>
		<option>대전</option>
		<option>제주</option>
	</select>
	
	<button id="btn1">해당 지역 대기오염정보 보기</button>
	
	<br><br>
	
	<table id="result1" border="1" align="center">
		<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() {
				
				$.ajax({
					url : "air.do",
					data : {location:$("#location").val()},
					success : function(data) {
						
						console.log(data);
						console.log(data.response);
						console.log(data.response.body);
						console.log(data.response.body.items);
						
					},
					error : function() {
						console.log("ajax로 대기 오염 정보 불러오기 실패!");
					}
					
				});
				
			});
			
		});
	</script>

</body>
</html>

 

 

 

📌 현재 상황

👉🏻 console.log(data)만 찍었을 때

 

👉🏻 data, data.response, data.response.body, data.response.body.items를 모두 찍었을 때

 

 

 

💻 응답 데이터를 json 형식으로 돌려받았을 경우 index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- jQuery 라이브러리 -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>

	<h2>실시간 대기 오염 정보</h2>
	
	지역: 
	<select id="location">
		<option>서울</option>
		<option>부산</option>
		<option>대전</option>
		<option>제주</option>
	</select>
	
	<button id="btn1">해당 지역 대기오염정보 보기</button>
	
	<br><br>
	
	<table id="result1" border="1" align="center">
		<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() {
				
				$.ajax({
					url : "air.do",
					data : {location:$("#location").val()},
					success : function(data) {
						
						// console.log(data);
						// console.log(data.response);
						// console.log(data.response.body);
						// console.log(data.response.body.items);
						
						var itemArr = data.response.body.items;
						
						var value = "";
						for(var i = 0; i < itemArr.length; i++) {
							// console.log(itemArr);
							
							var item = itemArr[i]; //{stationName:"~~", dataTime:"~~", ...}
							
							value += "<tr>"
										+ "<td>" + item.stationName + "</td>"
										+ "<td>" + item.dataTime + "</td>"
										+ "<td>" + item.khaiValue + "</td>"
										+ "<td>" + item.pm10Value + "</td>"
										+ "<td>" + item.coValue + "</td>"
										+ "<td>" + item.no2Value + "</td>"
										+ "<td>" + item.so2Value + "</td>"
										+ "<td>" + item.o3Value + "</td>"
								+ "</tr>";
						}
						
						$("#result1>tbody").html(value);
						
					},
					error : function() {
						console.log("ajax로 대기 오염 정보 불러오기 실패!");
					}
					
				});
				
			});
			
		});
	</script>

</body>
</html>

 

👉🏻 이제 버튼을 누르면 테이블이 나옴! 지역을 바꿔도 잘 나옴!

 

 

 


🔦 BUILD UP 

응답 데이터를 XML 형식으로 돌려받았을 때는 어떻게 처리할 수 있을까?


 

⌨️ 응답 데이터를 xml형식으로 돌려받았을 경우 index.jsp (콘솔에 어떻게 찍히나 확인 ver)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- jQuery 라이브러리 -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>

	<h2>실시간 대기 오염 정보</h2>
	
	지역: 
	<select id="location">
		<option>서울</option>
		<option>부산</option>
		<option>대전</option>
		<option>제주</option>
	</select>
	
	<button id="btn1">해당 지역 대기오염정보 보기</button>
	
	<br><br>
	
	<table id="result1" border="1" align="center">
		<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() {
				
				// 응답 데이터를 xml 형식으로 돌려받았을 경우
				$.ajax({
					url : "air.do",
					data : {location:$("#location").val()},
					success : function(data) {
						
						console.log(data);
						
					},
					error : function() {
						console.log("ajax로 대기오염 정보 불러오기 실패!");
					}
					
				});

			});
			
		});
	</script>

</body>
</html>

 

💻 APIController

👉🏻 @RequestMapping의 produces를 html/xml; 로 바꿔 줌

👉🏻 returnType 부분 json에서 xml로 바꿔 줌

@ResponseBody
// @RequestMapping(value="air.do", produces="application/json; charset=UTF-8") // json으로 응답데이터를 넘기고 싶음
@RequestMapping(value="air.do", produces="text/xml; charset=UTF-8") // xml로 응답데이터를 넘기고 싶을 때
	public String airPollution(String location) throws IOException { // 부모 타입인 IOException으로 바꿔 줬음

		 String url = "http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getCtprvnRltmMesureDnsty";
		 		url += "?serviceKey=" + SERVICEKEY;
		 		url += "&sidoName=" + URLEncoder.encode(location, "UTF-8");
		 		// url += "&returnType=json"; // json으로 요청 결과를 받고 싶을 때
		 		url += "&returnType=xml"; 
		 		url += "&numOfRows=50"; // 결과의 개수

 

 

 

📌 현재 상황

👉🏻 console.log(data)를 찍었을 때 공공 데이터 포털에서 본 것과 똑같이 콘솔에 찍힘!

 

 

 

⌨️ 응답 데이터를 xml형식으로 돌려받았을 경우 index.jsp

xml도 마찬가지로 html처럼 markup language임
👉🏻 xml = 확장된 markup language
👉🏻 태그로 구성되어 있기 때문에 jQuery 시간에 배웠던 탐색 메소드를 그대로 적용 가능함

👉🏻 jQuery에서의 find() 메소드 사용해 보기
👉🏻 기준이 되는 요소의 하위 요소들 중 특정 요소를 찾을 때 사용

	<script>
		$(function() {
			
			$("#btn1").click(function() {
				
				// 응답 데이터를 xml 형식으로 돌려받았을 경우
				$.ajax({
					url : "air.do",
					data : {location:$("#location").val()},
					success : function(data) {

						console.log(data.find("item"));
						
					},
					error : function() {
						console.log("ajax로 대기오염 정보 불러오기 실패!");
					}
					
				});

			});
			
		});
	</script>

 

👉🏻 없는 함수를 호출할 때 발생하는 오류임

데이터가 자바스크립트 타입인데 제이쿼리 메소드를 붙여서 그렇다!

 

⌨️ 콘솔에 찍을 내용을 제이쿼리 형식에 맞춰서 $(달러사인) 주기

console.log($(data).find("item"));

 

⌨️ item 중에서도 stationName에 해당하는 내용을 알고 싶음

👉🏻 <stationName>중구</stationName> 요소 자체가 찍힘

console.log($(item).find("stationName"));

 

 

⌨️ item 중에서도 stationName에 해당하는 내용 찍기

👉🏻 내가 원하는 대로 지역명만 찍힘!

console.log($(item).find("stationName").text());

 

💻 응답데이터를 xml파일로 돌려받은 index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- jQuery 라이브러리 -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>

	<h2>실시간 대기 오염 정보</h2>
	
	지역: 
	<select id="location">
		<option>서울</option>
		<option>부산</option>
		<option>대전</option>
		<option>제주</option>
	</select>
	
	<button id="btn1">해당 지역 대기오염정보 보기</button>
	
	<br><br>
	
	<table id="result1" border="1" align="center">
		<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() {
				
				// 응답 데이터를 xml 형식으로 돌려받았을 경우
				$.ajax({
					url : "air.do",
					data : {location:$("#location").val()},
					success : function(data) {
						
						// xml 형식의 응답 데이터를 받았을 때
						// 1. 응답 데이터 내부에 실제 데이터가 담겨 있는 요소 (item)를 선택해서 변수에 담기
						var itemArr = $(data).find("item"); // [item, item, item, ...]
						
						// 2. 반복문을 이용해서 실제 데이터가 담긴 요소들에 접근해 동적으로 요소 만들기
						var value = "";
						itemArr.each(function(index, item) {
							// console.log(item);
							// console.log($(item).find("stationName"));
							// <stationName>중구</stationName> 요소 자체에서 값만 뽑아야 함 == innerHTML
							// onsole.log($(item).find("stationName").text());
							
							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("coValue").text() + "</td>"
								 		+ "<td>" + $(item).find("no2Value").text() + "</td>"
								 		+ "<td>" + $(item).find("so2Value").text() + "</td>"
								 		+ "<td>" + $(item).find("o3Value").text() + "</td>"
								  + "</tr>";
						});
						
						// 3. 동적으로 만들어낸 요소를 화면에 출력
						$("#result1>tbody").html(value);
						
					},
					error : function() {
						console.log("ajax로 대기오염 정보 불러오기 실패!");
					}
					
				});

			});
			
		});
	</script>

</body>
</html>

 

👉🏻 json과 같은 결과! 버튼을 누르면 테이블이 나오고 지역을 바꿔도 잘 나옴!