-
forward와 sendRedirect 차이백엔드/서블릿&JSP 2021. 1. 11. 21:15
RequestDispatcher와 forward란?
클라이언트로부터 요청을 받고 이를 다른 리소스(서블릿, html, jsp)로 넘겨주는 역할을 하는 인터페이스.
RequestDispatcher는 javax.servlet 패키지에 포함된 인터페이스로 위 정의와 같은 역할을 한다.
그리고 RequestDispatcher 인터페이스는 두 가지 메서드를 가지고 있다.
그 중 하나가 forward()다.
forward()는 위에서 말한 RequestDispatcher 인터페이스의 역할을 수행하는 메서드다.
forward()은 사용자 요청에 의해 컨테이너에서 생성된 request와 response를
다른 리소스(서블릿, jsp, html)로 넘겨주는 역할을 한다.
사용법은 아래 코드와 같다.
@WebServlet("/Test") public class Test extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { RequestDispatcher rd = request.getRequestDispatcher("/해당 request를 보낼 경로"); rd.forward(request, response); } }
간단히 해석하자면 클라이언트가 보낸 request 객체를 전달한 경로를 getRequestDispathcer() 메서드로 지정한다.
그리고 forward() 메서드를 통해 미리 지정한 경로로 request, response를 전달한다.
http와 RequestDispatcher
흔히 우리가 사용하는 웹서비스의 프로토콜인 HTTP 방식은 클라이언트가 요청(request)하고
서버가 응답(response)를 하면 한 번의 과정이 끝나게 된다.
그리고 이러한 Http 방식을 통해 데이터를 주고 받은 하나의 단위를 트랜잭션이라 한다.
근데 왜 갑자기 RequestDispatcher 이야기를 하다가 Http와 트랜잭션 이야기를 하는걸까?
RequestDispatcher는 Http 프로토콜을 이해해야 이해가 더 쉬워지기 때문이다.
위에서 말한대로 Http 프로토콜은 요청과 응답으로 이뤄지고 응답이 이뤄지면서 통신이 끝난다.
여기서 중요한 점은 request는 응답 전까지 계속 여러번 사용할 수 있다는 점이다.
서블릿은 클라이언트의 요청인 request 객체를 response하기 전까지 여러 서블릿에서 계속 돌려쓸 수 있다.
즉 response로 응답하여 통신끝나기 전까진 request 객체를 이리저리 옮겨가며 쓸 수 있다는 것이다.
forward와 sendRedirect의 차이
반면 forward와 비교되는 sendRedirect는 다음과 같이 쓰인다.
@WebServlet("/Test") public class Test extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.sendRedirect("redirect할 경로"); } }
간단히 설명하면 sendRedirect() 메서드를 사용하면 서버가 request에 대해 response하고 난 뒤
메서드에 입력된 경로로 이동한다는 뜻이다.
이때 forward와 차이점은 sendRedirect()를 쓰면 클라이언트와 서버 간 통신이 끝난다는 것이다.
RequestDispatcher객체의 forward는 일부러 response하지 않고 응답을 끌면서 다른 리소스로 전달한다.
반면 response객체의 sendRedirect()는 응답을 끝내는 역할을 한다.
이때 Http 프로토콜의 통신 방식을 알면 두 메서드가 어떤 차이가 있는지 명확히 알 수 있다.
forward는 다른 리소스로 패스하고, sendRedirect는 response 객체와 함께 응답하며 통신을 끝내는 것이다.
두 메서드는 모양새는 다르지만 결과적으론 각자의 객체를 다른 리소스로 전달하는 역할을 한다.
마지막으로 한 가지 forward의 예시를 보도록 하자.
아래 예시에서 필요한 파일은 forward1,2,3 서블릿 3개와 forward1, 2 jsp 2개 총 5개의 파일이다.
forward1 서블릿
@WebServlet("/forward1") public class forward1 extends HttpServlet{ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // response할 때 인코딩해줄 문자 코드 설정 response.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=UTF-8"); // jsp를 통해 전달된 문자열을 저장 String test_word = request.getParameter("f_test"); // request 객체에 jsp를 통해 전달된 문자열을 저장 request.setAttribute("f1", test_word); //RequestDispatcher 객체가 전달될 경로 지정 RequestDispatcher rd = request.getRequestDispatcher("forward2"); //forward를 통해 지정된 경로로 request, reponse 객체 전달 rd.forward(request, response); } }
forward2 서블릿
@WebServlet("/forward2") public class forward2 extends HttpServlet{ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=UTF-8"); RequestDispatcher rd = request.getRequestDispatcher("forward3"); rd.forward(request, response); } }
forward3 서블릿
@WebServlet("/forward3") public class forward3 extends HttpServlet{ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=UTF-8"); RequestDispatcher rd = request.getRequestDispatcher("forward2.jsp"); rd.forward(request, response); } }
forward1 jsp파일
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>forward1 jsp</h1> <form action="forward1" method="post"> <input type="text" name="f_test"> <input type="submit"> </form> </body> </html>
forward2 jsp파일
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>forward2 jsp</h1> <p>여기는 forward2 jsp입니다.</p> <p>${f1}입니다.</p> </body> </html>
대략 구성도를 보면 아래와 같다.
맨 처음 forward1 jsp 파일에서 post 방식으로 foward1 서블릿으로 request를 전달한다.
그리고 나면 foward1 => forward2 => forward3 순으로 forward()를 통해 request 객체를 떠넘긴다.
최종적으로 받은 forward3는 forward()로 forward2 jsp파일로 request를 전달한다.
그리고 request를 받은 jsp 파일은 그 내용을 출력한다.
결과물을 보면 다음과 같다.
forward1 jsp 파일에서 위와 같이 이름을 입력하고 제출을 누른다.
forward1 서블릿으로 전달된 이름은 서블릿들을 거쳐서 최종적으로 forward2로 전달된다.
위와 같은 예는 별로 쓸 일은 없겠지만 foward가 어떤식으로 request를 활용할 수 있는지 쉽게 알 수 있다.
'백엔드 > 서블릿&JSP' 카테고리의 다른 글
서블릿에서 한글 문자 인코딩하기 (0) 2021.01.13 서블릿 기초 형태 (0) 2021.01.13 세션과 쿠키(Session과 Cookie) (0) 2021.01.07 javax.servlet.http 패키지 (0) 2021.01.07 javax.servlet 패키지 (0) 2021.01.06