ApiResponse apiResponse = restTemplate.getForObject(uri, ApiResponse.class);
위 명령어 대로 uri주소를 restTemplate기능을 써서 주소를 입력했으나 제대로된 url주소를 받지 못하고 인코딩이 제대로 되지 않는 문제 발생
문제 예상
1. uri주소가 잘못되었다 오타.
2. 인코딩이 제대로 실행되지 않는다.
3. 공공데이터 포탈 인증키가 잘못되었다.
문제해결
인증키 자체는 문제없이 돌아가는 것을 확인 > 공공데이터 포탈에서는 response값이 제대로 보임
코드내에 uri 주소가 잘못되었는지 체크를 하기위해 단계별로 uri 주소를 모두 출력
위 코드 상단에는 제대로 인증키까지 적힌 인코딩 주소가 입력되나, 위 코드를 실행시 제대로 인코딩이 되지 않는 문제 발견
인코딩이 더블인코딩이 되는 경우와 uri주소가 전체로 들어가지 않고 짤려서 들어가는 문제 발생 인코딩이 제대로 되지않음
String SERVICE_KEY = "디코딩 인증키".trim();
String encodedKey = URLEncoder.encode(SERVICE_KEY, "UTF-8");
System.out.println("미리 인코딩된 키: " + encodedKey); // 미리 인코딩된 결과 확인
URI uri = UriComponentsBuilder
.fromHttpUrl("https://api.odcloud.kr/api/15003087/v1/uddi:705bfaaa-1fee-4b3c-8e89-cbbf0fd57748")
.queryParam("page", "1")
.queryParam("perPage", "5")
.queryParam("serviceKey", encodedKey) // 여기서는 trim() 후, RestTemplate이 자동 인코딩하도록 함
.build(true) // true: 이미 인코딩된 값이라고 가정하면 false로 설정
.toUri();
해당 코드로 수동으로 인코딩을 해주고 가져옴
try {
ApiResponse apiResponse = restTemplate.getForObject(uri, ApiResponse.class);
if (apiResponse != null && apiResponse.getData() != null) {
List<FlightItem> items = apiResponse.getData();
for (FlightItem item : items) {
// DB 저장을 위한 엔티티 변환
Air air = new Air(
item.getFlightNumber(),
item.getAirline(),
item.getDepartureAirport(),
item.getDepartureTime(),
item.getArrivalAirport(),
item.getArrivalTime()
);
airRepository.save(air);
}
}
} catch (Exception e) {
// 예외 처리: 로그 남기기 등
e.printStackTrace();
}
이제 문제없이 하단의 코드가 실행됨
추후 개편사항
webClient로 변경해서 사용하는 방안
@Service
public class OpenApiService {
private final WebClient webClient;
private final AirRepository airRepository;
@Autowired
public OpenApiService(AirRepository airRepository) {
this.airRepository = airRepository;
// 기본 URL을 설정하거나, 매번 URI를 완전히 구성할 수 있습니다.
this.webClient = WebClient.builder()
.baseUrl("https://api.odcloud.kr")
.build();
}
public void fetchAndSaveData() {
// 공백이나 개행 문자가 없도록 trim() 처리합니다.
String SERVICE_KEY = "디코딩 인증키".trim();
// UriComponentsBuilder를 사용하여 URL과 쿼리 파라미터를 안전하게 구성합니다.
URI uri = UriComponentsBuilder.fromUriString("/api/15003087/v1/uddi:705bfaaa-1fee-4b3c-8e89-cbbf0fd57748")
.queryParam("page", "1")
.queryParam("perPage", "5")
.queryParam("serviceKey", SERVICE_KEY) // 원본 키 전달, WebClient가 자동 인코딩
.build(true) // true: 인코딩 적용, 이미 원본 값이라면 WebClient가 한 번 인코딩 처리함
.toUri();
System.out.println("최종 요청 URI: " + uri.toString());
try {
// GET 요청을 보내고, 응답을 ApiResponse 타입으로 변환 후 block()으로 동기적으로 기다림
ApiResponse apiResponse = webClient.get()
.uri(uri)
.retrieve()
.bodyToMono(ApiResponse.class)
.block();
if (apiResponse != null && apiResponse.getData() != null) {
List<FlightItem> items = apiResponse.getData();
for (FlightItem item : items) {
// DB 저장을 위한 엔티티 변환
Air air = new Air(
item.getFlightNumber(),
item.getAirline(),
item.getDepartureAirport(),
item.getDepartureTime(),
item.getArrivalAirport(),
item.getArrivalTime()
);
airRepository.save(air);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}'Project > Team Project(딱좋은여행)' 카테고리의 다른 글
| 서버 db에 값 미리 넣는 방법 (0) | 2025.04.29 |
|---|---|
| 트러블슈팅 - admin 빌드 오류 (0) | 2025.04.07 |
| 트러블슈팅 - queryDsl 오류 해결방법 (0) | 2025.04.04 |
| 항공 상품 필터 및 페이징 처리 (0) | 2025.03.22 |
| 딱좋은 여행 코드 정리 (엔티티 연관관계 매핑) (1) | 2025.02.27 |