서블릿 데이터 저장소 - request, session, ServletContext
서블릿을 이용하다보면 서블릿과 서블릿 사이 혹은 다른 리소스로 보내야할 때가 있다.
그럴때 이용할 수 있는 서블릿에서 제공하는 내장 객체가 있다.
request, session, servletContext가 바로 그것이다.
2021/01/06 - [백엔드/서블릿&JSP] - javax.servlet 패키지
javax.servlet 패키지
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; im..
sgcomputer.tistory.com
이미 한 차례 서블릿 패키지에 대해 설명할 때 쓴 적이 있다.
세 객체 모두 서블릿을 이용해 통신할 때 필요한 객체지만 더불어 데이터 저장소로서 사용이 가능하다.
이름 |
용도 + 데이터 공유 가능 범위 |
라이프 사이클 |
|
|
|
|
|
|
|
|
|
일반적으로 세 객체는 위 테이블과 같은 용도로 사용되고, 각자 라이프 사이클을 가진다.
그건 즉 데이터를 서블릿과 다른 자원들 사이에서 옮길 때 라이프 사이클을 고려해서 해야한다는 뜻이다.
별도의 DB(오라클, mysql)을 사용하지 않는다는 전제 하에 잠시 쓸 자료라면 request,
모든 서블릿에서 공유한다면 session, 모든 서블릿에서 공유하고 오래 보관해야한다면
servletContext를 이용하는 것이 좋다.
실제로 어떻게 쓰는지 실습해보자.
request를 데이터 저장소로 사용하기
request 데이터 저장 및 로드 흐름을 그림으로 나타내면 아래와 같다.
클라이언트가 서블릿으로 request를 보내면 서블릿 컨테이너는 해당 request를 객체로 만든다.
그리고 위 그림처럼 setAttribute()와 getAttribute()를 써서 객체에 데이터를 저장, 로드할 수 있다.
중요한건 request는 해당 request가 전달되는 서블릿에서만 데이터를 로드할 수 있다는 점이다.
즉 session, sevletContext에 비해 데이터 공유 가능 범위가 상대적으로 좁다.
실제 코드로 사용 방법을 보자.
아래 코드는 save1 서블릿에서 save2로 request를 통해 데이터를 전달하는 코드다.
@WebServlet("/save1")
public class DataSave extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String re = "request 객체 저장";
// request 객체에 문자열 저장
request.setAttribute("re", re);
// request를 다른 서블릿으로 forward함
RequestDispatcher rd = request.getRequestDispatcher("save2");
rd.forward(request, response);
}
}
@WebServlet("/save2")
public class DataSave2 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 전달받은 request 객체에서 데이터 로드
String re = (String) request.getAttribute("re");
PrintWriter out = response.getWriter();
out.print(re);
}
}
실행하면 아래와 같은 결과를 볼 수 있다.
save1 서블릿을 실행해서 request에 문자열을 저장하지만, request가 save2로 전달되어 화면에 출력된다.
request 객체를 통해 데이터를 저장하고 로드하려면 request 객체를 넘겨주는 과정이 있어야 한다.
위 코드로 보면 reqeustDispathRequestDispatcher를 통한 forward() 메서드가 그 과정을 진행한다.
Session, ServletContext 데이터 저장소로 사용하기
앞서 말했듯 session, sevletContext는 request와 달리 모든 서블릿이 공유해서 사용이 가능하다.
request에 데이터를 저장하는 방식은 제한이 있는 반면 session과 servletContext는 그런게 필요없다.
그림에서 볼 수 있듯이 별다른 처리 없이도 서블릿 컨테이너 내의 모든 서블릿에서 사용이 가능하다.
이번엔 코드로 보자.
save1 서블릿에서 데이터를 저장하고 save2 서블릿에서 데이터를 불러오는 코드다.
@WebServlet("/save1")
public class DataSave extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String se = "session 객체에 저장";
String sc = "sevletContext 객체에 저장";
// 세션과 서블릿 컨텍스트 선언
HttpSession session = request.getSession();
ServletContext servCon = getServletContext();
// 세션과 서블릿 컨텍스트에 데이터 저장
session.setAttribute("se", se);
servCon.setAttribute("sc", sc);
}
}
@WebServlet("/save3")
public class DataSave3 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
// 세션, 컨텍스트 정의
HttpSession session = request.getSession();
ServletContext servCon = getServletContext();
// 세션, 컨텍스트에 저장된 데이터를 로드해서 문자열에 저장
String se = (String) session.getAttribute("se");
String sc = (String) servCon.getAttribute("sc");
out.print(se+"<br>");
out.print(sc+"<br>");
}
}
해당 코드를 실행하면 아래와 같은 결과가 나온다.
request와 달리 별다른 흐름 처리 없이 모든 서블릿에서 사용이 가능하다.
단 session은 브라우저가 꺼지면 데이터가 날아가고, servletContext는 남아있다.