관리 메뉴

거니의 velog

(18) 서블릿 확장 API 사용하기 1 본문

Java_Servlet

(18) 서블릿 확장 API 사용하기 1

Unlimited00 2023. 8. 26. 15:32

1. 서블릿 포워드 기능 사용하기

* 웹 프로그래밍 개발 초기에는 지금까지 배운 기본적인 서블릿 기능을 이용해 실제 웹 사이트의 기능을 구현했다. 즉, 서블릿 요청과 비즈니스 로직 처리 작업, 웹 브라우저의 화면 표시 응답 기능 등을 모두 사용했다.

* 이번에는 이 외에 서블릿 프로그래밍을 개발할 때 사용하는 기능인 포워드, 바인딩, 에너테이션 등 다양한 기능에 대해 알아보자.


(1) 포워드 기능

* 실제 온라인 쇼핑몰 같은 웹 애플리케이션은 여러 기능을 합쳐 하나의 프로그램을 실행한다. 회원 관리 기능, 게시판 관리 기능, 주문 관리 기능 등에 대해 각각의 서블릿이 기능을 수행하는 것이다.

* 그런데 프로그램을 실행하다 보면 서블릿끼리 또는 서블릿과 JSP를 연동해서 작업해야 하는 경우가 있다.
  예를 들어, 쇼핑몰의 경우 상품 관리 서블릿과 조회된 상품을 화면에 표기하는 JSP는 각각 따로 존재한다. 따라서 사용자가 상품 조회를 요청하면 상품 관리 서블릿은 데이터베이스에서 상품 정보를 조회한 후 다시 JSP에게 전달하여 상품 정보를 표시한다.

이처럼 하나의 서블릿에서 다른 서블릿이나 JSP와 연동하는 방법을 포워드(forward)라고 한다. 

* 포워드 기능이 사용되는 용도는 여러 가지이나 요약하면 다음과 같다.

- 요청에 대한 추가 작업을 다른 서블릿에게 수행하게 한다.

- 요청(request)에 포함된 정보를 다른 서블릿이나 JSP와 공유할 수 있다.

- 요청(request)에 정보를 포함시켜 다른 서블릿에게 전달할 수 있다.

- 모델2 개발시 서블릿에서 JSP로 데이터를 전달하는 데 사용된다.

* 한 마디로 포워드 기능은 서블릿에서 다른 서블릿이나 JSP로 요청을 전달하는 역할을 한다. 그리고 이 요청(request)을 전달할 때 추가 데이터를 포함시켜서 전달할 수도 있다. 모델2 개발 방식으로 웹 어플리케이션을 개발할 경우 서블릿에서 JSP로 데이터를 전달할 때 주로 사용된다.


2. 서블릿의 여러 가지 포워드 방법

* 서블릿에서 사용되는 포워드 방법에는 다음 네 가지가 있다.

* redirect 방법

- HttpServletResponse 객체의 sendRedirect() 메서드를 이용한다.

- 웹 브라우저에서 재요청하는 방식이다.

- 형식 : sendRedirect("포워드할 서블릿 또는 JSP");
* Refresh 방법

- HttpServletResponse 객체의 addHeader() 메서드를 이용한다.

- 웹 브라우저에 재요청하는 방식이다.

- 형식 : response.addHeader("Refresh", 경과시간(초); url=요청할 서블릿 또는 JSP);
* location 방법

- 자바스크립트 location 객체의 href 속성을 이용한다.

- 자바스크립트에서 재요청하는 방식이다.

- 형식 : location.href = '요청할 서블릿 또는 JSP';
* dispatch 방법

- 일반적으로 포워딩 기능을 지칭한다.

- 서블릿이 직접 요청하는 방법이다.

- RequestDispatcher 클래스의 forward() 메서드를 이용한다.

- 형식
  => RequestDispatcher dis = request.getRequestDispatcher("포워드할 서블릿 또는 JSP");
     dis.forward(request, response);

