▸JSP & Servlet/기본 상식

JSP 내장객체의 구조와 생명주기 (session / config / application )

코데방 2020. 2. 17.
728x90

서블릿의 객체를 기반으로하는 JSP의 내장 객체들은 JSP에서 자동으로 생성될만큼 필수적인 객체들입니다. JSP/서블릿이 구동되기 위한 여러 정보들을 담고 있는데, 생성과 소멸 시점이 각기 다르고 공유되는 범위가 제각각이라 헷갈리는 것 같습니다. 순서대로 개념과 구조, 생명주기를 정리해보겠습니다. JSP 내장객체에 대한 자세한 설명은 아래 링크글들을 참조 부탁드립니다.

 

2020/02/14 - [· JSP & Servlet/- 기본 문법] - JSP 내장 객체_request, response, out [1/4]

2020/02/16 - [· JSP & Servlet/- 기본 문법] - JSP 내장 객체_page / config / application [2/4]

2020/02/16 - [· JSP & Servlet/- 기본 문법] - JSP 내장 객체_pageContext / exception [3/4]

2020/02/17 - [· JSP & Servlet/- 기본 문법] - JSP 내장 객체_session (쿠키와 세션) [4/4]

 

 

* 참고

Context 라는 단어는 프로젝트와 동일 개념이라고 생각하시면 됩니다. 프로젝트를 두 개 생성해서 server.xml 파일의 Context 정보를 확인해보면 아래와 같이 나옵니다. 하나의 프로젝트 단위임을 알 수 있습니다. 웹 어플리케이션이라는 단어도 사전적 의미는 모호하지만 일반적으로 하나의 웹 서비스를 의미하므로 같은 범위로 생각하면 될 것 같습니다.

 

서로 다른 프로젝트는 객체나 정보를 공유할 수 없습니다. sendRedirect()로 URI를 전달해서 파라미터와 함께 클라이언트가 다른 프로젝트 페이지로 건너가게 할 수는 있습니다. 하지만 이건 세상 어느 사이트라도 보낼 수 있는 방법이라 정보 공유의 개념은 아닌 것 같습니다. 

  <Context docBase="hsweb" path="/hsweb" reloadable="true" source="org.eclipse.jst.jee.server:hsweb"/>
  <Context docBase="hwweb" path="/hwweb" reloadable="true" source="org.eclipse.jst.jee.server:hwweb"/>

 

 


 

 

1. 별로 알 필요 없는 객체들

  • page
  • pageContext

이 객체들은 JSP/서블릿을 작성할 때 쓸일이 거의 없는 객체들입니다. pageContext의 경우 가끔 include와 함께 사용할 수도 있습니다. 예를 들어 pageContex에 setAttribute()로 데이터를 저장해두면 해당 Page에서 getAttribute()로 꺼내 쓸 수 있습니다.

 

쓸모 없어 보이지만 만약 다른 페이지를 include하고 있는 상황이라면 유용하게 사용할 수 있습니다. 아래와 같이 먼저 데이터를 담아두고 include를 하면 해당 페이지에서 EL 태그로 데이터를 가져다 사용할 수 있게 됩니다. 

<% pageContext.setAttribute("viewName", "회원가입"); %>
<%@ include file="/WEB-INF/views/layout/top.jsp"%>
<span class="red-line-page">${viewName}</span>

 

EL태그는 pageContext-request-session-application의 scope 순서로 데이터를 찾으므로 그냥 request 객체에다 담아두고 써도 무방합니다. 

 


 

 

2. 사용자 요청별로 생성됐다 처리되면 사라지는 객체

  • request (javax.servlet.http.HttpServletRequest)
  • response (javax.servlet.http.HttpServletResponse)
  • out (javax.servlet.jsp.jspWriter)

이 객체들의 이해는 쉬우니 간단히 넘어가겠습니다. 브라우저에서 서버로 요청을 하고 서버에서 브라우저로 회신해주고 나면 이 객체들은 모두 사라집니다. Request, Response 객체는 하나의 요청을 처리하는 스레드에서 모든 JSP와 서블릿이 공유합니다. out은 서블릿에 공유되지 않기 때문에 서블릿에서 바로 클라이언트로 출력해주기 위해서는 PrintWriter의 출력 스트림을 따로 생성해줘야 합니다.

 

* 서블릿에서 출력 스트림 생성 방법

		PrintWriter out = response.getWriter();
		out.println("~~");

 

 

 


 

 

3. 사용자(브라우저) 별로 유지되는 객체

  • session (javax.servlet.http.HttpSession)

