지난 포스트에서 포워드에 대해 다루면서 GET 방식을 이용해 다른 서블릿/JSP로 데이터를 전달하는 방법을 소개드렸었습니다.
resp.sendRedirect("b?id=b1"); //id값이 b1인 데이터 전달
위와같이 전달하는 데이터가 한두개정도일때는 큰 문제가 되지 않지만 더 많은 정보를 전달하고자하는 경우에는 GET 방식을 사용해서 데이터를 전달하기가 상당히 불편해집니다. 그래서 대량의 데이터를 전달할 때는 바인딩(binding)
기술을 사용합니다.
바인딩
은 웹 애플리케이션을 실행하면 데이터를 서블릿 관련 객체에 저장하게 됩니다. 사용은 주로 HttpServletRequest, HttpSession, ServletContext
객체에서 사용되며 저장된 데이터는 애플리케이션 실행 시 서블릿/JSP에서 공유되어서 사용이 됩니다.
서블릿 객체에서 바인딩 기능을 제공하는 메소드는 다음과 같습니다.
메소드 | 설명 |
---|---|
setAttribute(String name, Object object) | 데이터를 각 객체에 바인딩 |
getAttribute(String name) | 객체에 바인딩된 데이터를 name으로 취득 |
removeAttribute(String name) | 객체에 바인딩된 데이터를 name으로 삭제 |
바인딩을 사용하는 세 가지 객체 중
HttpSession, ServletContext
는 추후에 다룰 내용이 따로 있기 때문에 해당 내용을 다룰때 소개드리고, 여기서는HttpServletRequest
의 바인딩 방법만 소개합니다.
먼저 redirect 방식을 사용할 때 바인딩을 하는 방법입니다. ServletA
를 다음과 같이 작성해주세요.
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/aa")
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>");
//HttpServletRequest 객체에 message라는 이름으로 "Hello Servlet!" 바인딩
req.setAttribute("message", "Hello Servlet!");
resp.sendRedirect("bb");
}
}
redirect할 ServletB
도 이어서 작성합니다.
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/bb")
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();
String message = (String) req.getAttribute("message");
out.println("<html><body><h1>전달된 데이터: " + message
+ "</h1></body></html>");
}
}
작성 후 톰캣 서버를 실행하고 http://localhost:8090/aa
로 접속하면...전달된 데이터가 null
로 나옵니다. 우린 분명 "Hello Servlet!"
이라는 데이터를 전달했는데 말이죠.
이렇게 나온 이유는 redirect
의 동작에 있습니다.포워딩을 하기 전 요청(1번)과 포워딩 이후 요청(3번)이 별개의 요청이기 때문입니다. 바인딩된 데이터는 1번의 요청 객체에 담겨져있기 때문에 별개의 요청인 3번 요청 객체에는 데이터가 담겨 있지 않게되는 것입니다.
그렇기 때문에 바인딩을 할 때 redirect
를 이용하는 방법은 적절하지 못하며 dispatch
방식을 이용해서 바인딩을 하게 됩니다.
SerlvetA
를 dispatch를 사용하도록 변경해주세요.
@WebServlet("/aa")
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>");
req.setAttribute("message", "Hello Servlet");
//dispatch를 사용하도록 변경
RequestDispatcher dispatcher = req.getRequestDispatcher("/bb");
dispatcher.forward(req, resp);
}
}
다시 실행 후 http://localhost:8090/aa
로 접속하면 제대로 바인딩된 데이터가 출력됨을 볼 수 있습니다.dispatch
의 동작에 따라 서블릿 포워딩이 서버에서 수행되었기 때문에 클라이언트의 주소는 그대로나오고 결과는 포워딩된 서블릿에서 보여주고 있음을 볼 수 있습니다.