BackEnd/WEB

XML_Naver검색API_국비DAY71

Leo.K 2022. 6. 13. 17:48

웹을 구현하는 프로그래밍 언어는 굉장히 다양하다.

하지만 프로그래밍 언어마다 사용하는 데이터 타입이 다르기 때문에 서로 다른 언어끼리는 직접적인 통신이 불가능하다. 그렇다면 어떤 방식으로 하나의 웹 서버에서 다른 언어로 구현한 데이터들을 송수신할 수 있을까? 이를 해결하기 위해 공통 DataType을 가지는 XML과 JSON이 존재한다. 서로 다른 언어들은 직접적으로 통신을 할 수는 없지만 아래 그림과 같이 공통 DataType인 XML과 JSON을 거치게 되면 서로 통신할 수 있도록 서비스를 제공한다. 오늘은 XML을 pharsing해보는 실습을 해보기 위해서 네이버에서 제공하는 검색 Open API를 사용해보겠다.

 

[ Naver 검색 Open Api사용하기 ]

 

NAVER Developers

네이버 오픈 API들을 활용해 개발자들이 다양한 애플리케이션을 개발할 수 있도록 API 가이드와 SDK를 제공합니다. 제공중인 오픈 API에는 네이버 로그인, 검색, 단축URL, 캡차를 비롯 기계번역, 음

developers.naver.com

  • 로그인을 진행하고 Application을 눌러서 Application을 등록한다. 
  • 첫 등록이라면 본인인증을 거치고 다음의 과정을 거쳐야 하는데 이미지를 참고하길 바란다.
    • 애플리케이션 이름은 아무거나 사용해도 된다.
    • 사용할 API를 선택하고 API를 사용할 환경을 선택한다. 환경은 Android, IOS, WEB이 있다. 
    • API를 사용할 웹 서비스 URL주소를 주소와 포트번호까지만 입력한 후 Application을 생성한다.

 

위의 설정을 마쳤다면, 상단 메뉴에서 Product의 서브 메뉴 중 서비스API의 "검색"을 클릭하면 검색 API를 사용하기 위한 개발 가이드를 확인할 수 있다.

오늘은 저번 시간에 배운 XML문서를 파싱하는 방법을 사용해서 검색 API를 통해 읽어 들인 XML문서를 자바로 파싱하여 출력해볼것이다.

 

XML을 문서를 파싱하는 코드는 아래와 같다. 특정 코드에 대해서는 주석을 달아두었고, 나머지 변수의 쓰임새는 네이버에 개발자 가이드를 참고하면 된다. 지난 시간에 배운대로, XML을 파싱할때는 반드시 root태그부터 순서대로 파싱해야한다.코드의 23~24번줄은 Application을 등록하면서 받은 클라이언트 아이디와 비밀번호를 입력해야 한다. 

