목차
build.gradle 파일에 gson 라이브러리 추가
날씨 정보 api에서 전달받은 json 파일을 파싱 하기 위한 gson 라이브러리 추가하기
- https://mvnrepository.com/ 접속
- gson 검색
- 사용할 버전 선택
- 사용할 방식 선택하여 추가하기 (Maven, Gradle, jar파일 다운로드 등...)
dependencies {
// https://mvnrepository.com/artifact/com.google.code.gson/gson
implementation 'com.google.code.gson:gson:2.10.1'
}
프로젝트 구조 만들기
- 위도/경도 DTO(Locale), 날씨정보 DTO(Weather)
- 위도/경도 Service(LocaleService), 날씨정보 Service(WeatherService)
- 전체(날씨정보) 컨트롤러
- 사용자 화면(ConsoleView)
api 키 발급
- https://openweathermap.org/ 가입하기
- 사용자 메뉴에서 키 발급받기
위도/경도 받아오기
API call 예시
http://api.openweathermap.org/geo/1.0/direct?q={city name},{state code},{country code}&limit={limit}&appid={API key}
Parameters
- q (필수값) : 도시이름, 주 코드(미국만 해당) 및 국가 코드를 쉼표로 구분하여 작성
- appid (필수값) : 발급받은 API 키
- limit (옵션값) : API 응답의 수 (최대 5개)
// 항상 최대값으로 5개를 가져오도록 전달, country는 메서드를 호출하는 쪽에서 주입(사용자가 입력)
String address = "http://api.openweathermap.org/geo/1.0/direct?q=" + country + "&limit=5&appid=" + Api.key();
Http 통신
URL url = new URL(address);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/json");
responseCode = connection.getResponseCode();
if (responseCode == 200) {
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
// TODO json parsing
} else {
throw new RuntimeException("Http Error");
}
응답값 파싱 후 DTO 담기
JsonArray localeArray = JsonParser.parseString(sb.toString()).getAsJsonArray();
for (JsonElement element : localeArray) {
JsonObject object = element.getAsJsonObject();
if (object.getAsJsonObject().has("country")) {
String ct = object.getAsJsonObject().get("country").getAsString();
if (ct.equals("KR")) {
locale.setLat(object.getAsJsonObject().get("lat").getAsDouble());
locale.setLon(object.getAsJsonObject().get("lon").getAsDouble());
locale.setSucceed(true);
locale.setName(country);
break;
}
}
}
// 필요한 값만 변수로 선언한 LocaleDTO
public class Locale {
private boolean isSucceed = false; // http 응답 결과
private String name; // 도시이름
private Double lat; // 위도
private Double lon; // 경도
public Locale() {
}
public Locale(boolean isSucceed, String name, Double lat, Double lon) {
this.isSucceed = isSucceed;
this.name = name;
this.lat = lat;
this.lon = lon;
}
public boolean isSucceed() {
return isSucceed;
}
public void setSucceed(boolean succeed) {
isSucceed = succeed;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getLat() {
return lat;
}
public void setLat(Double lat) {
this.lat = lat;
}
public Double getLon() {
return lon;
}
public void setLon(Double lon) {
this.lon = lon;
}
@Override
public String toString() {
return "Locale{" +
"isSucceed=" + isSucceed +
", name='" + name + '\'' +
", lat=" + lat +
", lon=" + lon +
'}';
}
}
위도/경도를 이용하여 날씨 정보 받아오기
API call 예시
https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}
Parameters
- lat (필수값) : 위도
- lon (필수값) : 경도
- appid (필수값) : 발급받은 API 키
- lang (선택값) : 국가별 언어 지원
String address = "https://api.openweathermap.org/data/2.5/weather?lat="
+ locale.getLat() + "&lon=" + locale.getLon()
+ "&appid=" + Api.key() + "&lang=kr";
Http 통신
try {
URL url = new URL(address);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/json");
responseCode = connection.getResponseCode();
if (responseCode == 200) {
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
// json parsing
} else {
throw new RuntimeException("Http Error");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
응답값 파싱 후 DTO 담기
JsonObject weatherData = JsonParser.parseString(sb.toString()).getAsJsonObject();
JsonArray weatherArray = weatherData.getAsJsonArray("weather");
String description = weatherArray.get(0).getAsJsonObject().get("description").getAsString();
double temp = convertKelvinToCelsius(weatherData.getAsJsonObject("main").get("temp").getAsDouble());
double tempMin = convertKelvinToCelsius(weatherData.getAsJsonObject("main").get("temp_min").getAsDouble());
double tempMax = convertKelvinToCelsius(weatherData.getAsJsonObject("main").get("temp_max").getAsDouble());
int humidity = weatherData.getAsJsonObject("main").get("humidity").getAsInt();
String sunrise = convertEpochToTimestamp(weatherData.getAsJsonObject("sys").get("sunrise").getAsLong());
String sunset = convertEpochToTimestamp(weatherData.getAsJsonObject("sys").get("sunset").getAsLong());
weather.setDescription(description);
weather.setTemp(temp);
weather.setTempMin(tempMin);
weather.setTempMax(tempMax);
weather.setHumidity(humidity);
weather.setSunrise(sunrise);
weather.setSunset(sunset);
// 필요한 값만 변수로 선언한 WeatherDTO
public class Weather {
private int resultCode;
private String description;
private Double temp;
private Double tempMin;
private Double tempMax;
private Integer humidity;
private String sunrise;
private String sunset;
public Weather() {
}
public Weather(int resultCode, String description, Double temp, Double tempMin, Double tempMax, Integer humidity, String sunrise, String sunset) {
this.resultCode = resultCode;
this.description = description;
this.temp = temp;
this.tempMin = tempMin;
this.tempMax = tempMax;
this.humidity = humidity;
this.sunrise = sunrise;
this.sunset = sunset;
}
public int getResultCode() {
return resultCode;
}
public void setResultCode(int resultCode) {
this.resultCode = resultCode;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getTemp() {
return temp;
}
public void setTemp(Double temp) {
this.temp = temp;
}
public Double getTempMin() {
return tempMin;
}
public void setTempMin(Double tempMin) {
this.tempMin = tempMin;
}
public Double getTempMax() {
return tempMax;
}
public void setTempMax(Double tempMax) {
this.tempMax = tempMax;
}
public Integer getHumidity() {
return humidity;
}
public void setHumidity(Integer humidity) {
this.humidity = humidity;
}
public String getSunrise() {
return sunrise;
}
public void setSunrise(String sunrise) {
this.sunrise = sunrise;
}
public String getSunset() {
return sunset;
}
public void setSunset(String sunset) {
this.sunset = sunset;
}
@Override
public String toString() {
return "Weather{" +
"resultCode=" + resultCode +
", description='" + description + '\'' +
", temp=" + temp +
", tempMin=" + tempMin +
", tempMax=" + tempMax +
", humidity=" + humidity +
", sunrise='" + sunrise + '\'' +
", sunset='" + sunset + '\'' +
'}';
}
}
json 구조에 따라 jsonObject에서 키 값으로 바로 파싱해오거나, 배열에 먼저 접근하여 하위 jsonObject에서 파싱
애플리케이션 시작하여 확인하기
public class WeatherController {
private final ConsoleView consoleView;
private final LocaleService localeService;
private final WeatherService weatherService;
public WeatherController() {
consoleView = new ConsoleView();
localeService = new LocaleService();
weatherService = new WeatherService();
}
public void applicationStart() {
while (true) {
String country = consoleView.getCountry();
if (country.equalsIgnoreCase("q")) {
break;
} else {
Locale locale = localeService.locale(country);
Weather weather = weatherService.weather(locale);
consoleView.printWeather(weather);
}
}
}
}
WeatherController에서 위도/경도를 가져오는 Service, 날씨정보를 가져오는 Service 사용
사용자가 q를 입력하면 애플리케이션 중지, 도시 또는 지역을 입력하면 정보 출력
출력 결과
> Task :WeatherApplication.main()
지역을 입력해주세요(시 또는 구 또는 동) : 서초동
==============================
날씨 : 온흐림
평균기온 : -5
최저기온 : -5
최고기온 : -5
습도 : 44
일출시각 : 2023/12/20 07:41:56
일몰시각 : 2023/12/20 17:16:21
==============================
지역을 입력해주세요(시 또는 구 또는 동) : 용산
==============================
날씨 : 구름조금
평균기온 : -5
최저기온 : -6
최고기온 : -5
습도 : 63
일출시각 : 2023/12/20 07:42:10
일몰시각 : 2023/12/20 17:16:20
==============================
지역을 입력해주세요(시 또는 구 또는 동) : 제주도
==============================
날씨 : 가벼운 눈
평균기온 : -5
최저기온 : -5
최고기온 : -5
습도 : 56
일출시각 : 2023/12/20 07:32:50
일몰시각 : 2023/12/20 17:29:12
==============================
마치며
기본적인 api 활용법, json 파싱에 대해 알아볼 수 있었다.
'프로그래밍 > Java' 카테고리의 다른 글
[Java] 엑셀(Excel) 파일 읽기 (Feat.poi) (2) | 2023.11.19 |
---|---|
[Java] MVC 패턴의 이해 (0) | 2023.11.17 |
[Java] 다형성의 이해와 활용 (0) | 2023.11.15 |
[Java] 추상클래스(abstract)와 인터페이스(interface) (0) | 2023.11.14 |