Spring 애플리케이션에서 외부 API와 통신하여 JSON 데이터를 가져오는 것은 일반적인 작업인데
특히 JSON 객체 목록을 처리하는 경우가 많다.
API를 가져올떄 ResponseDTO를 사용해서 가져오는게 일반적이지만 내가 가지고 오려는 API는 컬렉션으로 한겹 더 쌓여 있어서 DTO와 맵핑이 되지 않았다
그래서 구글링을 하던중 https://www.baeldung.com/spring-rest-template-list
이 페이지에서 RestTemplate을 사용하여 JSON 객체 목록을 가지고 올수있고 해당 코드를 예시가 나와있어
직접 적용 해보고 내코드를 예시로 다시 가지고와 설명을 해보려고 한다 .
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
위 코드에서는 RestTemplate 객체를 생성하고 이를 Spring 컨텍스트에 등록 하고 . 이제 이 빈을 사용하여 외부 API와 통신할 수 있다.
외부 API에서 날씨 정보를 받아오는 WeatherService를 구현을 하고 특정 URL에서 날씨 정보를 가져와 이를 리스트로 변환하고, 특정 조건에 맞는 데이터를 필터링을 한다
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class WeatherResponseDto {
@JsonProperty("date")
private String date;
@JsonProperty("weather")
private String weather;
public WeatherResponseDto() {
}
}
WeatherResponseDto 클래스는 date와 weather라는 두 가지 필드를 포함하고 있고. date는 날짜를, weather는 날씨 정보를 나타낸다.
@Override
public WeatherResponseDto getWeatherForToday() {
WeatherResponseDto[] response = restTemplate.getForObject(weatherApiUrl, WeatherResponseDto[].class);
if (response == null || response.length == 0) {
throw new RuntimeException("날씨 정보를 가져오는데 실패 했습니다.");
}
String today = LocalDate.now().format(DateTimeFormatter.ofPattern("MM-dd"));
return Arrays.stream(response)
.filter(weather -> today.equals(weather.getDate()))
.findFirst()
.orElseGet(() -> {
WeatherResponseDto weatherResponseDto = new WeatherResponseDto();
weatherResponseDto.setDate(today);
weatherResponseDto.setWeather("날씨 정보 없음");
return weatherResponseDto;
});
}
단계별로 설명을 하자만
WeatherResponseDto[] response = restTemplate.getForObject(weatherApiUrl, WeatherResponseDto[].class);
if (response == null || response.length == 0) {
throw new RuntimeException("날씨 정보를 가져오는데 실패 했습니다.");
}
이 코드는 weatherApiUrl에서 데이터를 받아와 WeatherResponseDto 배열로 변환하고. 만약 API 호출이 실패하거나 빈 데이터를 반환한 경우, 예외를 발생
String today = LocalDate.now().format(DateTimeFormatter.ofPattern("MM-dd"));
return Arrays.stream(response)
.filter(weather -> today.equals(weather.getDate()))
.findFirst()
.orElseGet(() -> {
WeatherResponseDto weatherResponseDto = new WeatherResponseDto();
weatherResponseDto.setDate(today);
weatherResponseDto.setWeather("날씨 정보 없음");
return weatherResponseDto;
});
filter: 오늘 날짜와 일치하는 WeatherResponseDto 객체를 필터링
findFirst: 필터링된 첫 번째 요소를 가져옵니다.
orElseGet: 오늘 날짜에 해당하는 데이터가 없을 경우, 기본 값을 반환합니다.
3.4 기본값 설정
.orElseGet(() -> {
WeatherResponseDto weatherResponseDto = new WeatherResponseDto();
weatherResponseDto.setDate(today);
weatherResponseDto.setWeather("날씨 정보 없음");
return weatherResponseDto;
});
이 부분은 Optional에서 값을 찾지 못했을 때 실행되고, 오늘의 날짜와 “날씨 정보 없음”이라는 메시지를 포함한 WeatherResponseDto 객체를 반환