[Spring] 네이버 지역 검색 API - 2 (기능 구현하기)

yunSeok·2023년 11월 24일
0

사이드 프로젝트

목록 보기
5/14

저번 글에서 사용해본 네이버 지역 검색 API를 활용해볼건데요!!

위 처럼 구글이나 네이버같은 웹페이지에서 검색할때 키워드를 입력하면 아래에 자동완성되는 검색결과들이 나오잖아요? 이와 비슷한 기능으로 구현하는게 목표입니다!!

저는 검색중에서도 지역 검색 API를 사용하고 있기 때문에 검색을 한다면 검색어에 맞는 지역 키워드만 출력이 됩니다!

저번 글에서 컨트롤러는 다 작성했기 때문에 입력칸과 ajax를 작성해서 최대한 사용가능하게 만들어보겠습니다!!❗️❗️


구현하기


입력칸에 입력을 할 때마다 ajax를 이용해 검색어에 대한 응답을 요청하고 응답결과를 입력창 아래에 보여주는 방식으로 구현이 되도록 해보겠습니다.

jsp

일단 검색어를 입력할 검색창을 하나 만들어줄게요.

<div class="post-form">
	<label for="postLoc" class="post-label">지역</label>
	<div class="post-search">
       <!-- 검색창 -->
	   <input name="postLoc" id="postLoc" class="form-control" placeholder="내용을 입력해주세요.">
       <img   ... >
       <img   ... >
	</div>
    <!-- 검색어에 대한 응답 출력 -->
	<div id="resultContainer"></div>
</div>

태그안에 돋보기 이미지와 x표시 이미지를 넣어줬습니다..ㅎㅎ

Ajax

ajax 요청과 응답 흐름을 작성해보겠습니다.

$("#postLoc").on("input", function(event) {
                 .
                 .
                 .
});

입력칸에 값이 입력될때마다 이벤트가 작동되도록 해줬습니다.


var text = $("#postLoc").val();

검색창 input 태그안에 입력값을 받아옵니다.


if (text.trim() !== "") {  
         .
         . 
     // ajax 요청과 응답
         .
         .
} else {
   return;
}

입력값이 있다면 ajax 요청을 처리하도록 if문 사용해주었습니다.