* redirect, refresh, location 방법은 서블릿이 웹 브라우저를 거쳐 다른 서블릿이나 JSP에게 요청하는 방법이다. 반면에 dispatch 방법은 서블릿에서 클라이언트를 거치지 않고 바로 다른 서블릿에게 요청하는 방법이다.

* 네 가지 모두 자주 사용하므로 각각의 사용법과 차이점을 익혀두는 것이 좋다.


(1) redirect를 이용한 포워딩

* redirect 방법은 서블릿의 요청이 클라이언트의 웹 브라우저를 다시 거쳐 요청되는 방식이다.

1. 클라이언트의 웹 브라우저에서 첫 번째 서블릿에 요청한다.

2. 첫 번째 서블릿은 sendRedirect() 메서드를 이용해 두 번째 서블릿을 웹 브라우저를 통해서 요청한다.

3. 웹 브라우저는 sendRedirect() 메서드가 지정한 두 번째 서블릿을 다시 요청한다.


(2) redirect를 이용한 포워딩 실습

1. 새 프로젝트 pro08을 만들고 sec01.ex01 패키지를 추가한다. FirstServlet 클래스와 SecondServlet 클래스를 추가한다.

2. FirstServlet 클래스를 다음과 같이 작성한다. redirect 기능을 구현한 서블릿이다.

package sec01.ex01;

import java.io.IOException;
import java.io.PrintWriter;

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

@WebServlet("/first")
public class FirstServlet extends HttpServlet{
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out = response.getWriter();
      response.sendRedirect("second"); // sendRedirect() 메서드를 이용해 웹 브라우저에게 다른 서블릿인 second로 재요청한다.
   }
}

3. SecondServlet 클래스는 첫 번째 서블릿에서 요청을 받아 실행하는 두 번째 서블릿이다.

package sec01.ex01;

import java.io.IOException;
import java.io.PrintWriter;

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

@WebServlet("/second")
public class SecondServlet extends HttpServlet{
	protected void doGet(HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException {
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out = response.getWriter();

      out.println("<html><body>");
      out.println("sendRedirect를 이용한 redirect 실습입니다."); // 브라우저로 출력한다.
      out.println("</body></html>");
   }
}

4. http://localhost:8090/pro08/first 로 요청한다.

5. 최종적으로 웹 브라우저에 표시되는 매핑 이름은 /second이다. 즉, /first로 요청하면 sendRedirect()를 호출해 웹 브라우저에게 다시 /second를 요청하는 것이다.


(3) refresh를 이용한 포워딩

* refresh를 이용한 포워딩 역시 redirect처럼 웹 브라우저를 거쳐서 요청을 수행한다.

1. 클라이언트의 웹 브라우저에서 첫 번째 서블릿에 요청한다.

2. 첫 번째 서블릿은 addHeader() 메서드를 이용해 두 번째 서블릿을 웹 브라우저를 통해서 요청한다.

3. 웹 브라우저는 addHeader() 메서드가 지정한 두 번째 서블릿을 다시 요청한다.


(4) refresh를 이용한 포워딩 실습

1. sec01.ex02 패키지를 만들고 redirect 포워딩 실습 때와 마찬가지로 두 개의 서블릿 클래스를 추가한다.

2. FirstServlet 클래스를 다음과 같이 작성한다. response의 addHeader() 메서드에 Refresh를 설정하고 1초 후 url=second에 지정한 second 서블릿에 브라우저에서 재요청하게 한다.

package sec01.ex02;

import java.io.IOException;
import java.io.PrintWriter;

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

@WebServlet("/first")
public class FirstServlet extends HttpServlet{
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out = response.getWriter();
      response.addHeader("Refresh","1;url=second"); // 웹 브라우저에 1초 후 서블릿 second로 재요청한다.
   }
}

