자바(JAVA)/JSP 웹 프로그래밍 공부 (성낙현의 JSP 자바 웹 프로그래밍 참고)

JAVA/JSP 47. 네이버 검색 API를 활용하여 검색 결과를 출력하는 프로젝트 - 서블릿 구현, 검색 결과를 웹 브라우저에 출력(이 카테고리의 마지막 글)

개발학생 2025. 5. 15. 18:28
반응형

*JAVA/JSP 35번 글의 시점부터는 노트북이 고장나는 바람에.. 다른 분의 글과 이전에 올렸던 글들을 참고하여, 다른 데스크탑의 윈도우 환경에 환경설정을 다시 진행한 후 작성하였습니다. 환경설정 관련 글들은 아래를 참고해 주세요.

  • JDK11 설치 및 환경 변수(JAVA_HOME) 설정 - CLASSPATH는 추가하지 않음
 

자바(JAVA) 11 설치 및 환경설정 | 자바 11 환경 변수

자바로 코딩 공부를 하려면 개발 할 수 있는 환경을 만들어 주어야 한다. 그 순서를 먼저 작성하자면JAVA SE JDK 설치 -> JAVA 환경 변수 설정 -> IDE 설치 이렇게 볼 수 있겠다. 이 포스팅은 자바로 개

velog.io

  • 톰캣 설치, 이클립스 설치 - 이 글을 쓰는 시점에서는 Tomcat 8버전이 없어, Tomcat 9버전 설치
 

JSP) JDK, 이클립스(eclipse), 톰캣 설치 및 환경 설정

1. JDK 설치 → Path 설정 2.eclipse JAVA EE버전 다운로드 3.웹컨테이너 톰캣 설치 →톰캣 환경설정 1. JDK 설치 - JAVA) 1. JDK 참고하여 설치하고 설정한다. -https://storyblogger.tistory.com/15?category=984696 2. 구글에

storyblogger.tistory.com

  • 이클립스 JDK 버전 설정 - JDK11로 설정
 

[이클립스] JDK 버전 바꾸는 법

스프링을 사용하는 에러가 난다? 그러면 JRE 버전을 확인해보자! 프로젝트의 JRE System Library의 오른쪽을 살펴보면 [JavaSE-17]이라고 되어있다. 스프링이나 하이버네이트를 사용할 때, 자바 8이나 자

myvelop.tistory.com

  • JDK 설치 및 환경 변수(JAVA_HOME) 설정, 톰캣 설치, 이클립스 설치 및 JDK 버전 설정 이후~ ⇒ 톰캣 버전과 jsp 파일 경로는 글 내용과 다르게 아래 이미지와 같음

 

JAVA/JSP 1. 개발 환경 구축 - 이클립스 기본 설정

*JDK 설치 및 환경 변수(JAVA_HOME) 설정, 톰캣 설치, 이클립스 설치를 완료한 상태OpenJDK 11: 자바 프로그램을 컴파일하고 실행해주는 기본 도구*이클립스 JDK-17이 설치되어있어서, https://coding-house.tisto

keep-programming-study.tistory.com

 

 

JAVA/JSP 1. 개발 환경 구축 - JSP 예제 테스트

1. 프로젝트 생성1) [File] → [New] → [Dynamic Web Project] 선택 2) 프로젝트 설정 화면 → Project name: HelloJSP, Target runtime: Apache Tomcat v9.0, Dynamic web module version: 4.0으로 설정 후 Next 클릭 3) 자바 소스 파일

keep-programming-study.tistory.com

 

 

JAVA/JSP 1. 개발 환경 구축 - 마지막 추가 설정

1. 외부 웹 브라우저로 실행하기-크롬이클립스는 웹 애플리케이션 실행 시, 자체 브라우저를 통해 실행 결과 출력웹 애플리케이션 배포 시 사용자는 크롬/파이어폭스 같은 전용 웹 브라우저로

keep-programming-study.tistory.com

  • 오라클(Oracle Database 11gR2 Express Edition) 설치 및 설정, 시퀀스 설정 
 

JAVA/JSP 14. 데이터베이스 - 특징, 오라클 설치(Oracle Database 11gR2 Express Edition), 사용자 계정 생성 및

