Step-by-Step

[Spring] 8. 날씨 API 받아오기 본문

프로젝트/Eggo (Mobile App)

[Spring] 8. 날씨 API 받아오기

희주(KHJ) 2022. 5. 19. 17:58

해당 위치(nx, ny)와 날짜(base_date), 시간(base_time)을 통해 단기 예보를 가져와 DB에 저장하는 코드를 작성했다

 

 

우선 공공데이터 포털에서 활용 신청을 하고 key를 받아와야 한다

https://www.data.go.kr/data/15084084/openapi.do

 

기상청_단기예보 ((구)_동네예보) 조회서비스

초단기실황, 초단기예보, 단기((구)동네)예보, 예보버전 정보를 조회하는 서비스입니다. 초단기실황정보는 예보 구역에 대한 대표 AWS 관측값을, 초단기예보는 예보시점부터 6시간까지의 예보를,

www.data.go.kr

 

그리고 사이트에 주어진 활용가이드 zip 파일을 열어보면

이런식으로 지역마다 가지고 있는 격자 좌표(nx,ny)가 있고, API를 어떻게 활용해야 하는지 알려준다.

 

내가 사용할 부분은 단기예보 이며, 해당 부분을 보면

이런식으로 나와있구 항목구분이 1인 부분을 채워서 url로 보내주면 된다

 

serviceKey 부분에는 받은 인증키값을 넣어주면 되고, 나머지는 자기가 필요한 정보를 넣어주면 된다.

 

 

★ 나는 추가로 dataType을 JSON으로 지정하여 받았다

이런식으로 응답이오고 category에 따라서 원하는 값을 추출해내면 된다.

응답이 정상적으로 오는 것을 확인했으니, 이제 Spring에 반영하면 된다!

 

 

쿼리 생성

	// 쿼리 생성
	public String getQuery(String[] times) {
		StringBuilder query = new StringBuilder();
		query.append("?");
		query.append("serviceKey=").append(serviceKey);
		String nx = "56"; //경도
		String ny = "71"; //위도
		query.append("&nx=").append(nx).append("&ny=").append(ny);
		
		String numOfRows = "10";
		String pageNo = "1";
		query.append("&numOfRows=").append(numOfRows).append("&pageNo=").append(pageNo);
		
		String base_date = times[0]; // 자신이 조회하고싶은 날짜를 입력해주세요 
		String base_time = times[1]; //자신이 조회하고싶은 시간대를 입력해주세요 
		query.append("&base_date=").append(base_date).append("&base_time=").append(base_time);
		
		String type = "JSON";
		query.append("&dataType=").append(type);
		return query.toString();
	}

URL과 serviceKey값은 전역 필드로 선언하였고, StringBuilder를 이용하여 쿼리를 완성하였다.

 

 

요청 보내기

// 날씨 정보 받아오기
	public String getWeatherConn(String urlStr) {
		String result = null;
		try {
			URL url = new URL(urlStr);
			HttpURLConnection conn =(HttpURLConnection)url.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(10000);
			
			int res = conn.getResponseCode();
			System.out.println(urlStr);
			System.out.println("res====>"+res);
			
			BufferedReader rd;
			if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
				rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			} else {
				rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
			}
			
			StringBuilder sb = new StringBuilder();
			String line;
			while ((line = rd.readLine()) != null) {
				sb.append(line);
			}
			rd.close();
			conn.disconnect();
			result = sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}  
		return result;
	}

HttpUrlConnection을 이용하여 url에 쿼리를 더한 주소값을 GET 방식으로 전송한 후 result에 담아 리턴하였다.

 

 

원하는 값 추출

// Json에서 정보 추출
	public HashMap<String, Object> getWeatherData(String result){
		JSONParser jsonParser = new JSONParser();
		HashMap<String, Object> weatherMap = new HashMap<>();
		try {
			JSONObject jsonObj = (JSONObject) jsonParser.parse(result);
			JSONObject parse_response = (JSONObject) jsonObj.get("response");
			JSONObject parse_body = (JSONObject) parse_response.get("body");// response 로 부터 body 찾아오기
			JSONObject parse_items = (JSONObject) parse_body.get("items");// body 로 부터 items 받아오기
			JSONArray parse_item = (JSONArray) parse_items.get("item");
			Long totalCount = (Long) parse_body.get("totalCount");
			String baseDate = (String) ((JSONObject) parse_item.get(0)).get("baseDate");
			String baseTime = (String) ((JSONObject) parse_item.get(0)).get("baseTime");
			//System.out.println(totalCount);
			WeatherDTO weatherDTO = new WeatherDTO();
			for(int i=0; i<totalCount; i++) {
				JSONObject obj = (JSONObject)parse_item.get(i);
				String category = (String) obj.get("category");
				
				/*
				1시간 기온 TMP ℃
				1시간 강수량 PCP 범주 (1 mm)
				습도 REH %		
				풍속 WSD m/s
				*/
				switch(category) {
					case "T1H":{
						weatherDTO.setT1H((String)obj.get("obsrValue"));
						break;
					}
					case "RN1":{
						weatherDTO.setRN1((String)obj.get("obsrValue"));
						break;
					}
					case "REH":{
						weatherDTO.setREH((String)obj.get("obsrValue"));
						break;
					}
					case "WSD":{
						weatherDTO.setWSD((String)obj.get("obsrValue"));
						break;
					}
				}	
			}
			
			weatherMap.put("date", baseDate);
			weatherMap.put("time", baseTime);
			weatherMap.put("T1H", weatherDTO.getT1H());
			weatherMap.put("RN1", weatherDTO.getRN1());
			weatherMap.put("REH", weatherDTO.getREH());
			weatherMap.put("WSD", weatherDTO.getWSD());
			//ObjectMapper objectMapper = new ObjectMapper();
			//weatherMap.putAll((java.util.Map<? extends String, ? extends Object>) objectMapper.convertValue(weatherDTO, Map.class));
		}catch(Exception e) {
			e.printStackTrace();
		}
		
		return weatherMap;
	}

category를 먼저 확인한 후 필요한 부분이면 obsrValue값을 빼내어 저장하였다.

 

 

공공데이터포털에서 API 사용하는 게 처음이었는데, 생각보다 어렵지 않았던 것 같다

다음에는 HttpURLConnection 내용을 담아야겠다!

 

 

Comments