JAVA/프로젝트

카카오맵 Rest API - 주소로 위도, 경도 반환하기

whyHbr 2024. 7. 13. 23:25
728x90
반응형

https://developers.kakao.com/docs/latest/ko/local/dev-guide#address-coord

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

yml 파일에 추가

kakao:
  rest:
    api:
      key: ${KAKAO_REST_API_KEY}

 

환경변수에 키 값을 추가한다

 

반환하는 로직

@Slf4j
@Service
@RequiredArgsConstructor
public class KakaoMapService {

    private final RestTemplate restTemplate;

    private static final String KAKAO_MAP_URL = "https://dapi.kakao.com/v2/local/search/address.json";

    @Value("${kakao.rest.api.key}")
    private String apiKey;

    public MapResponse getAddress(String address) {

        if (ObjectUtils.isEmpty(address)) {
            throw new MapException(ErrorType.ADDRESS_IS_EMPTY);
        }

        URI uri = builderUriByAddress(address);

        HttpHeaders headers = new HttpHeaders();
        headers.set(HttpHeaders.AUTHORIZATION, "KakaoAK " + apiKey);
        HttpEntity httpEntity = new HttpEntity<>(headers);

       return restTemplate.exchange(uri, HttpMethod.GET, httpEntity, MapResponse.class).getBody();

    }

    public URI builderUriByAddress(String address) {
        UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(KAKAO_MAP_URL);
        uriBuilder.queryParam("query", address);

        URI uri = uriBuilder.build().encode().toUri(); //encode default utf-8
        log.info("[Build by Uri Address Search] address : {}, uri : {}", address, uri);

        return uri;
    }
}

 

반환값

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MapResponse {

    @JsonProperty("documents")
    private List<DocumentResponse> documents;
}
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class DocumentResponse {

    @JsonProperty("address_name")
    private String addressName;
    @JsonProperty("y")
    private double latitude;

    @JsonProperty("x")
    private double longitude;

}

 

 

적용

@Slf4j
@Service
@RequiredArgsConstructor
public class ProductService {

    private final ProductRepository productRepository;
    private final ProductInfoPerNightRepository productInfoPerNightRepository;
    private final AccommodationRepository accommodationRepository;
    private final LikeRepository likeRepository;
    private final MemberRepository memberRepository;
    private final KakaoMapService kakaoMapService;

    @Transactional
    public AccommodationDetailListResponse getAccommodationDetail(
        Long accommodationId, LocalDate checkInDate,
        LocalDate checkOutDate, int personNumber) {
        validateInputs(checkInDate, checkOutDate, personNumber);

        Accommodation accommodationEntity = findAccommodation(accommodationId);

        MapResponse mapResponse = kakaoMapService.getAddress(accommodationEntity.getAddress());

        updateXy(accommodationEntity, mapResponse);

        List<Product> productEntityList = productRepository.findAllByAccommodationId(
            accommodationId);

        List<ProductInfoPerNight> productInfoPerNightList = productInfoPerNightRepository
            .findByAccommodationIdAndDateRange(accommodationId, checkInDate, checkOutDate);

        List<Product> validProductList = findProductList(productEntityList, productInfoPerNightList,
            checkInDate, checkOutDate, personNumber);

        if (validProductList.isEmpty()) {
            throw new ProductException(ErrorType.INVALID_NUMBER_OF_PEOPLE);
        }

        List<ProductResponse> productResponses = findProductResponse(validProductList,
            productInfoPerNightList);

        AccommodationImageResponse accommodationImageResponse = AccommodationImageResponse
            .from(accommodationEntity.getImages());

        AccommodationOptionResponse accommodationOptionResponse = AccommodationOptionResponse
            .from(accommodationEntity.getOptions());

        Boolean liked = false;
        int likeCount = likeRepository.countByAccommodation(accommodationEntity);

        return AccommodationDetailListResponse.from(accommodationEntity, checkInDate,
            checkOutDate, accommodationImageResponse, accommodationOptionResponse,
            productResponses, liked, likeCount, mapResponse);
    }

 

데이터 베이스에 위도, 경도가 없으면 저정하는 로직

private void updateXy(Accommodation accommodation, MapResponse response) {
    if (accommodation.getLatitude() == null || accommodation.getLongitude() == null) {
        accommodation.setLatitude(response.getDocuments().get(0).getLatitude());
        accommodation.setLongitude(response.getDocuments().get(0).getLongitude());
        accommodationRepository.save(accommodation);
        log.info("Saved Accommodation with ID: {}", accommodation.getId());
    }
}
728x90