[ MySearchUtil ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package util;
 
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
 
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
 
import vo.ProductVo;
 
public class MySearchUtil {
    
    //상품정보과 시작위치, 개수를 지정해서 이 메서드를 호출하면 리스트 형식으로 데이터를 뽑아준다.
    //추가적으로 static 메소드이기 때문에 클래스의 객체를 생성하지 않고 사용할 수 있다.
    //ㄴ> 클래스네임.스태틱메서드명
    public static List<ProductVo> search_shop(String p_name,int start,int display)
    {
//검색된 데이터를 저장할 list
        List<ProductVo> list = new ArrayList<ProductVo>();
        String clientId = "Your_Client_id";
        String clientSecret = "Your_Client_pwd";
 
        try {
            
            //"""일반적"""으로 모든 웹 사이트는 utf-8을 사용한다.
            //자바 코드 상에서 URL상의 데이터를 인코딩 하는 법
            p_name = URLEncoder.encode(p_name, "utf-8");
            String urlStr = String.format("https://openapi.naver.com/v1/search/shop.xml?query=%s&start=%d&display=%d",
                             p_name,start,display
                    );
 
            URL url = new URL(urlStr);
            //그냥 url만 보내도 되지만, 그렇게 하면 header에 id와 pwd를 담아서 따로 보내야한다. url커넥션을 생성하면, url과 헤더를 한 번에 보낼수 있다.
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            //발급받은 ID
            connection.setRequestProperty("X-Naver-Client-Id", clientId); 
            //발급받은 PW
            connection.setRequestProperty("X-Naver-Client-Secret", clientSecret); 
            // 받을요청타입
            connection.setRequestProperty("Content-Type""application/xml"); 
            connection.connect();

//XML 파싱 객체. jdom2 라이브러리를 사용한다.
            SAXBuilder builder = new SAXBuilder();
            Document   doc = builder.build (connection.getInputStream());

//XML문서 상에 루트 태그부터 그 밑의 자식 태그를 읽어서 list에 담아 준다.
            Element  root     = doc.getRootElement(); //<rss>
            List<Element>   element_list = (List<Element>)root.getChild("channel").getChildren("item");
 
            for(Element item : element_list){
                String title = item.getChildText("title");
                String link  = item.getChildText("link");
                String image = item.getChildText("image");
                int lprice=0,hprice=0;
                try {
                    lprice = Integer.parseInt(item.getChildText("lprice"));
                } catch (Exception e) {
                    // TODO: handle exception
                }
                
                try {
                    //에러가 발생한 경우 초깃값 0으로 처리해라.
                    hprice = Integer.parseInt(item.getChildText("hprice"));
                } catch (Exception e) {
                    // TODO: handle exception
                }
                
                String mallName = item.getChildText("mallName");
                
                //상품목록을 포장
                ProductVo vo = new ProductVo();
                vo.setTitle(title);
                vo.setLink(link);
                vo.setImage(image);
                vo.setLprice(lprice);
                vo.setHprice(hprice);
                vo.setMallName(mallName);
                                
                //ArrayList에 넣기
                list.add(vo);
                
 
            }
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
        
        
        return list;
    }
    
    
}
 
cs

 

  1. 검색을 할 메인화면을 구성한다. 메인화면에서 ajax통신을 사용하여 메인 페이지에서 검색버튼을 누르면 데이터를 가져와줄 서블릿을 비동기로 호출한다. 비동기로 전송할 파라미터는 검색할 단어(p_name), 페이지가 시작되는 번호(start), 그리고 가져올 검색 결과의 개수(display)이다. 사용자가 선택한 값에 대해서 검색결과를 페이징 처리 하는데, 매 페이지에서 인덱스가 1부터 시작하면 안되기 때문에, 약간의 산수를 응용하여 인덱스번호가 이어질 수 있도록 한다. 
  2. 서블릿에서는 파라미터를 수신하고, 수신한 데이터를 함수의 인자로 전달한다. 네이버에서 검색한 결과를 XML문서로 받는데, 이 XML문서를 파싱해서 리스트로 반환해주는 역할을 하는 파일이 바로 위의 코드 MySearchUtil.java이다. 이는 네이버 Open API를 사용하여 네이버에서 검색한 결과를 XML파일로 받고, 받은 파일을 pharsing하여 리스트로 변환해주는 역할을 한다.   
  3. 위의 파일로부터 반환받은 리스트를 product_search.jsp파일로 포워딩하여 리스트를 출력한다. 비동기로 호출당한 서블릿은 이 jsp파일 자체를 응답하여 callback함수의 인자로 들어가는 res_data에는 jsp파일이 들어간다. 결국 검색조건(페이지 설정)을 설정하고 검색버튼을 누르면 화면의 이동이 없이 검색 결과가 html페이지에 나타난다. 

 

[ search_show.html ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
 
<!-- BootStrap 3.x -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
 
<style type="text/css">
    #disp{
        width: 1000px;
    }
</style>
 
<script type="text/javascript">
    function search_product(){
        var p_name = $("#p_name").val().trim();
        
        if(p_name ==''){
            alert('검색할 상품명을 입력하세요.');
            $("p_name").val('');
            $("p_name").focus();
            return;
        }
        
        //페이지 
        var s_page = $("#search_page").val();
        //페이지당 출력갯수
        var s_disp = $("#search_display").val();
        
        var start   = ((s_page-1)*s_disp)+1;
        var display = s_disp;
        
        
        //Ajax로 요청 
        //검색 버튼을 누르면 서블릿을 호출하고, 서블릿은 jsp파일로 포워딩하여 jsp파일을 만들고, 이 jsp파일 자체를 res_data로 넘겨준다. 
        //비동기로 수신한 res_data(jsp파일)을 바로 출력한다.
        $.ajax({
            
            url      : 'product/search.do',    //ProductSearchAction
            data     : {'p_name':p_name, 'start':start, 'display':display},
            success  : function(res_data){    //서블릿에서 요청한 정보에 대한 상품 정보를 res_data에 담아서 줌. json으로 수신하는 것이 아니라 그대로 쓸것임
                $("#disp").html(res_data);
            },
            error    : function(err){
                alert(err.responseText);
            }
        });
    }
</script>
 
</head>
<body>
 
상품명 : <input id="p_name">
         <input type="button" value="검색" onclick="search_product();">
         
         <!-- 페이지당 조회건수 설정하기 -->
         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
         페이지 : <select id="search_page">
                           <option value="1">1</option>
                           <option value="2">2</option>
                           <option value="3">3</option>
                           <option value="4">4</option>
                           <option value="5">5</option>
                           <option value="6">6</option>
                           <option value="7">7</option>
                           <option value="8">8</option>
                           <option value="9">9</option>
                           <option value="10">10</option>
                   </select>
         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
         페이지당 조회 건수 : <select id="search_display">
                                       <option value="10">10</option>
                                       <option value="20">20</option>
                                       <option value="30">30</option>
                                       <option value="40">40</option>
                                       <option value="50">50</option>
                                       <option value="60">60</option>
                                       <option value="70">70</option>
                                       <option value="80">80</option>
                                       <option value="90">90</option>
                                       <option value="100">100</option>
                               </select>
<hr>
<div id="disp"></div>
</body>
</html>
cs

 

[ ProductSearchAction ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package action;
 
import java.io.IOException;
import java.util.List;
 
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import util.MySearchUtil;
import vo.ProductVo;
 
/**
 * Servlet implementation class ProductSearchAction
 */
@WebServlet("/product/search.do")
public class ProductSearchAction extends HttpServlet {
    private static final long serialVersionUID = 1L;
 
    /**
     * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
     */
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        // /product/search.do?p_name=노트북
        request.setCharacterEncoding("utf-8");
        
        //1.parameter 받기 
        String p_name = request.getParameter("p_name");
        //검색할 인덱스(몇 번째부터 검색할꺼냐?)
        int    start   = 1;
        //검색할 데이터 개수(몇 개 검색할꺼냐?)
        int    display = 10;
        
        
        
        //값이 안들어왔을 경우를 대비한 방어 코드
        try {
            start   = Integer.parseInt(request.getParameter("start"));
        } catch (Exception e) {
            // TODO Auto-generated catch block
        }
        
        
        try {
            display = Integer.parseInt(request.getParameter("display"));
        } catch (Exception e) {
            // TODO Auto-generated catch block
        }
        
        
        
        //2. 검색 정보 가져오기. static메서드 이기 때문에 객체를 생성할 필요가 없이 메서드를 사용할 수 있다.
        List<ProductVo> list = MySearchUtil.search_shop(p_name, start, display);
        
        //request binding
        request.setAttribute("list", list);
 
        //forward
        String forward_page = "product_search.jsp";
        RequestDispatcher disp = request.getRequestDispatcher(forward_page);
        disp.forward(request, response);
 
    }
 
}
 
 
cs
 

 

[ product_search.jsp ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
 
<!-- BootStrap 3.x -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
 
<style type="text/css">
    img { 
        width : 120px;
        height: 100px;
    }
</style>
 
</head>
<body>
${param.p_name } 검색결과 입니다...
<hr>
<!-- 
     이 문서 전체가 응답의 결과로 search_shop.html에 $("#disp") 안으로 들어가기 때문에 
     부모태그는 id가 disp인 div태그이다. 
     -->
<table class="table table-striped">
    <tr class="success">
        <th>번호</th>
        <th>이미지</th>
        <th>상품명</th>
        <th>가격(최저가)</th>
        <th>가격(최고가)</th>
        <th>판매처</th>
    </tr>
    
    
    <!-- for(ProductVo vo : list) -->
    <c:forEach var="vo" items="${list}" varStatus="i">
        <tr>
            <td>${param.start + i.index}</td>
            <td><img src="${vo.image }"></td>
            <td><a href="${vo.link }">${vo.title }</a></td>
            <td><fmt:formatNumber value="${vo.lprice }"/></td>
            <td><fmt:formatNumber value="${vo.hprice }"/></td>
            <td>${vo.mallName }</td>
        </tr>
    </c:forEach>
</table>
 
</body>
</html>
cs

 

[ ProductVo ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package vo;
 
public class ProductVo {
    String title;
    String link;
    String image;
    int    lprice;
    int    hprice;
    String mallName;
    int    startNum;
    
    public int getStartNum() {
        return startNum;
    }
    public void setStartNum(int startNum) {
        this.startNum = startNum;
    }
    
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getLink() {
        return link;
    }
    public void setLink(String link) {
        this.link = link;
    }
    public String getImage() {
        return image;
    }
    public void setImage(String image) {
        this.image = image;
    }
    public int getLprice() {
        return lprice;
    }
    public void setLprice(int lprice) {
        this.lprice = lprice;
    }
    public int getHprice() {
        return hprice;
    }
    public void setHprice(int hprice) {
        this.hprice = hprice;
    }
    public String getMallName() {
        return mallName;
    }
    public void setMallName(String mallName) {
        this.mallName = mallName;
    }
    
}
 
cs

 

 

[ 카카오 로컬 Open API활용하기 ]

    1. 다음의 사이트로 접속한다. https://developers.kakao.com/
 

Kakao Developers

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

developers.kakao.com

 

위와 같이 내 어플리케이션에 들어가서 어플리케이션을 새로 생성한다. 앱 이름과 사업자명은 하고 싶은 내용을 적는다 .

  • 문서 > 로컬 > 개발 가이드로 들어가서 파라미터 정보와 개발에 필요한 기본정보가 소개되어있으니 참고한다.
  • 위도는 지구를 평면에 두었을때 y축, 경도는 x축에 해당하는 축이다.
  • 위도와 경도의 정보는 여기에서 검색을 하면 url상에서 확인할 수 있다.

postman이라는 무료 소프트웨어를 사용하여 결과를 확인해보면 다음과 같이 나온다. 설정한 위도 경도 좌표를 기준으로 반경 1000m(radius)안에있는 coffee집을 모두 찾아서 json형태로 넘겨준다.

먼저 아래의 url과 header정보를 추가해준다. Header에는 사용자의 REST Key를 등록해야 한다. 아래 url정보에서 query값만 바꾸면 해당 파라미터로 검색이 가능하다.

요청 url : https://dapi.kakao.com/v2/local/search/keyword.xml?y=37.5523419&x=126.9377159&radius=1000&query=coffee&sort=distance
Header   : Authorization: KakaoAK "YOUR REST KEY" 이때, KakaoAK라는 예약어도 1칸의 공백과 함께 key에포함된다는 것을 명심하고 주의하자!!

위의 xml데이터에서 필자는 아래의 이미지에서 확인할 수 있듯이 <documents>태그의 특정 데이터만 vo로 포장해서 list로 가져와 출력할 것이다.

위에서 사용했던 XML 파싱 파일에서 메서드만 추가해서 내용을 수정하면 아래와 같다. 

  1. search_local.html파일에서 현재 위치를 위도와 경도로 구한다. -> geolocation()
  2. ajax통신을 사용하는데, LocalSearchAction 서블릿으로 파라미터를 전송하는데, 검색명(l_name), 검색반경(radius), 위도 (latitude), 경도 (longitude) 네가지 정보를 전송한다. 
  3. 서블릿에서 위의 4가지 파라미터를 수신하고 XML을 파싱해주는 파일내부에 search_kakao_local()메소드에 수신한 파라미터를 인자로 주어서 호출하여 반환값으로 list를 받는다.
  4.  local_search.jsp파일로 3에서 구한 list를 포워딩 하여 출력한다. 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public static List<LocalVo> search_kakao_local(
        String search_name,         //검색(query)
        double latitude,            //위도
        double longitude,            //경도
        int radius                     //검색반경
        )
{
    List<LocalVo> list = new ArrayList<LocalVo>();
    
    String rest_api_key = "KakaoAK 425bbd2f8e5337e39c025a0314eb3175";
 
    try {
        
        //일반적으로 모든 웹 사이트는 utf-8을 사용한다. 
        //자바 코드 상에서 URL상의 데이터를 인코딩 하는 법
        search_name = URLEncoder.encode(search_name, "utf-8");
        String urlStr = String.format("https://dapi.kakao.com/v2/local/search/keyword.xml?y=%.8f&x=%.8f&radius=%d&query=%s&sort=distance",
                                                                                           latitude, longitude,radius, search_name
                );
 
        URL url = new URL(urlStr);
        //그냥 url만 보내도 되지만, 그렇게 하면 header를 따로 보내야한다. url커넥션을 생성하면, url과 헤더를 한 번에 보낼수 있다.
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        //Rest API Key
        connection.setRequestProperty("Authorization", rest_api_key); 
        // 받을요청타입
        connection.setRequestProperty("Content-Type""application/xml"); 
        connection.connect();
 
        SAXBuilder builder = new SAXBuilder();
        Document   doc = builder.build (connection.getInputStream());
 
        Element  root     = doc.getRootElement(); //<result>
        List<Element>   element_list = (List<Element>)root.getChildren("documents");
 
        for(Element item : element_list){
            String place_name        = item.getChildText("place_name");
            String road_address_name = item.getChildText("road_address_name");
            String place_url         = item.getChildText("place_url");
            String phone              = item.getChildText("phone");
            int distance              = Integer.parseInt(item.getChildText("distance"));
            double x                  = Double.parseDouble(item.getChildText("x"));    //경도
            double y                  = Double.parseDouble(item.getChildText("y"));    //위도
            
            
            
            //상품목록을 포장
            LocalVo vo = new LocalVo(place_name, road_address_name, place_url, phone, distance, x, y);
                            
            //ArrayList에 넣기
            list.add(vo);
            
 
        }
        
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    
    
    
    return list;
}
cs

[ search_local.html ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
 
<!-- BootStrap 3.x -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
 
<style type="text/css">
    #disp{
        width: 1000px;
    }
</style>
 
<script type="text/javascript">
 
    var latitude  = 0;
    var longitude = 0;
    
    function geoLocation(){
        if (navigator.geolocation) { // GPS를 지원하면
            navigator.geolocation.getCurrentPosition(function(position) {
              //alert(position.coords.latitude + ' ' + position.coords.longitude);
              latitude  = position.coords.latitude;
              longitude = position.coords.longitude;
            }, function(error) {
              console.error(error);
            }, {
              enableHighAccuracy: true,
              maximumAge: 0,
              timeout: Infinity
            });
        } else {
            alert('GPS를 지원하지 않습니다');
        }
    }
    
    geoLocation();
    
    
    function search_local(){
        var l_name = $("#l_name").val().trim();
        
        if(l_name ==''){
            alert('검색할 카테고리를 입력하세요.');
            $("l_name").val('');
            $("l_name").focus();
            return;
        }
        
        var radius = 1000;
        alert(latitude + ' ' + longitude);
        
        //Ajax로 요청 
        //검색 버튼을 누르면 서블릿을 호출하고, 서블릿은 jsp파일로 포워딩하여 jsp파일을 만들고, 이 jsp파일 자체를 res_data로 넘겨준다. 
        //비동기로 수신한 res_data(jsp파일)을 바로 출력한다.
        $.ajax({
            
            url      : 'local/search.do',    //LocalSearchAction
            data     : {'l_name':l_name, 'radius':radius, 'latitude':latitude, 'longitude':longitude},
            success  : function(res_data){    //서블릿에서 요청한 정보에 대한 상품 정보를 res_data에 담아서 줌. json으로 수신하는 것이 아니라 그대로 쓸것임
                $("#disp").html(res_data);
            },
            error    : function(err){
                alert(err.responseText);
            }
        });
    }
</script>
 
</head>
<body>
 
검색명 : <input id="l_name">
         <input type="button" value="검색" onclick="search_local();">
         
         <!-- 페이지당 조회건수 설정하기 -->
         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
         페이지 : <select id="search_page">
                           <option value="1">1</option>
                           <option value="2">2</option>
                           <option value="3">3</option>
                           <option value="4">4</option>
                           <option value="5">5</option>
                           <option value="6">6</option>
                           <option value="7">7</option>
                           <option value="8">8</option>
                           <option value="9">9</option>
                           <option value="10">10</option>
                   </select>
         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
         페이지당 조회 건수 : <select id="search_display">
                                       <option value="10">10</option>
                                       <option value="20">20</option>
                                       <option value="30">30</option>
                                       <option value="40">40</option>
                                       <option value="50">50</option>
                                       <option value="60">60</option>
                                       <option value="70">70</option>
                                       <option value="80">80</option>
                                       <option value="90">90</option>
                                       <option value="100">100</option>
                               </select>
<hr>
<div id="disp"></div>
</body>
</html>
cs

 

[ LocalSearchAction ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package action;
 
import java.io.IOException;
import java.util.List;
 
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import util.MySearchUtil;
import vo.LocalVo;
import vo.ProductVo;
 
/**
 * Servlet implementation class ProductSearchAction
 */
@WebServlet("/local/search.do")
public class LocalSearchAction extends HttpServlet {
    private static final long serialVersionUID = 1L;
 
    /**
     * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
     */
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        // /product/search.do?p_name=노트북
        request.setCharacterEncoding("utf-8");
        
        //1.parameter 받기 
        String l_name    = request.getParameter("l_name");
        int    radius    = Integer.parseInt(request.getParameter("radius"));
        
        //현재 위치의 위도 경도 정보
        double latitude  = Double.parseDouble(request.getParameter("latitude"));        
        double longitude = Double.parseDouble(request.getParameter("longitude"));
        
        
        //2. 검색 정보 가져오기. static메서드 이기 때문에 객체를 생성할 필요가 없이 메서드를 사용할 수 있다.
        List<LocalVo> list = MySearchUtil.search_kakao_local(l_name, latitude, longitude, radius);
        
        //request binding
        request.setAttribute("list", list);
 
        //forward
        String forward_page = "local_search.jsp";
        RequestDispatcher disp = request.getRequestDispatcher(forward_page);
        disp.forward(request, response);
 
    }
 
}
cs

 

[ local_search.jsp ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
 
<!-- BootStrap 3.x -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
 
<style type="text/css">
    img { 
        width : 120px;
        height: 100px;
    }
    
    .title_style{
        width: 50%;
        
    }
</style>
 
</head>
<body>
${param.l_name } 검색결과 입니다...
<hr>
<!-- 
     이 문서 전체가 응답의 결과로 search_shop.html에 $("#disp") 안으로 들어가기 때문에 
     부모태그는 id가 disp인 div태그이다. 
     -->
<table class="table table-striped">
    <tr class="success">
        <th>번호</th>
        <th>상호명</th>
        <th>도로명주소</th>
        <th>전화번호</th>
        <th>거리</th>
        <th>경도</th>
        <th>위도</th>
    </tr>
    
    
    <!-- for(ProductVo vo : list) -->
    <c:forEach var="vo" items="${list}" varStatus="i">
        <tr>
            <td>${i.count}</td>
            <td><a href="${vo.place_url }" target="_blank"><span class="title_style">${vo.place_name }</span></a></td>    <!-- target="_blank" -> 새페이지에서 보게해줌 -->
            <td>${vo.road_address_name }</td>
            <td>${vo.phone }</td>
            <td>${vo.distance }(m)</td>
            <td>${vo.longitude }</td>
            <td>${vo.latitude }</td>
        </tr>
    </c:forEach>
</table>
 
</body>
</html>
cs

 

'BackEnd > WEB' 카테고리의 다른 글

mybatis_국비Day73  (0) 2022.06.15
ORM_DB프레임워크_국비_DAY72  (0) 2022.06.14
XML_국비_DAY70  (0) 2022.06.10
PhotoGallery[완결]_국비_DAY69  (0) 2022.06.09
세션 트래킹_국비_Day68  (0) 2022.06.08