session에 대한 자세한 사항은 위 링크 글 중 "session [4/4]"를 참조하시면 됩니다. 간단히 session은 브라우저가 완전히 꺼질 때까지 해당 브라우저의 고유 식별자(id)를 서버에 저장해두고 같은 브라우저에서 요청이 왔는지 알아볼 수 있게 해주는 객체입니다. 브라우저 하나당 한 개의 session 객체를 가집니다.

 

새로운 브라우저 식별자가 들어오면 새로운 session 객체를 생성해놨다가 같은 식별자를 가진 브라우저가 다시 요청하면 해당 session 객체를 다시 전달해줍니다. 소멸 시점은 isInvalid() 메소드로 무효화 해주거나 지정한 유효 시간이 지나 자동으로 무효화 될 때입니다.

 

* 서블릿에서 HttpSession 객체 얻는 방법

HttpSession session = request.getSession();

 

 

 

 


 

 

4. JSP/서블릿마다 하나씩 생성되는 객체

  • config (javax.servlet.ServletConfig)

ServletConfig 객체는 web.xml 파일에서 특정 JSP/서블릿에 초기화 파라미터를 매핑시켜둔 값을 가지고 있는 객체입니다. JSP/서블릿이 메모리에 로드되는 시점에 실제 생성되는 객체인데, 동일 JSP/서블릿은 딱 하나의 ServletConfig 객체를 가집니다. 따라서 따로 다른 클래스나 JSP에 객체 또는 값을 전달하지 않는 한 해당 객체는 지정된 JSP/서블릿에서만 사용할 수 있는 딱 하나의 객체입니다. 같은 요청을 처리하는 동일 스레드에서도 다른 클래스나 JSP끼리 자동으로 공유되고 그러지 않습니다. 각자 하나씩 가지고 있습니다.

 

JSP나 서블릿이 수정돼서 다시 컴파일을 거친 후 메모리에 로드되면 이 객체도 다시 생성되는데, 어차피 web.xml 파일의 값은 컨테이너를 재가동 시켜야 다시 가져올 수 있으므로 초기화 파라미터 값은 변하지 않아 별 의미는 없습니다. 그냥 생명주기도 컨테이너의 생명주기와 같다고 생각하면 됩니다.

 

* 서블릿에서 ServletConfig 객체 얻는 방법 (상속받은 HttpServlet에 있는 메소드)

ServletConfig conf = this.getServletConfig();

 

 

 

 


 

 

5. 컨테이너 구동 시 생성되는 객체

  • application (javax.servlet.ServletContext)

ServletContext 객체는 어플리케이션(프로젝트 단위)이 딱 하나만 가지고 있는 객체입니다. 컨테이너에서 프로젝트를 구동시킬 때 프로젝트 단위로 딱 하나씩 만들어서 줍니다. 따라서 이 객체는 프로젝트 단위 내의 모든 JSP와 서블릿에서 공유되는 객체입니다. 

 

기본적으로는 컨테이너의 내외부 환경에 대한 정보를 가지고 있는데 Attribute 객체를 임의로 추가할 수 있어서 정보 공유의 수단으로 많이 사용됩니다.

 

 

* 서블릿에서 ServletContext 객체 얻는 방법 (ServletConfig 객체의 메소드로 얻을 수 있음)

		ServletConfig conf = this.getServletConfig();
		ServletContext application = conf.getServletContext();

 

 

 

 


 

 

※ 정리

 

  1. 하나의 요청을 처리하는 로직에서 JSP/서블릿끼리 정보를 주고받을 때는 Request 객체에 실어서 주고 받으면 됩니다. 물론 다른 방식으로 주고 받아도 됩니다.
  2. 하나의 브라우저에 대응하는 로직에서 JSP/서블릿끼리 정보를 주고받을 떄는 Session 객체에 실어서 주고 받으면 됩니다. 대표적으로 로그인 인증에 대한 정보가 있습니다.
  3. 소스코드 내에 하드코딩하기 애매한 정보들(DB 정보 등)이 있다면 특정 JSP/서블릿에 매핑한 초기화 파라미터를 지정해준 뒤, 해당 JSP/서블릿에서 config 객체를 사용해 가져오면 됩니다.
  4. 어플리케이션(프로젝트) 실행 내내 주고 받아야 할 정보가 있다면 application 객체에 실어서 주고 받으면 됩니다. 물론 하나의 요청을 처리하는 로직에서도 사용할 수 있겠지만 잘 못 쓰면 데이터가 꼬일 위험이 있습니다. 

 

728x90

댓글

💲 추천 글