포워드(Forward)란?
하나의 서블릿에서 다른 서블릿이나 JSP(페이지)로 요청을 전달하는 것
원래 요청(request)에 포함된 정보는 한번 이동하고 나면 이동한 서블릿이나 JSP에서만 사용할 수 있지만, 포워드 기능을 사용하면 받은 요청을 다른 서블릿이나 JSP에 다시 전달해 사용할 수 있다.
HttpServletResponse
객체의 sendRedirect()
메서드 호출
response.sendRedirect("포워드할 서블릿 또는 JSP");
HttpServletResponse
객체의 addHeader()
메서드 호출
response.addHeader("Refresh", 경과시간(초); url="요청할 서블릿 또는 JSP");
자바스크립트에서 location
객체의 href
속성 지정
location.href = "요청할 서블릿 또는 JSP";
RequestDispatcher
클래스의 forward()
메서드 호출
일반적으로 포워드 기능은 dispatch를 이용한 포워드를 뜻함
RequestDispatcher dis = request.getRequestDispatcher("포워드할 서블릿 또는 JSP");
dis.forward(request, response);
1,2,3 방법은 서블릿이 클라이언트(웹 브라우저)로 이동한 후 다시 포워드하면서 요청을 보내지만, 4 방법은 클라이언트를 거치지 않고 서버에서 바로 포워딩이 이루어진다.
1,2,3 에서는 포워드할 때 웹 브라우저를 거치기 때문에 포워드한 페이지로 URL이 변경되지만 4 에서는 포워드 후에도 URL이 변경되지 않는다.
바인딩이란?
서블릿에서 다른 서블릿 등으로 이동할 때 데이터를 전달하기 위해 서블릿 관련 객체에 저장하는 것
HttpServletRequest
,HttpSession
,ServletContext
객체에서
setAttribute()
,getAttribute()
,removeAttribute()
메서드를 사용함
package sec02.ex01;
import java.io.IOException;
import java.io.PrintWriter;
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;
@WebServlet("/first2")
public class FirstServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
// dispatch : first 서블릿에서 웹 브라우저로 돌아가지 않고 second 서블릿으로 바로 포워드
// 이동하려는 서블릿으로 요청값을 전달할 수 있음
// 키 이름이 'id'와 'name'인 데이터를 request에 바인딩해 포워드 (name은 url에 붙임)
request.setAttribute("id", "아이디");
RequestDispatcher dispatch = request.getRequestDispatcher("second2?name=lee");
dispatch.forward(request, response);
}
}
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("/second2")
public class SecondServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
// 이전 서블릿에서 전달받은 요청값 변수에 담기
String name = request.getParameter("name");
String id = (String) request.getAttribute("id");
out.print("<html><body>");
out.print("dispatch를 이용한 forward<br>");
out.print("name : "+name+", id : "+id);
out.print("</body></html>");
}
}
💻 실행 결과
URL이 변경되지 않고 /second2 서블릿으로 포워드한 것을 확인할 수 있음
MemberServlet
서블릿에서 화면을 출력하는 내용만 분리해 사용자에게 화면을 보여줄 서블릿을 따로 생성한다. MemberServlet
에서 회원 목록 데이터를 바인딩해 화면 기능 담당 서블릿에 전달한다.
MemberServlet
서블릿의 내용을 수정
화면에 내용을 출력하는 부분을 삭제하고 viewMembers
라는 URL로 포워딩하는 코드 추가
...
@WebServlet("/member")
public class MemberServlet extends HttpServlet {
...
private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// 회원 추가/삭제 커맨드 처리
...
List<MemberDTO> list = dao.listMembers();
// 회원 목록을 request에 바인딩하기
request.setAttribute("membersList",list);
// viewMembers 서블릿으로 포워드할 때 바인딩한 request를 가져감
RequestDispatcher dispatch = request.getRequestDispatcher("viewMembers");
dispatch.forward(request, response);
}
ViewServlet
서블릿 생성
이전 서블릿에서 넘어온 회원 정보를 가져와 화면에 출력하는 코드 작성
package sec03.ex01;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.util.List;
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("/viewMembers")
public class ViewServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
// 바인딩해서 넘어온 request에서 회원 목록 가져오기
// 바인딩한 데이터 값은 Object 타입으로 저장되므로 원래 타입으로 캐스팅 필요
List<MemberDTO> membersList = (List) request.getAttribute("membersList");
String data = "";
data += "<html><body>";
data += "<table border=1><tr align='center' bgcolor='lightgreen'>";
data += "<td>아이디</td><td>비밀번호</td><td>이름</td><td>이메일</td><td>가입일</td><td>삭제</td></tr>";
for(int i=0; i < membersList.size(); i++) {
MemberDTO dto = membersList.get(i);
String id = dto.getId();
String pwd = dto.getPwd();
String name = dto.getName();
String email = dto.getEmail();
Date joinDate = dto.getJoinDate();
data += "<tr><td>"+id+"</td><td>"+pwd+"</td><td>"+name+"</td><td>"+email+"</td><td>"+joinDate+"</td><td>"+"<a href='member?command=delMember&id="+id+"'>삭제</a></td></tr>";
}
data += "</table>";
data += "<a href='memberForm.html'>새 회원 등록하기</a>";
data += "</body></html>";
out.print(data);
}
}
💻 실행 결과
보이는 화면은 이전 실습과 똑같지만,
MemberServlet
서블릿에서는 요청에 따라 작업을 수행하고 작업한 결과를 다른 서블릿으로 포워드하는 기능, ViewServlet
서블릿에서는 화면에 받아온 결과를 출력하는 기능만을 담당하도록 분리되었다. 뷰 기능을 하는 서블릿이 분화되어 발전된 것이 JSP
이다.