$.ajax({
	      url: "<c:url value='/naver/search'/>",
	      type: "GET",
	      data: {"text": text},
	      dataType: "json",
                .
                .
                .

요청 type은 공식문서에 따라 반드시 GET으로 요청 보내주고,
data에 검색어 입력값을 보내주도록 하겠습니다.


success: function(result) {
            .
            .
            .
}

다음은 중요한 응답처리인데요,
저번 글에도 작성되어 있지만, 검색어 요청에 대한 응답 결과와 형식을 먼저 확인해보겠습니다.

(강릉으로 검색한 예시입니다.)

{
    "lastBuildDate": "Sun, 26 Nov 2023 03:24:08 +0900",
    "total": 5,
    "start": 1,
    "display": 5,
    "items": [
        {
            "title": "<b>강릉</b>시청",
            "link": "https://www.gn.go.kr/",
            "category": "공공,사회기관>시청",
            "description": "",
            "telephone": "",
            "address": "강원특별자치도 강릉시 홍제동 1001",
            "roadAddress": "강원특별자치도 강릉시 강릉대로 33",
            "mapx": "1288758360",
            "mapy": "377521750"
        },
        {
            "title": "<b>강릉</b>짬뽕순두부 동화가든 본점",
            "link": "https://www.donghwagarden.com",
            "category": "한식>두부요리",
            "description": "",
            "telephone": "",
            "address": "강원특별자치도 강릉시 초당동 309-1 동화가든",
            "roadAddress": "강원특별자치도 강릉시 초당순두부길77번길 15 동화가든",
            "mapx": "1289146373",
            "mapy": "377911797"
        },
        {
            "title": "세인트존스호텔",
            "link": "https://new.stjohns.co.kr/",
            "category": "숙박>호텔",
            "description": "",
            "telephone": "",
            "address": "강원특별자치도 강릉시 강문동 1-1",
            "roadAddress": "강원특별자치도 강릉시 창해로 307",
            "mapx": "1289209164",
            "mapy": "377912822"
        },
        {
            "title": "카페 툇마루",
            "link": "http://www.instagram.com/cafe_toenmaru",
            "category": "음식점>카페,디저트",
            "description": "",
            "telephone": "",
            "address": "강원특별자치도 강릉시 초당동 355 카페 툇마루",
            "roadAddress": "강원특별자치도 강릉시 난설헌로 232 카페 툇마루",
            "mapx": "1289144756",
            "mapy": "377928911"
        },
        {
            "title": "부산처녀횟집",
            "link": "https://www.instagram.com/gyeongpo_busan/",
            "category": "한식>생선회",
            "description": "",
            "telephone": "",
            "address": "강원특별자치도 강릉시 강문동 산4-5 1층",
            "roadAddress": "강원특별자치도 강릉시 창해로 485 1층",
            "mapx": "1289092754",
            "mapy": "378034651"
        }
    ]
}

이런식으로 검색어에 대한 응답 결과들이 "items"안에 묶여서 응답되는 것을 확인할 수 있습니다.

따라서 ajax 응답시 result.items.응답받을데이터(ex) title, address ...) 이런 형식으로 응답받으면 됩니다.

success: function(result) {
   if (result && result.items.length > 0) {
	              
	      for (var i = 0; i < 5; i++) {
	            	  
	           var item = result.items[i];
	                  
	           $("#resultContainer").append("<p role='button' data-title='" 
                                            + item.title + "' data-address='" + item.address + "'>" 
                                            + item.title + "<br>" + item.address + "</p>");
          }
	              
	}     
}

위처럼 결과값이 있다면 p태그들이 출력되도록 해주었습니다. 테스트해볼게요!!


다음은 출력되는 결과들을 클릭했을 때 입력창에 들어가도록 해줄게요!!

$("#resultContainer p").on("click", function() {
                      
    var title = $(this).data("title");
    				  
    $("#postLoc").val(title);
    				    
    $("#resultContainer").empty();
});

제목만 input 태그에 넣어주고 검색결과를 클릭하면 .empty() 를 이용해서 검색결과를 지워줬습니다.

제목에 <b> 태그 까지 출력이 되어버려서..
split 을 이용해서 태그를 공백으로 바꿔줬습니다!!

수정 전

$("#postLoc").val(title);

수정 후

$("#postLoc").val(title.split("<b>").join("").split("</b>").join(""));

전체 코드

jsp

<div class="post-form">
    <label for="postLoc" class="post-label">지역</label>
    <div class="post-search">
      <input name="postLoc" id="postLoc" class="form-control" placeholder="내용을 입력해주세요.">
      <img id="searchImg" role="button" src="${pageContext.request.contextPath/images/search.png">
      <img id="xImg" role="button" src="${pageContext.request.contextPath}/images/xmark.png" onclick="clearInput()">
    </div>
    <div id="resultContainer"></div>
</div>

Ajax

$("#postLoc, #searchImg").on("input keypress click", function(event) {
	
	if(event.keyCode == 13) {
		event.preventDefault();
	}
	
	$("#resultContainer").empty();
	
	var text = $("#postLoc").val();
	
	if (text.trim() !== "") {
		
	    $.ajax({
	      url: "<c:url value='/naver/search'/>",
	      type: "GET",
	      data: {"text": text},
	      dataType: "json",
	      success: function(result) {
	    	  
	    	  if (result && result.items.length > 0) {
	              
	              for (var i = 0; i < 5; i++) {
	            	  
	                  var item = result.items[i];
	                  
	                  $("#resultContainer").append("<p role='button' data-title='" + item.title + "' data-address='" + item.address + "'>" + item.title + "<br>" + item.address + "</p>");
	              }
	              
	              $("#resultContainer p").on("click", function() {
                      
                      var title = $(this).data("title");
    				  
                       $("#postLoc").val(title.split("<b>").join("").split("</b>").join(""));
    				   $("#resultContainer").empty();
                  });
	              
	          } else {
	        	  $("#resultContainer").empty();
	          }
	      }, error: function(error) {
	    	  $("#resultContainer").empty();
	    	  console.log("Error:" + error.responseText);
	      }
	    });
	    
	} else {
		$("#resultContainer").empty();
		return;
	}
});



function clearInput() {
    var searchInput = document.getElementById('postLoc');

    searchInput.value = '';
}

결과화면

🤔 처음엔 막연하게 입력창에 자동완성 기능을 만들고 싶어서 구현해보려 했는데, 검색 결과를 DB에 저장해서 응답하는 방식으로 구현하게되면 엄청나게 많은 데이터를 DB에 저장하고 관리해야 하기 때문에 DB 성능이나 관리 측면에서 어려움이 있을거 같아서 오픈 API를 사용해봐야겠다고 생각했습니다. 기능 구현이 그렇듯 막히는 부분도 있었지만 해결하고 구현이 되니 좋네요 ㅎㅎ

다음에는 또 다른 API를 사용해서 기능을 구현해봐야겠습니다..!!

0개의 댓글