웹 프로그래밍 개발 초기에는 기본적인 서블릿 기능을 이용해 실제 웹 사이트의 기능을 구현하였음
또 서블릿 요청과 비즈니스 로직 처리 작업, 웹 브라우저의 화면 표시 응답 기능 등을 모두 사용했었음
실제 온라인 쇼핑몰 같은 웹 애플리케이션은 여러 기능을 합쳐 하나의 프로그램을 실행함
예를 들어 회원 관리 기능, 게시판 관리 기능, 주문 관리 기능 등에 대해 각각의 서블릿이 기능을 수행함
프로그램을 실행하다보면 서블릿끼리 또는 서블릿과 JSP를 연동해서 작업해야 하는 경우가 있음
이처럼 하나의 서블릿에서 다른 서블릿이나 JSP와 연동하는 방법을 포워드라고 함
포워드 기능이 사용되는 용도
- 요청에 대한 추가 작업을 다른 서블릿에게 수행하게 함
- 요청에 포함된 정보를 다른 서블릿이나 JSP와 공유가 가능
- 요청에 정보를 포함시켜 다른 서블릿에 전달이 가능
- 모델2 개발 시 서블릿에서 JSP로 데이터를 전달하는 데 사용됨
한마디로 포워딩 기능은 서블릿에서 다른 서블릿이나 JSP로 요청을 전달하는 역할
그리고 이 요청을 전달할 때 추가 데이터를 포함시켜서 전달함
모델2 방식으로 웹 애플리케이션을 개발할 경우 서블릿에서 JSP로 데이터를 전달할 때 주로 사용됨
서블릿에서 사용되는 포워드 방법에는 네 가지가 있음
1. redirect 방법
HttpServletResponse 객체의 sendRedirect( ) 메서드를 이용
웹 브라우저에 재요청하는 방식
형식: sendRedirect("포워드할 서블릿 또는 JSP");
2. Refresh 방법
HttpServletResponse 객체의 addHeader( ) 메서드를 이용
웹 브라우저에 재요청하는 방식
형식: response.addHeader("Refresh", "경과시간(초); url=요청할 서블릿 또는 JSP)";
3. location 방법
자바스크립트 location 객체의 href 속성을 이용
자바스크립트에서 재요청하는 방식
형식: location.href='요청할 서블릿 또는 JSP';
4. dispatch 방법
일반적으로 포워딩 기능을 지칭
서블릿이 직접 요청하는 방식
RequestDispatcher 클래스의 forward( ) 메서드를 이용
형식: RequestDispatcher dis = request.getRequestDispatcher("포워드할 서블릿 또는 JSP");
dis.forward(request, response);
redirect, refresh, location 방법은 서블릿이 웹 브라우저를 거쳐 다른 서블릿이나 JSP에게 요청하는 방법
반면에 dispatch 방법은 서블릿에서 클라이언트를 거치지 않고 바로 다른 서블릿에게 요청하는 방법
1. redirect를 이용한 포워딩
서블릿의 요청이 클라이언트의 웹 브라우저를 다시 거쳐 요청되는 방법
- 클라이언트의 웹 브라우저에서 첫 번째 서블릿에 요청
- 첫 번째 서블릿은 sendRedirect( ) 메서드를 이용해 두 번째 서블릿을 웹 브라우저를 통해 요청
- 웹 브라우저는 sendRedirect( ) 메서드가 지정한 두 번째 서블릿을 다시 요청
// FirstServlet.java
package sec01.ex01;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class FirstServlet
*/
@WebServlet("/first")
public class FirstServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("FirstServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("FirstServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
response.sendRedirect("second");
}
}
// SecondServlet.java
package sec01.ex01;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class SecondServlet
*/
@WebServlet("/second")
public class SecondServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("SecondServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("SecondServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
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>");
}
}
2. refresh를 이용한 포워딩
redirect와 같이 웹 브라우저를 거쳐서 요청을 수행함
- 클라이언트의 웹 브라우저에서 첫 번째 서블릿에 요청
- 첫 번째 서블릿은 sendRedirect( ) 메서드를 이용해 두 번째 서블릿을 웹 브라우저를 통해 요청
- 웹 브라우저는 sendRedirect( ) 메서드가 지정한 두 번째 서블릿을 다시 요청
// FirstServlet.java
package sec01.ex02;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class FirstServlet
*/
@WebServlet("/first")
public class FirstServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("FirstServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("FirstServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
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");
}
}
// SecondServlet.java
package sec01.ex02;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class SecondServlet
*/
@WebServlet("/second")
public class SecondServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("SecondServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("SecondServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
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>");
}
}
3. location을 이용한 포워딩
자바스크립트의 location의 href 속성에 second 서블릿을 설정해 재요청
// FirstServlet.java
package sec01.ex03;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class FirstServlet
*/
@WebServlet("/first")
public class FirstServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("FirstServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("FirstServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
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>");
}
}
// SecondServlet.java
package sec01.ex03;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class SecondServlet
*/
@WebServlet("/second")
public class SecondServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("SecondServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("SecondServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
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>");
}
}
GET 방식을 이용하여 redirect 방식으로 다른 서블릿에 이름/값 쌍으로 데이터를 전달하는 방법
// FirstServlet.java
package sec02.ex01;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class FirstServlet
*/
//@WebServlet("/first")
public class FirstServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("FirstServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("FirstServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
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방식을 이용한 데이터 전달
}
}
// SecondServlet.java
package sec02.ex01;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class SecondServlet
*/
//@WebServlet("/second")
public class SecondServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("SecondServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("SecondServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
String name = request.getParameter("name");
out.println("<html><body>");
out.println("이름: " + name);
out.println("</body></html>");
}
}
GET 방식을 이용하여 refresh 방식으로 다른 서블릿에 이름/값 쌍으로 데이터를 전달하는 방법
// FirstServlet.java
package sec02.ex02;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class FirstServlet
*/
@WebServlet("/first")
public class FirstServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("FirstServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("FirstServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
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?name=lee"); // GET방식을 이용한 데이터 전달
}
}
// SecondServlet.java
package sec02.ex02;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class SecondServlet
*/
@WebServlet("/second")
public class SecondServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("SecondServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("SecondServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
String name = request.getParameter("name");
out.println("<html><body>");
out.println("이름: " + name);
out.println("</body></html>");
}
}
GET 방식을 이용하여 location 방식으로 다른 서블릿에 이름/값 쌍으로 데이터를 전달하는 방법
// FirstServlet.java
package sec02.ex03;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class FirstServlet
*/
@WebServlet("/first")
public class FirstServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("FirstServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("FirstServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
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?name=lee';"); // GET방식을 이용한 데이터 전달
out.print("</script>");
}
}
// SecondServlet.java
package sec02.ex03;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class SecondServlet
*/
@WebServlet("/second")
public class SecondServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("SecondServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("SecondServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
String name = request.getParameter("name");
out.println("<html><body>");
out.println("이름 : " + name);
out.println("</body></html>");
}
}
4. dispatch를 이용한 포워딩
dispatch를 이용한 포워딩 과정
dispatch를 이용한 포워딩 과정이 redirect 방법과 다른 점은 클라이언트의 웹 브라우저를 거치지 않고 바로 서버에서 포워딩이 진행됨. 따라서 웹 브라우저 주소창의 URL이 변경되지 않기때문에 클라이언트 측에서는 포워드가 진행되었는 지 알 수 없음
- 클라이언트의 웹 브라우저에서 첫 번째 서블릿에 요청
- 첫 번째 서블릿은 RequestDispatcher를 이용해 두 번째 서블릿으로 포워드
dispatch 방법은 모델2 방식이나 스트럿츠(struts), 스프링(spring) 프레임워크에서 포워딩할 때 사용함
// FirstServlet.java
package sec03.ex01;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class FirstServlet
*/
@WebServlet("/first")
public class FirstServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("FirstServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("FirstServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
RequestDispatcher dispatch = request.getRequestDispatcher("second?name=lee");
dispatch.forward(request, response);
}
}
// SecondServlet.java
package sec03.ex01;
import java.io.IOException;
import javax.servlet.ServletConfig;
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 java.io.PrintWriter;
/**
* Servlet implementation class SecondServlet
*/
@WebServlet("/second")
public class SecondServlet extends HttpServlet {
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("SecondServlet init 메서드 호출");
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("SecondServlet destroy 메서드 호출");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
String name = request.getParameter("name");
out.println("<html><body>");
out.println("이름:" + name);
out.println("<br>");
out.println("dispatch를 이용한 forward 실습입니다.");
out.println("</body></html>");
}
}
서블릿의 포워드가 서버에서 수행되었기 때문에 주소창의 URL이 변경되지 않고 그대로인 것을 확인할 수 있음
'웹 개발 기초 > 자바 웹을 다루는 기술' 카테고리의 다른 글
HttpServletRequest를 이용한 redirect 포워딩 시 바인딩 (0) | 2023.02.18 |
---|---|
바인딩 (0) | 2023.02.18 |
이클립스 디버깅 기능 사용하기 (0) | 2023.02.17 |
DataSource 이용해 회원 정보 삭제하기 (0) | 2023.02.17 |
DataSource 이용해 회원 정보 등록하기 (0) | 2023.02.17 |