1. 데이터베이스의 특징우리가 매일 PC나 스마트폰을 통해 접하는 거의 모든 웹 애플리케이션에서 사용함매일 업데이트되는 뉴스나 날씨 등의 정보는 데이터베이스가 없다면 클라이언트에 전달

keep-programming-study.tistory.com

 

JAVA/JSP 15. 데이터베이스 - 테이블 및 시퀀스 생성, JDBC 설정 및 데이터베이스 연결

*회원제 게시판 만들기-회원 인증 필요4. 테이블 및 시퀀스 생성1) 테이블 생성(1) member 테이블 - 아이디, 패스워드, 이름, 가입 날짜테이블 정의컬럼명데이터 타입 null 허용 키 기본값 설명idvarchar2

keep-programming-study.tistory.com

 

JAVA/JSP 16. 데이터베이스 - 커넥션 풀로 성능 개선, 간단한 쿼리 작성 및 실행

6. 커넥션 풀로 성능 개선웹은 클라이언트의 요청에 서버가 응답하는 구조→ Connection 객체 생성 때마다 네트워크 통신이 이뤄지며, 시간이 걸리는 작업들이 수반됨 == 시스템 성능에 큰 영향을

keep-programming-study.tistory.com

1. 서블릿 구현

1) 이전 글에서 언급한 API 설명 문서의 호출 예제를 복사해 수정함

2025.05.14 - [자바(JAVA)/JSP 웹 프로그래밍 공부 (성낙현의 JSP 자바 웹 프로그래밍 참고)] - JAVA/JSP 46. 네이버 검색 API를 활용하여 검색 결과를 출력하는 프로젝트 - 사전 지식 및 프로젝트 구상, 오픈 API 이용 신청, API 문서 살펴보기

https://keep-programming-study.tistory.com/142

// Java Resources/src/api/SearchAPI.java
package api;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 1.
@WebServlet("/NaverSearchAPI.do")
// 2.
public class SearchAPI extends HttpServlet {
  // 3.
	@Override
  protected void service(HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException {
  	// API 설명 문서의 호출 예제 코드 복사 및 수정
		// 1. 인증 정보 설정 
    String clientId = "uumDXqI7cU1PNGEAtt5j"; //애플리케이션 클라이언트 아이디
    String clientSecret = "BwIfCYS1Aj"; //애플리케이션 클라이언트 시크릿

    // 2. 검색 조건 설정 
    int startNum = 0;  // 검색 시작 위치
    String text = null;  // 검색어
    try {
    	startNum = Integer.parseInt(req.getParameter("startNum"));
      String searchText = req.getParameter("keyword");
      text = URLEncoder.encode(searchText, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException("검색어 인코딩 실패",e);
    }

    // 3. API URL 조합 (한 번에 가져올 검색 결과 개수와 검색 시작 위치 추가)
    String apiURL = "https://openapi.naver.com/v1/search/blog?query=" + text
     		          + "&display=10&start=" + startNum;  // json 결과

    // 4. API 호출(클라이언트 아이디와 시크릿을 요청 헤더로 전달)
    Map<String, String> requestHeaders = new HashMap<>();
    requestHeaders.put("X-Naver-Client-Id", clientId);
    requestHeaders.put("X-Naver-Client-Secret", clientSecret);
    String responseBody = get(apiURL,requestHeaders);

    // 5. 결과 출력 
    System.out.println(responseBody);
    resp.setContentType("text/html; charset=utf-8");
    resp.getWriter().write(responseBody);  // 서블릿에서 즉시 출력
  }
	
  //API 설명 문서의 호출 예제 메서드 3개 복사: 수정 없음 
  private static String get(String apiUrl, Map<String, String> requestHeaders){
    HttpURLConnection con = connect(apiUrl);
    try {
      con.setRequestMethod("GET");
      for(Map.Entry<String, String> header :requestHeaders.entrySet()) {
        con.setRequestProperty(header.getKey(), header.getValue());
      }

      int responseCode = con.getResponseCode();
      if (responseCode == HttpURLConnection.HTTP_OK) { // 정상 호출         
        return readBody(con.getInputStream());
      } else { // 오류 발생
        return readBody(con.getErrorStream());
      }
    } catch (IOException e) {
        throw new RuntimeException("API 요청과 응답 실패", e);
    } finally {
        con.disconnect();
    }
  }

  private static HttpURLConnection connect(String apiUrl){
    try {
        URL url = new URL(apiUrl);
        return (HttpURLConnection)url.openConnection();
    } catch (MalformedURLException e) {
        throw new RuntimeException("API URL이 잘못되었습니다. : " + apiUrl, e);
    } catch (IOException e) {
        throw new RuntimeException("연결이 실패했습니다. : " + apiUrl, e);
    }
  }

  private static String readBody(InputStream body){
    InputStreamReader streamReader = new InputStreamReader(body);

    try (BufferedReader lineReader = new BufferedReader(streamReader)) {
        StringBuilder responseBody = new StringBuilder();

        String line;
        while ((line = lineReader.readLine()) != null) {
            responseBody.append(line);
        }

        return responseBody.toString();
    } catch (IOException e) {
        throw new RuntimeException("API 응답을 읽는 데 실패했습니다.", e);
    }
  }
}

 

2) 서블릿 테스트

2. 검색 결과를 웹 브라우저에 출력

