Spring RestTemplate을 사용하여 JSON 객체 목록 가져오기

KangWook·2024년 8월 23일

Spring 애플리케이션에서 외부 API와 통신하여 JSON 데이터를 가져오는 것은 일반적인 작업인데
특히 JSON 객체 목록을 처리하는 경우가 많다.

API를 가져올떄 ResponseDTO를 사용해서 가져오는게 일반적이지만 내가 가지고 오려는 API는 컬렉션으로 한겹 더 쌓여 있어서 DTO와 맵핑이 되지 않았다

그래서 구글링을 하던중 https://www.baeldung.com/spring-rest-template-list

이 페이지에서 RestTemplate을 사용하여 JSON 객체 목록을 가지고 올수있고 해당 코드를 예시가 나와있어
직접 적용 해보고 내코드를 예시로 다시 가지고와 설명을 해보려고 한다 .

1. RestTemplate 설정

@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}

위 코드에서는 RestTemplate 객체를 생성하고 이를 Spring 컨텍스트에 등록 하고 . 이제 이 빈을 사용하여 외부 API와 통신할 수 있다.


2. WeatherResponseDto 클래스 정의

외부 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는 날씨 정보를 나타낸다.

3. 메서드를통해 외부 API 가지고 오기

@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;
            });
}

단계별로 설명을 하자만

  • 3.1
    먼저 RestTemplate을 사용하여 외부 API로부터 날씨 정보를 가져온다
WeatherResponseDto[] response = restTemplate.getForObject(weatherApiUrl, WeatherResponseDto[].class);

if (response == null || response.length == 0) {
    throw new RuntimeException("날씨 정보를 가져오는데 실패 했습니다.");
}

이 코드는 weatherApiUrl에서 데이터를 받아와 WeatherResponseDto 배열로 변환하고. 만약 API 호출이 실패하거나 빈 데이터를 반환한 경우, 예외를 발생

  • 3.2 오늘 날짜 비교
    가져온 데이터에서 오늘 날짜에 해당하는 날씨 정보를 필터링하고. 여기서 오늘의 날짜는 MM-dd 형식으로 변환한다
String today = LocalDate.now().format(DateTimeFormatter.ofPattern("MM-dd"));

  • 3.3 날씨 정보 필터링
    Arrays.stream을 사용하여 가져온 날씨 데이터 배열에서 오늘 날짜에 해당하는 데이터를 필터링
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 객체를 반환

profile
꾸준히 성장하는 개발자

0개의 댓글