백엔드 자바 웹 프로그래밍

2.3. 내장객체와 속성관리

들어가면서

이번 장에서는 내장객체에 대해 살펴본다. 내장객체는 jsp에서 선언없이 사용할 수 있는 객체를 말하며 JSP가 서블릿 형태로 변환되어 실행될 때 함께 동작 하므로 자바 웹 프로그램 개발 전반에 걸쳐 활용되고 있다.

내장객체 학습을 통해

등에 대해 배우고 컨트롤러 개발에 활용할 수 있다.



내장객체(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>");
...
}

코드에서 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 요청시 생성되며 주요 기능은 다음과 같다.

API 문서 ->

response

HTTP 응답을 처리하기 위한 객체

클라이언트에서 서버로 서블릿이나 jsp 요청시 생성되며 주요 기능은 다음과 같다.

API 문서 ->

session

세션 관련 작업을 처리하기 위한 객체

세션 관련 작업에 사용된다. 세션은 웹 서버 접속시 사용자마다 생성되는 객체로 일정시간 혹은 브라우저 종료 전까지 유지 된다.

API 문서 ->

application

웹 애플리케이션 정보를 참조하기 위한 객체

웹 애플리케이션이 시작될 때 함께 생성되며 현재 웹 애플리케이션의 상태나 서버 관련 정보 처리에 사용.

API 문서 ->

pageContext

다른 내장객체들에 접근하기 위한 객체

API 문서 ->



페이지간 정보 공유

WWW비연결형 구조의 HTTP를 사용하기 때문에 페이지 요청과 응답이 완료되면 연결이 유지 되지 않는다. 따라서 클라이언트가 다른 페이지를 요청할때 부가적인 정보가 없다면 서버는 클라이언트의 현재 상태를 알 수 없기 때문에 처음 접속한것과 마찬가지로 인식할 수 밖에 없다.

예를들어 쇼핑몰에서 여러페이지에 걸쳐 상품정보들이 흩어져 있는데 현재 페이지에서 선택된 상품에 대한 정보는 다른 페이지로 전달되지 않는다. 이러한 문제 해결을 위해서 일반적으로 사용하는 방법들은 다음과 같다.

URL rewriting

HTTP 의 Query String 을 이용하는 방식으로 URL에 파라미터를 추가해 서버로 요청하는 형식이다.

https://www.xxx.com/shop/productInfo?user=hong&p1=0112&p2=12021&sel=11786

쿠키는 클라이언트에 저장되는 작은 정보 이다. 서버의 요청(응답 헤더에 포함)에 의해 브라우저가 저장하게 되며 서버가 요청시 제공하는 형식이다.

서블릿 코드에서 쿠키를 저장하는 방법은 다음과 같다.

<%                                                                  
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로 할당된 영역에 접근하는 형식이다.

세션 관리의 효율을 위해 별도의 세션관리 데이터베이스를 사용하는 경우도 있다. 가장 일반적인 형태는 redis 라고 하는 인메모리 데이터베이스를 사용하는 것이다. redis 는 NoSQL 형태로 단순 key-value 구조의 데이터를 빠르게 처리할 수 있어 인기가 많다.


속성 관리

useBean 액션scope 에 사용되는 page, request, session, application 은 자바빈 을 생성하고 참조하기 위한 범위로 동일한 이름의 내장객체를 의미하기도 한다.

이들 내장객체들은 각각 생성 소멸 시기가 정해져 있고 서로 다른 html, jsp, 서블릿 간의 데이터 전달이나 공유를 위한 용도로 활용된다.

내장객체 생성 소멸 범위
page 현재 페이지 서블릿 실행 서블릿 소멸/재시작 현재 페이지
request 현재 페이지 요청 다른 페이지로 이동 현재 페이지, 포워딩의 경우 다음 페이지 까지
session 클라이언트가 서버에 접속할때 일정시간이 지나거나 브라우저 종료시 동일 클라이언트, 다른 페이지
application 웹 애플리케이션 시작 웹애플리케이션 종료 모든 클라이언트

주로 requestsession 을 활용하게 되며 모든 사용자가 공유 하거나 웹 애플리케이션 전체에서 필요로 하는 경우 application 을 사용할 수 있다.

이들 내장객체는 속성을 저장하고 참조하기 위한 다음 메서드가 공통적으로 제공 된다.

속성 저장: setAttribute(String name, Object o)
속성 참조: Object getAttribute(String name)

사용 예시

서블릿이나 jsp 로 컨트롤러를 구현시 다음과 같은 시나리오를 생각해 볼 수 있다.

로그인

로그인 후 세션을 이용해 사용자 이름을 저장하고 메인화면으로 이동하는 경우

  1. 클라이언트 로그인
  2. 컨트롤러는 request.getParameter() 를 통해 id, password 확인
  3. 로그인 정보가 맞을 경우 사용자 이름이나 기타 정보를 session 에 저장
  4. 메인 화면으로 리디렉션
// controller
session.setAttribute("uname", "홍길동");
response.sendRedirect("/main.jsp");

// main.jsp
<h2>${uname}</h2>

게시판 목록

데이터베이스 연동을 통해 List 형태의 데이터를 저장하고 jsp 에서 사용하는 경우

  1. 컨트롤러는 DB로 부터 게시판의 첫번째 페이지 데이터를 가지고 옴
  2. requestList 형태의 데이터 저장
  3. 목록 화면으로 포워딩
// controller
List<Member> mlist = dao.getMemberList();
request.setAttribute("mlist", mlist);
request.getRequestDispatcher("/mlist.jsp").forward(request, response);
// 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: 내장객체 종합 예제

실습-2: 내장객체를 이용한 속성관리 예제