  • API 호출 결과로 받은 JSON을 파싱하여 웹 브라우저에 출력

1) 뷰 작성(JSP 파일)

<!-- src/main/webapp/api/SearchView.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>검색 API</title>
<!-- jQuery 사용 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<script>
// [검색 요청] 버튼 클릭 시 실행할 메서드 정의
$(function() {
  $('#searchBtn').click(function() {
    $.ajax({
      url : "../NaverSearchAPI.do",  // 요청 URL
      type : "get",                  // HTTP 메서드
      data : {                       // 매개변수로 전달할 데이터
    	keyword : $('#keyword').val(),                   // 검색어
        startNum : $('#startNum option:selected').val()  // 검색 시작 위치
      },
      dataType : "json",      // 응답 데이터 형식
      success : sucFuncJson,  // 요청 성공 시 호출할 메서드 설정
      error : errFunc         // 요청 실패 시 호출할 메서드 설정
    });
  });
});

// 검색 성공 시 결과를 화면에 출력
function sucFuncJson(d) {
  var str = "";
  
  // 배열을 첫 번째 인수로 받아 반복 실행 
  $.each(d.items, function(index, item) {
    str += "<ul>";
    str += "  <li>" + (index + 1) + "</li>";
    str += "  <li>" + item.title + "</li>";
    str += "  <li>" + item.description + "</li>";
    str += "  <li>" + item.bloggername + "</li>";
    str += "  <li>" + item.bloggerlink + "</li>";
    str += "  <li>" + item.postdate + "</li>";
    str += "  <li><a href='" + item.link + "' target='_blank'>바로가기</a></li>";
    str += "</ul>";
  });
  $('#searchResult').html(str);
}

// 실패 시 경고창
function errFunc(e) {
  alert("실패: " + e.status);
}
</script>

<style>
  ul{border:2px #cccccc solid;}
</style>
</head>
<body>
<div>
  <div>
    <form id="searchFrm">
      한 페이지에 10개씩 출력 <br />
      <select id="startNum">
        <option value="1">1페이지</option>
        <option value="11">2페이지</option>
        <option value="21">3페이지</option>
        <option value="31">4페이지</option>
        <option value="41">5페이지</option>
      </select>
      <input type="text" id="keyword" placeholder="검색어를 입력하세요." />
      <button type="button" id="searchBtn">검색 요청</button>
    </form>
  </div>
  <div class="row" id="searchResult">
    여기에 검색 결과가 출력
  </div>
</div>
</body>
</html>

2) 동작 확인(SearchView.jsp를 우클릭하여 Run As -> Run On Server 클릭)

검색어 입력 후 검색 요청 클릭
검색 결과 10개 출력-1
검색 결과 10개 출력-2
[2페이지]를 선택하고 [검색 요청]을 클릭하면 다른 글들이 출력되는 것을 볼 수 있음

반응형