2.3. 내장객체와 속성관리
들어가면서
이번 장에서는 내장객체에 대해 살펴본다. 내장객체는 jsp에서 선언없이 사용할 수 있는 객체를 말하며 JSP가 서블릿 형태로 변환되어 실행될 때 함께 동작 하므로 자바 웹 프로그램 개발 전반에 걸쳐 활용되고 있다.
내장객체 학습을 통해
- 내장객체 종류와 역할
- 클라이언트 요청과 응답 처리
- scope 내장객체의 속성 관리
등에 대해 배우고 컨트롤러 개발에 활용할 수 있다.
내장객체(Implicit Object) 개요
내장객체는 jsp가 서블릿 코드로 변환될 때 참조할 수 있는 객체들로 jsp의 스크립트릿 등에서 별도의 선언없이 사용할 수 있는 자바 객체를 말한다.
예를들어 입력양식을 통해 서버로 전달된 데이터를 받아 오는 jsp 코드는 다음과 같다.
<h2><%= request.getParameter("uname") %></h2>
...
이때 사용된 request 는 내장객체중 하나로 별도의 선언없이 사용하고 있다. 서블릿의 doGet(), doPost()
메서드에도 request, response 가 인자로 전달되며 jsp 파일의 경우 서블릿 코드로 변환될때 모든 내용이 _jspService()
메서드 안에 위치하게 되는데 이때 _jspService()
의 인자에도 request, response 가 전달 된다.
public void _jspService(final javax.servlet.http.HttpServletRequest request,
final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
...
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
...
out.write("<html><head>.....");
out.write("<h2>"+request.getParameter("uname")+"</h2>");
...
}
- request 는 _jspService() 의 인자.
- our.write 에서 사용되는 request.getParameter()는 인자로 전달된 request를 사용하는 것.
코드에서 out.write()
부분에 jsp 파일의 내용들이 라인 단위로 위치하게 되고 _jspService()
의 인자와 지역변수들은 코드 구조상 jsp 영역에서 참조 가능한 형태가 되는 것이다. 이들 참조 변수들과 exception 을 포함한 9개의 객체를 JSP 내장객체라고 부른다.
내장객체 종류
내장객체는 기본적으로 다음 표의 9개를 말한다. 이들은 웹 애플리케이션 운영을 위해 다양한 목적에서 만들어진 것으로 JSP만을 위해 개발된것이 아니라 대부분 원래 서블릿에서 사용되던 클래스들이다(javax.servlet.*
패키지 사용). 각각의 내장객체에 대한 자세한 사항은 API 문서를 참조하기 바란다.
내장객체 | 타입 | 주요 제공 기능 |
---|---|---|
out | javax.servlet.jsp.JspWriter | 클라이언트(웹브라우저)로 출력 전달 |
request | javax.servlet.http.HttpServletRequest | HTTP 요청 처리 |
response | javax.servlet.http.HttpServletResponse | HTTP 응답 처리 |
config | javax.servlet.ServletConfig | 서블릿 관련 정보 처리 |
application | javax.servlet.ServletContext | 웹애플리케이션 정보 처리 |
session | javax.servlet.http.HttpSession | 세션 정보 처리 |
pageContext | javax.servlet.jsp.PageContext | 다른 내장 객체의 참조나 forward에 사용 |
page | java.lang.Object | 현재 JSP 문서 정보 처리, 현재 페이지의 서블릿 객체를 가리킴 |
exception | java.lang.Throwable | 예외 처리 |
여러 차례 언급한것 처럼 이들 내장 객체를 일반적인 JSP 파일의 스크립트릿에서 사용하는 것은 바람직 하지 않으며 컨트롤러를 JSP로 형태로 구현하는 경우에는 유용하게 사용할 수 있다.
만일 JSP 를 뷰 용도로만 사용한다면 직접적으로 내장객체를 사용할 일은 없겠지만 서블릿의 고급 활용을 위해서라면 관련 내용은 꼭 알아두어야 한다.
request
HTTP 요청을 처리하기 위한 객체
클라이언트에서 서버로 서블릿이나 jsp 요청시 생성되며 주요 기능은 다음과 같다.
- 웹 서버의 기본적인 사용자 인증
- 폼 입력 데이터 접근
- 요청 URL 을 비롯한 경로정보
- HTTP 헤더 정보 참조
- 속성 저장 및 참조
response
HTTP 응답을 처리하기 위한 객체
클라이언트에서 서버로 서블릿이나 jsp 요청시 생성되며 주요 기능은 다음과 같다.
- 쿠키 설정
- 응답 헤더 설정 및 참조
- 상태정보 및 에러 전달
- 페이지 리디렉션(다른 페이지로 이동)
session
세션 관련 작업을 처리하기 위한 객체
세션 관련 작업에 사용된다. 세션은 웹 서버 접속시 사용자마다 생성되는 객체로 일정시간 혹은 브라우저 종료 전까지 유지 된다.
- 세션 정보 참조
- 세션 유효 시간 설정
- 속성 저장 및 참조
application
웹 애플리케이션 정보를 참조하기 위한 객체
웹 애플리케이션이 시작될 때 함께 생성되며 현재 웹 애플리케이션의 상태나 서버 관련 정보 처리에 사용.
- 서버 버전 정보
- 서버 로그 생성
- 서블릿, 필터, 리스너 등의 등록
- 속성 저장 및 참조
pageContext
다른 내장객체들에 접근하기 위한 객체
- request, response, session, application 등의 다른 내장객체에 접근
- 다른 jsp의 실행결과를 현재 페이지에 포함시키거나 다른 페이지로 포워딩
페이지간 정보 공유
WWW은 비연결형 구조의 HTTP를 사용하기 때문에 페이지 요청과 응답이 완료되면 연결이 유지 되지 않는다. 따라서 클라이언트가 다른 페이지를 요청할때 부가적인 정보가 없다면 서버는 클라이언트의 현재 상태를 알 수 없기 때문에 처음 접속한것과 마찬가지로 인식할 수 밖에 없다.
예를들어 쇼핑몰에서 여러페이지에 걸쳐 상품정보들이 흩어져 있는데 현재 페이지에서 선택된 상품에 대한 정보는 다른 페이지로 전달되지 않는다. 이러한 문제 해결을 위해서 일반적으로 사용하는 방법들은 다음과 같다.
URL rewriting
HTTP 의 Query String 을 이용하는 방식으로 URL에 파라미터를 추가해 서버로 요청하는 형식이다.
https://www.xxx.com/shop/productInfo?user=hong&p1=0112&p2=12021&sel=11786
- productInfo라는 서버 요청(jsp 혹은 서블릿)
- 현재 상품 정보를 보여주면서 사용자 정보와 지금까지 선택된 상품정보를 모두 URL에 포함
- 정보 유지를 위해 파라미터를 매 페이지 마다 확인하고 계속 추가해주어야 하며 복잡한 정보 유지는 어렵다는 문제가 있다
Cookie
쿠키는 클라이언트에 저장되는 작은 정보 이다. 서버의 요청(응답 헤더에 포함)에 의해 브라우저가 저장하게 되며 서버가 요청시 제공하는 형식이다.
- 파일로 클라이언트의 컴퓨터에 저장되는 방식이며 보안상 문제가 있을 수 있다.
- 광고 혹은 기타의 목적으로 사용자의 이용 행태 추적에 이용될 수 있으며 이러한 목적의 경우 사용자 정보 활용 동의 필요.
- 연속되는 페이지 이동에 대한 정보 저장 보다는 재방문등의 확인 용도로 많이 사용.
name=value
형식이며 유효기간, 요청경로, 도메인지정등 부가 속성을 포함- 주로 자바스크립트를 통해 처리 하지만
HttpOnly
설정으로 서버에서만 사용할 수 있도록 설정 가능.
서블릿 코드에서 쿠키를 저장하는 방법은 다음과 같다.
<%
response.addCookie(new Cookie("name", "hong"));
response.addCookie(new Cookie("tel", "010-1234-12345"));
response.addCookie(new Cookie("email", "hong@korea.com"));
%>
위의 코드는 아래와 같은 HTTP 응답으로 클라이언트에 전달 된다.
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: name=hong
Set-Cookie: tel=010-1234-1234
Set-Cookie: email=hong@korea.com
Content-Type: text/html;charset=utf-8
Content-Length: 160
Date: Sun, 13 Sep 2020 11:11:13 GMT
...HTTP BODY...
Session
세션은 클라이언트가 웹애플리케이션 서버에 접속할 때 서버쪽에 생성되는 공간으로 내부적으로는 세션ID를 통해 참조 된다. 즉, 브라우저는 서버에 접속할때 발급받은 세션ID를 기억하고 서버는 해당 세션ID로 할당된 영역에 접근하는 형식이다.
- 세션 유효시간이나 브라우저 종료전까지 유지 되므로 서로 다른 페이지에서도 정보공유 가능
- 로그인 유지, 장바구니, 컨트롤러 구현등 다양하게 사용됨
- 사용자마다 생성되는 공간으로 동시에 많은 사용자가 세션을 통해 대량의 데이터를 관리한다면 충분한 메모리를 비롯한 세션 관리 대책이 필요함.
속성 관리
useBean 액션의 scope
에 사용되는 page, request, session, application
은 자바빈 을 생성하고 참조하기 위한 범위로 동일한 이름의 내장객체를 의미하기도 한다.
이들 내장객체들은 각각 생성 소멸 시기가 정해져 있고 서로 다른 html, jsp, 서블릿 간의 데이터 전달이나 공유를 위한 용도로 활용된다.
내장객체 | 생성 | 소멸 | 범위 |
---|---|---|---|
page | 현재 페이지 서블릿 실행 | 서블릿 소멸/재시작 | 현재 페이지 |
request | 현재 페이지 요청 | 다른 페이지로 이동 | 현재 페이지, 포워딩의 경우 다음 페이지 까지 |
session | 클라이언트가 서버에 접속할때 | 일정시간이 지나거나 브라우저 종료시 | 동일 클라이언트, 다른 페이지 |
application | 웹 애플리케이션 시작 | 웹애플리케이션 종료 | 모든 클라이언트 |
주로 request
와 session
을 활용하게 되며 모든 사용자가 공유 하거나 웹 애플리케이션 전체에서 필요로 하는 경우 application
을 사용할 수 있다.
이들 내장객체는 속성을 저장하고 참조하기 위한 다음 메서드가 공통적으로 제공 된다.
속성 저장: setAttribute(String name, Object o)
속성 참조: Object getAttribute(String name)
- name 은 속성을 저장하고 참조하기 위한 키값
- 속성은 Object 타입으로 모든 자바 클래스 타입이 가능
- getAttribute() 의 리턴은 Object 이므로 적절한 형변환 필요
사용 예시
서블릿이나 jsp 로 컨트롤러를 구현시 다음과 같은 시나리오를 생각해 볼 수 있다.
로그인
로그인 후 세션을 이용해 사용자 이름을 저장하고 메인화면으로 이동하는 경우
- 클라이언트 로그인
- 컨트롤러는
request.getParameter()
를 통해 id, password 확인 - 로그인 정보가 맞을 경우 사용자 이름이나 기타 정보를
session
에 저장 - 메인 화면으로 리디렉션
// controller
session.setAttribute("uname", "홍길동");
response.sendRedirect("/main.jsp");
// main.jsp
<h2>${uname}</h2>
게시판 목록
데이터베이스 연동을 통해 List 형태의 데이터를 저장하고 jsp 에서 사용하는 경우
- 컨트롤러는 DB로 부터 게시판의 첫번째 페이지 데이터를 가지고 옴
request
에List
형태의 데이터 저장- 목록 화면으로 포워딩
// controller
List<Member> mlist = dao.getMemberList();
request.setAttribute("mlist", mlist);
request.getRequestDispatcher("/mlist.jsp").forward(request, response);
- session 과 달리 request에 저장된 데이터는 페이지 리디렉션을 이용해 전환시 소멸 되므로 포워딩 방식을 사용해야 함.
// mlist.jsp
<c:forEach items="${mlist}" var="m">
<tr>
<td>${m.id}</td>
<td>${m.name}</td>
<td>${m.tel}</td>
<td>${m.birth}</td>
</tr>
</c:forEach>
실습-1: 내장객체 종합 예제
회원가입 양식을 처리하는 jsp 구현을 통해 request, response, application 내장객체의 활용을 살펴본다.
실습-2: 내장객체를 이용한 속성관리 예제
로그인에서 부터 상품 선택과 session 의 속성관리 기능을 이용한 장바구니 기능 구현을 살펴 본다.