포워드(Forward)
는 추가 작업을 다른 서블릿에게 수행하게 하거나, 요청에 대한 정보를 다른 서블릿/JSP와 공유하는 등의 용도로 다양하게 사용되는 기술입니다. 간단히 요약하면 포워드
는 한 서블릿에서 다른 서블릿이나 JSP로 요청(데이터)를 전달하는 기술이라고 할 수 있습니다.
포워드
를 구현하는 방식에는 redirect, Refresh, location, dispatch
4가지 방식이 있습니다.
HttpServletResponse.sendRedirect()
메소드 이용- 웹 브라우저에 재요청
sendRedirect("포워드 대상")
redirect
는 서블릿 요청이 클라이언트를 거쳐 다시 요청되는 방식입니다.
ServletA, ServletB
두 개의 서블릿을 생성합니다. A에서 B를 요청합니다.
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/a")
public class ServletA extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<html><body><h1>ServletA</h1></body></html>");
resp.sendRedirect("b"); //웹 브라우저에 다른 서블릿인 b를 요청
}
}
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/b")
public class ServletB extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<html><body><h1>ServletB</h1></body></html>");
}
}
톰캣 서버를 실행해서 http://localhost:8090/a
로 들어가게되면 바로 /b
로 리다이렉트 됨을 볼 수 있습니다.
redirect 방식을 이용할 때 다른 서블릿/JSP으로 데이터를 전달할 수도 있습니다.
resp.sendRedirect("b?id=b1");
GET
메소드의 키-값 쌍을 전달함으로써 데이터를 다른 서블릿/JSP로 데이터를 전달할 수 있습니다.
HttpServletResponse.addHeader()
메소드 이용- 웹 브라우저에 재요청
response.addHeader("Refresh", 경과시간, url=요청할_서블릿/JSP)
Refresh
방식도 redirect 방식과 유사하게 서블릿 요청이 클라이언트를 거쳐 다시 요청됩니다. 앞에서 작성한 ServletA
의 redirect 부분을 주석처리하고 아래와 같이 Refresh 포워딩 코드를 삽입합니다.
@WebServlet("/a")
public class ServletA extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<html><body><h1>ServletA</h1></body></html>");
//resp.sendRedirect("b"); redirect 포워딩
resp.addHeader("Refresh", "1;url=/b");
}
}
경과시간 단위는 초
로 위 코드에선 1초로 지정되었기 때문에 http://localhost:8090/a
에 접속하면 1초 후 http://localhost:8090/b
로 이동됩니다.
자바스크립트 location 객체의 href 속성
사용- 자바스크립트에서 재요청
location.href='요청할 서블릿, JSP';
location
은 자바스크립트의 객체 중 하나입니다. location.href
의 속성값으로 요청하고자하는 서블릿/JSP를 지정하면 포워딩하게 됩니다.
PrintWriter
를 이용해서 <script>
태그로 감싼 자바스크립트 코드를 전달합니다.
@WebServlet("/a")
public class ServletA extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<html><body><h1>ServletA</h1></body></html>");
//resp.sendRedirect("b"); redirect 포워딩
//resp.addHeader("Refresh", "1;url=/b"); Refresh 포워딩
out.print("<script type=\"text/javascript\">location.href=\"b\";</script>");
}
}
마찬가지로 http://localhost:8090/a
를 입력하면 바로 http://localhost:8090/b
로 이동함을 볼 수 있습니다.
- 포워딩이라고 하면 일반적으로 사용되는 방식
- 서블릿이 직접 요청
RequestDispatcher.forward()
메소드 이용
dispatch 포워딩
은 앞에서 본 redirect, Refresh와는 다르게 요청이 클라이언트를 거치지 않고 서버 내에서 포워딩이 바로 진행된다는 점 입니다.
@WebServlet("/a")
public class ServletA extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<html><body><h1>ServletA</h1></body></html>");
//resp.sendRedirect("b"); redirect 포워딩
//resp.addHeader("Refresh", "1;url=/b"); Refresh 포워딩
//out.print("<script type=\"text/javascript\">location.href=\"b\";</script>"); location 포워딩
RequestDispatcher dispatcher = req.getRequestDispatcher("b");
dispatcher.forward(req, resp);
}
}
역시 http://localhost:8090/a
로 접속하면 다음과 같은 결과가 나옵니다. 결과는 /b
지만 url은 그대로 /a
죠? 이는 dispatch가 위 그림대로 서버에서 포워딩이 실행되기 때문에 나타나는 결과입니다.
dispatch 방식도
GET
메소드의 키-값 쌍을 통해 다른 서블릿/JSP로 데이터를 전달할 수 있습니다.RequestDispatcher dispatcher = req.getRequestDispatcher("b?id=b1"); dispatcher.forward(req, resp);