우편번호 찾기 팝업 (custom)

박성현·2025년 7월 31일

개발중 학습

목록 보기
11/43

✅ Kakao 주소 API를 활용한 우편번호 검색 팝업 기능 구현

  • 기술 스택: Java (Spring Boot), Kakao REST API, Gson, jQuery

  • Kakao 주소 검색 API
    https://dapi.kakao.com/v2/local/search/address.json을 활용하여
    사용자가 입력한 주소로부터 우편번호, 도로명/지번주소, 위도/경도, 법정동코드 등 위치 정보 조회

  • Kakao API의 CORS 정책으로 인해 프론트엔드에서 직접 호출 불가
    → 백엔드(Spring Boot)에서 중계 API 구현 필요
    (※ 이 부분에서 다소 시간 소요됨)

  • 클라이언트는 검색 키워드를 JSON 형태로 전송
    → 백엔드에서 Kakao API에 GET 요청
    → 응답 JSON을 DTO(HttpKakaoAddressDTO)로 파싱하여 프론트에 반환

  • 기존의 daum.Postcode() 팝업을 사용하지 않고,
    직접 만든 HTML 팝업에서 주소 검색, 결과 표시 및 부모창 값 전달까지 커스터마이징


🧩 백엔드 주소 검색 API 중계 구현 (Java, Spring Boot)

  • @RequestMapping(value = "/HttpKakaoAddress" 생략
@RequestMapping("/loadAddressJSON")
public HttpKakaoAddressDTO loadAddress(Locale locale, @RequestBody Map<String, Object> param) {
    Gson gson = new Gson();
    log.info("loadAddress called. param: {}", param);

    try {
        String address = Objects.toString(param.get("address"), "");
        log.info("검색어 address: {}", address);

        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("Authorization", "KakaoAK ----발급받은 KEY값----");

        String url = "https://dapi.kakao.com/v2/local/search/address.json?analyze_type=similar&page=1&size=30&query=" + URLEncoder.encode(address, "UTF-8");

        String content = HttpHelper.httpGet(url, headers);
        return gson.fromJson(content, HttpKakaoAddressDTO.class);
    } catch (Exception ex) {
        ex.printStackTrace();
    }

    return gson.fromJson("{}", HttpKakaoAddressDTO.class);
}

기존 방식: Daum 우편번호 팝업 사용 방식 (비활용)

new daum.Postcode({
  oncomplete: function(data) {
    // 주소 자동 채움
  }
}).open();
  • 외부 팝업에 의존하며 UI/동작 방식 커스터마이징에 제약 존재

새 방식: 직접 구현한 HTML 팝업 + Kakao 주소 API AJAX 호출

$.ajax({
    type: "POST",
    url: "/HttpKakaoAddress/loadAddressJSON",
    contentType: "application/json",
    data: JSON.stringify({ address: keyword }),
    success: function (res) {
        const list = res.documents || [];
        const $tbody = $("table.list tbody");
        $tbody.empty();

        list.forEach(doc => {
            const html = `
                /* 추가 작성할 html 코드 */
            `;
            $tbody.append($(html));
        });
    }
});

💡 구현 포인트 요약

  • Kakao 주소 검색 API의 응답 구조를 분석하여 필요한 정보만 추출
    → 도로명 주소, 지번 주소, 우편번호, 위도/경도, 행정구역 코드 등

  • 백엔드(Spring Boot)에서 Kakao API 요청 중계 구현
    HttpHelper.httpGet()을 통해 헤더 포함된 GET 요청 수행
    → Gson으로 JSON 응답을 DTO로 매핑 후 프론트에 반환

  • CORS 문제 해결을 위해 프론트 → 백엔드 → Kakao API 방식으로 구성
    → 브라우저 보안 정책 우회 가능

  • 기존 daum.Postcode() 팝업을 대체하여
    HTML 기반 사용자 정의 팝업에서 주소 검색 및 선택 기능 구현
    → UI/UX 및 동작 커스터마이징 가능

  • 검색 결과를 <tbody>에 렌더링하여 실시간 검색 결과 제공
    → 사용자 선택 시 부모 창에 자동 입력 및 이벤트 트리거 가능

  • 외부 라이브러리 의존 최소화 + 사용자 정의 UI 구현
    → 유지보수 용이, 디자인 확장성 확보


🔍 문제 상황 및 개선 설명

Kakao 주소 검색 API를 사용할 때, 정확한 도로명 주소를 입력하지 않으면 응답 JSON의 address 또는 road_address 필드가 null로 반환되는 경우가 발생합니다.

이러한 경우에는 다음과 같은 문제가 발생합니다:

  • zone_no(우편번호), address_name(도로명 주소), h_code, b_code 등의 핵심 정보가 존재하지 않음
  • 따라서 사용자에게 유효하지 않은 주소 선택지를 표시할 수 있음

✅ 해결 방안

정확한 도로명 주소가 포함된 결과만 필터링하도록 아래와 같은 조건문을 추가하였습니다:

const validList = list.filter(doc => doc.road_address?.zone_no);

if (validList.length === 0) {
    $tbody.append("<tr><td colspan='2'>검색 결과가 없습니다. 도로명 뒤에 <b>건물번호까지</b> 정확히 입력해주세요.<br>예) 디지털로33길 27</td></tr>");
    return;
}

ex)
1. 명확한 도로명 주소가 아닐 시 응답 json값

2. 도로명 주소가 명확할 시 응답 json값

profile
개발기록장

0개의 댓글