본문 바로가기

개발 지식/API

API :: 공공 API 사용하기 (기상청)

 

 

CORS
Cross Origin Resource Sharing
공공 API는 Ajax를 실행하여 직접 데이터를 호출하게 된다면 CORS 문제가 발생한다.


CORS는 한 도메인 또는 Origin의 웹 페이지가 다른 도메인 (도메인 간 요청)을 가진 리소스에 액세스 할 수 있게하는 보안 메커니즘이다. CORS는 서버와 클라이언트가 정해진 헤더를 통해 서로 요청이나 응답에 반응할지 결정하는 방식으로 CORS라는 이름으로 표준화 되었다. CORS는 최신 브라우저에서 구현된 동일 출처 정책(same-origin policy) 때문에 등장했다. 동일 출처 정책은 동일한 출처의 리소스에만 접근하도록 제한하는 것이다. 여기서 출처는 프로토콜, 호스트명, 포트가 같다는 것을 의미한다.

 

이러한 오류가 생기는 것을 방지하기 위해 1. jsoup( 자바(Java)로 만들어진 HTML 파서(Parser) )을 이용하여 자바스크립트 파일을 가져와서 이를 json 형식으로 파싱해서 데이터를 사용하거나 2. 서버에서 CorsFilter를 통해서 처리하는 방, 3. @CrossOrigin 어노테이션을 사용하는 방법 등을 선택할 수 있다.

 

 

기상청 동네날씨 API 사용하기

 

1. 가져오고자 하는 지역의 RSS를 3시간, 1시간 중 하나 택하여 가져온다.

제주 서귀포 남원읍 3시간 RSS : http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=5013025300

 

 

2. 이러한 XML 파일 또한 확인할 수 있다

 

3. 날씨를 찍어줄 HTML 작성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>날씨 예보 확인</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script type="text/javascript" src="js/wather.js"></script>
<style type="text/css">
table {
	border: 1px solid #ccc;
	border-collapse: collapse;
}

tr, tr {
	border: 1px solid #ccc;
}

.hd {
	background-color: skyblue;
	text-align: center;
}

img {
	text-align: center;
}
</style>
</head>
<body>
	<h3>기상청에서 제공하는 날씨 RSS</h3>
	<table>
		<tr class="hd">
			<th colspan="3">지역</th>
		</tr>
		<tr>
			<td>주소선택</td>
			<td><select id="address">
					<option value="1154551000" selected="selected">서울 금천구</option>
					<option value="5013025300">제주도 남원읍</option>
			</select></td>
			<td>
				<button id="weatherView">날씨보기</button>
			</td>
		</tr>
		<tr class="hd">
			<th>현재날씨</th>
		</tr>
		<tr>
			<td>기준시간</td>
			<td><input type="text" id="pubDate" readonly="readonly">
			</td>
			<td rowspan="5"><img id="weatherImg" alt="날씨이미지"
				src="img/Clear.png"></td>
		</tr>
		<tr>
			<td>날씨</td>
			<td><input type="text" id="wfKor" readonly="readonly"></td>
		</tr>
		<tr>
			<td>온도</td>
			<td><input type="text" id="temp" readonly="readonly"></td>
		</tr>
		<tr>
			<td>습도</td>
			<td><input type="text" id="reh" readonly="readonly"></td>
		</tr>
		<tr>
			<td>강수확률</td>
			<td><input type="text" id="pop" readonly="readonly"></td>
		</tr>
	</table>
</body>
</html>

 

 

4. HTML과 연결된 자바스크립트. XML으로부터 받아온 값을 다시 화면으로 출력하는 기능을 담당한다.

$("#weatherView").click(function() {
		var code = $("#address option:selected").val();
		console.log("선택된 지역코드 : ", code);

		$.ajax({
			url: "./weatherOpen.do",
			type: "get",
			data : {zone:code},
			dataType : "text",
			success : function(data){
				let obj = JSON.parse(data);
				//console.log(typeof data, data, data.pubDate);
				//console.log(typeof obj);
				//console.log(data);
				$("#pop").val(obj.pop);
				$("#pubDate").val(obj.pubDate);
				$("#reh").val(obj.reh);
				$("#wfKor").val(obj.wfKor);
				$("#temp").val(obj.temp);
				
				var weather_icon = obj.wfKor;
				switch(weather_icon){
					case "맑음" : $("#weatherImg").attr("src", "img/Clear.png"); break;
					case "구름 조금" : $("#weatherImg").attr("src", "img/Partly_Cloudy.png"); break;
					case "구름 많음" : $("#weatherImg").attr("src", "img/Mostly_Cloudy.png"); break;
					case "흐림" : $("#weatherImg").attr("src", "img/Cloudy.png"); break;
					case "비" : $("#weatherImg").attr("src", "img/Rain.png"); break;
					case "눈/비" : $("#weatherImg").attr("src", "img/Snow_Rain.png"); break;
					case "눈" : $("#weatherImg").attr("src", "img/Snow.png"); break;
				}
			},
			error:function(){
				alert("잘못된 요청 처리");	
			}
		});

	});

 

 

5. 서블릿으로 만든 서버쪽 GET 메서드

package com.min.edu.ctrl;

import java.io.IOException;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class WeatherCtrl extends HttpServlet {

	private static final long serialVersionUID = -5982128587639515540L;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String zone = req.getParameter("zone");
		System.out.println("전달받은 요청값 : "+zone);
			
		req.setAttribute("zone", zone);
		req.getRequestDispatcher("/weatherjson.jsp").forward(req, resp);
		
	}
}

 

 

6. GET 메서드에서 requestDispatcher로 보낸 JSP 영역. 이곳에서 XML의 어느 값을 받아올지 받아올 값의 위치를 지정해준다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml"%>
<c:catch var="err">
<c:set var="weatherURL" value="http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=${zone}"/>
<c:import var="wrd" url="${weatherURL}"/>
<x:parse var="w" xml="${wrd}"/>
{"pubDate":"<x:out select="$w/rss/channel/pubDate"/>",
"wfKor":"<x:out select="$w/rss/channel/item/description/body/data/wfKor"/>",
"temp":"<x:out select="$w/rss/channel/item/description/body/data/temp"/>",
"reh":"<x:out select="$w/rss/channel/item/description/body/data/reh"/>",
"pop":"<x:out select="$w/rss/channel/item/description/body/data/pop"/>"}
</c:catch>
<c:if test="err != null">
	{"msg":${err}}
</c:if>

 

 

7. 실행 화면 

 

처음 시작의 빈 화면

 

날씨보기를 누르면 해당 주소의 날씨를 가져온다
지역을 선택하면 해당 지역의 날씨 정보를 실시간으로 받아온다

'개발 지식 > API' 카테고리의 다른 글

API :: CLOVA Summary (AI 요약 Service)  (0) 2024.08.27
API :: Geolocation API (구글 맵 API)  (0) 2024.07.09
API :: PDF api 사용하기  (0) 2024.07.07
API :: 카카오톡 로그인 API  (0) 2024.07.05