3. SecondServlet 클래스를 다음과 같이 작성한다. 이는 브라우저에서 재요청하면 브라우저로 메시지를 출력하는 서블릿이다.

package sec01.ex02;

import java.io.IOException;
import java.io.PrintWriter;

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

@WebServlet("/second")
public class SecondServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out = response.getWriter();

      out.println("<html><body>");
      out.println("refresh를 이용한 redirect 실습입니다.");
      out.println("</body></html>");
   }
}

4. 브라우저에서 http://localhost:8090/pro08/first 로 요청하면 /second로 재요청한다.


(5) location을 이용한 포워딩

* 이번에는 자바스크립트의 location 객체를 이용하는 방법을 알아보자.

1. sec01.ex03 패키지를 만들고 다음과 같이 두 개의 서블릿 클래스를 추가한다.

2. FirstServlet 클래스를 다음과 같이 작성한다. 서블릿에서 PrintWriter로 자바스크립트 코드를 출력해 서블릿 second로 재요청한다.

package sec01.ex03;

import java.io.IOException;
import java.io.PrintWriter;

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

@WebServlet("/first")
public class FirstServlet extends HttpServlet{
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws  ServletException, IOException {
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out = response.getWriter();
      out.print("<script type='text/javascript'>");
      out.print("location.href='second';");
      out.print("</script>"); // 자바스크립트 location의 href 속성에 서블릿 second를 설정해 재요청한다.
   }
}

3. 마찬가지로 브라우저에서 재요청하면 브라우저로 메시지를 출력하는 두 번째 서블릿을 작성한다.

package sec01.ex03;

import java.io.IOException;
import java.io.PrintWriter;

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

@WebServlet("/second")
public class SecondServlet extends HttpServlet{
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws  ServletException, IOException {
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out = response.getWriter();

      out.println("<html><body>");
      out.println("location을 이용한 redirect 실습입니다.");
      out.println("</body></html>");
   }
}

4. http://localhost:8090/pro08/first 로 요청하면 /second로 재요청한다.


(6) redirect 방식으로 다른 서블릿에 데이터 전달하기

* redirect 방식을 이용하면 웹 브라우저를 통해 다른 서블릿을 호출하면서 원하는 데이터를 전달할 수도 있다.

1. 이번에는 redirect 방법으로 최초 요청한 서블릿에서 GET 방식으로 다른 서블릿으로 데이터를 전달하는 예제를 같은 방법으로 작성해 보자. FirstServlet 클래스를 다음과 같이 작성한다.

package sec02.ex01;

import java.io.IOException;
import java.io.PrintWriter;

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

@WebServlet("/first")
public class FirstServlet extends HttpServlet{
	protected void doGet(HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException {
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out = response.getWriter();
      response.sendRedirect("second?name=lee"); // GET 방식을 이용해 이름/값 쌍으로 데이터를 다른 서블릿으로 전달한다.
   }
}

2. SecondServlet 클래스를 다음과 같이 작성한다. 이전 서블릿에서 전달된 값을 getParameter() 메서드를 이용해 가져온다.

package sec02.ex01;

import java.io.IOException;
import java.io.PrintWriter;

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

@WebServlet("/second")
public class SecondServlet extends HttpServlet{
	protected void doGet(HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException {
      response.setContentType("text/html;charset=utf-8");
      PrintWriter out = response.getWriter();
      out.println("<html><body>");
      String name=request.getParameter("name"); // name으로 이전 서블릿에서 전달된 lee를 받는다.
      out.println("</body></html>");
      out.println("이름:"+name);
      out.println("<br>");
      out.println("</body></html>");

   }
}

3. 다음은 실행 결과이다. GET 방식을 이용해 redirect 되는 서블릿 second로 이름이 전달된다.

- http://localhost:8090/pro08/first

* refresh나 location 역시 GET 방식을 이용해 다른 서블릿으로 데이터를 전달할 수 있다.