이번 시간엔 기본 객체에 대하여 자세히 알아보려 한다. 또한, JSP 와 관련된 각 영역의 범위와 속성에 대해서도 알아볼 것이다. 하나씩 알아보자.
기본 객체
JSP에는 앞서 알아본 request 와 response 를 포함하여 총 9개의 기본 객체가 있다. 다음 표를 통하여 알아보자.
request |
클라이언트의 요청정보를 저장 |
response |
응답 정보를 저장 |
pageContext |
JSP 페이지 정보를 저장 |
session |
HTTP 세션 정보를 저장 |
application |
웹 어플리케이션 정보를 저장 |
out |
생성 결과를 출력 할 때 사용되는 출력스트림 |
config |
JSP 페이지 설정 정보 저장 |
page |
JSP 페이지를 구현한 자바 클래스 인스턴스 |
exception |
예외 객체, 에러 페이지에 사용 |
이 중에서 exception 기본 객체는 에러 페이지에서만 사용이 가능하며, 나머지는 JSP 페이지에서 모두 사용이 가능하다.
이번 시간엔 out, pageContext, application 기본 객체에 대해 알아보고 exception 과 session 에 대해서는 좀 더 이후에 알아보자.
* page, config 기본 객체는 사용하는 경우가 거의 없기 때문에 따로 설명하지 않고 필요한 경우가 생기면 그 때 추가로 설명하도록 하겠다.
out 기본 객체
웹 브라우저에 데이터를 전송하는 출력 스트림이다.
JSP 페이지가 생성하는 모든 내용은 out 기본 객체를 통하여 전송된다. JSP 페이지 내에서 사용되는 모든 요소들(HTML 코드, 텍스트, 표현식 등)이 out 기본 객체에 그대로 전달된다.
다음과 같이 스트립트릿에서도 사용이 가능하다.
* 실제로 out 기본 객체를 이용하여 출력하는 경우는 거의 없고 표현식을 사용하는 것이 더 좋다.
if~else 문처럼 표현식과 스크립트릿이 복잡하게 섞여있을 때 사용하여 간단하게 만들어 주는 경우가 아니라면 사용하지 않는 것이 좋다.
- out 기본 객체의 출력 메서드
: 다음과 같이 세 가지가 있다.
* print() : 데이터 출력.
* println() : 데이터 출력하고 줄바꿈.
* newLine() : 줄바꿈.
- out 기본 객체와 버퍼의 관계
이전 시간에 알아본 버퍼의 속성을 지정하여 사용하면 out 기본 객체가 내부적으로 사용하는 버퍼의 크기도 같은 크기로 지정이 된다.
▶ <%@ page buffer="8kb"%>
위와 같이 버퍼의 속성을 지정할 경우 out 기본 객체의 내부적 버퍼의 크기로 8kb 가 된다는 뜻이다.
또한 out 기본 객체는 버퍼와 관련된 메서드를 가지고 있는데 다음 표를 통해 알아보자.
getBufferSize() |
버퍼의 크기 / 리턴 타입 : int |
getRemaining() |
버퍼의 남은 크기 / 리턴 타입 : int |
clear() |
버퍼의 내용을 비운다. (버퍼가 이미 비어있을 경우 IOException 발생) / 리턴 타입 : void |
clearBuffer() |
버퍼의 내용을 비운다. (clear() 메서드와 달리 IOException 발생 안함) / 리턴 타입 : void |
flush() |
버퍼를 비운다. / 리턴 타입 : void |
isAutoFlush() |
버퍼가 다 차서 자동으로 플러시 할 경우 true를 리턴한다. / 리턴 타입 : boolean (page 디렉티브의 autoFlush 속성값을 받아온다.) |
다음 예제를 통해 확인해 보자.
버퍼의 크기와 남은 버퍼의 크기, autoFlush의 여부가 차례대로 출력된 것을 확인할 수 있다.
pageContext 기본 객체
하나의 JSP 와 1:1로 매핑되는 객체로서, 다음과 같은 기능을 제공한다.
* 다른 기본 객체 구하기
* 속성 처리하기(Attribute)
* 페이지의 흐름 제어하기
* 에러 데이터 구하기
pageContext 기본 객체는 JSP 에서 직접적으로 사용하기 보단, 커스텀 태그에서 많이 사용된다. 좀 더 발전된 JSP 프로그래밍을 하기 위해선 필요하므로 잘 익혀두자.
- 기본 객체 접근 메서드
: pageContext는 JSP 기본 객체에 접근 할 수 있는 메서드를 제공한다. 다음 표를 보자.
getRequest() |
request 기본 객체를 구한다. / 리턴 타입 : ServletRequest |
getResponse() |
response 기본 객체를 구한다. / 리턴 타입 : ServletResponse |
getSession() |
session 기본 객체를 구한다. / 리턴 타입 : HttpSession |
getServletContext() |
application 기본 객체를 구한다. / 리턴 타입 : ServletContext |
getServletConfig() |
config 기본 객체를 구한다. / 리턴 타입 : ServletConfig |
getOut() |
out 기본 객체를 구한다. / 리턴 타입 : JspWriter |
getException() |
exception 기본 객체를 구한다. / 리턴 타입 : Exception |
getPage() |
page 기본 객체를 구한다. / 리턴 타입 : Object |
이 중에서 getException() 메서드는 에러 페이지인 경우에만 해당한다.
* getRequest(), getResponse() 메서드는 사용할 때 알맞게 형변환을 해줘야 한다.
getRequest() 메서드의 리턴 타입은 ServletRequest 인데, HTTP 요청을 처리하는 경우에는
HttpServletRequest 로 형변환을 해줘야 한다.
▶ HttpServletRequest httpRequest = (HttpServletRequest) pageContext.getRequest();
getResponse() 메서드의 경우도 마찬가지이다.
예제를 통해 알아보자.
request 기본 객체와 pageContext.getRequest() 의 리턴 값이 같고 pageContext.getOut() 메서드를 이용한 출력을 확인할 수 있다.
application 기본 객체
특정 웹 어플리케이션에 포함된 모든 JSP 페이지는 하나의 application 기본 객체를 공유하게 된다.
웹 어플리케이션 전반에 걸쳐서 사용되는 정보를 담고 있으며, 초기 설정 정보를 읽어오거나, 서버 정보를 읽고 제공되는 자원을 읽어올 수 있다.
- 웹 어플리케이션 초기화 파라미터 읽기
: 서블릿 규약은 웹 어플리케이션 전체에 걸쳐서 사용할 수 있는 초기화 파라미터를 제공한다.
초기화 파라미터는 주로 웹 어플리케이션의 초기화 작업에 필요한 설정 정보를 저장하기 위해 사용된다. DB와 연결된 설정 파일의 경로나, 로깅 설정파일 또는 주요 속성 정보를 담고 있는 파일의 경로 등을 지정할 때 사용한다.
초기화 파라미터는 web.xml 파일에 <context-param> 태그를 추가하여 다음과 같이 사용할 수 있다.
▶ <context-param>
<description>파라미터 설명(필수아님)</description>
<param-name>파라미터 이름</param-name>
<param-value>파라미터 값</param-value>
</context-param>
application 기본 객체는 초기화 파라미터를 읽어올 수 있도록 다음과 같은 메서드를 제공한다.
getInitParameter(String name) |
이름이 name인 초기화 파라미터의 값을 읽어온다. 존재하지 않을 경우 null 반환 / 리턴타입 : String |
getInitParameterNames() |
초기화 파라미터 이름의 목록 반환 / 리턴타입 : Enumeration |
* 톰캣은 web.xml 파일이 변경될 경우 웹 어플리케이션을 다시 시작하는 웹 컨테이너 중 하나이다. 하지만 수정된 web.xml 파일을 자동으로 읽어오지 않을 경우, 웹 컨테이너를 다시 시작해줘야 변경된 내용이 저장된다.
- 서버 정보 읽기
: 현재 사용중인 웹 컨테이너에 대한 정보를 읽어오는 메서드를 제공한다. 다음과 같다.
getServerInfo() |
서버 정보를 구한다 / 리턴 타입 : String |
getMajorVersion() |
서버가 지원하는 서블릿 규약의 메이저 버전을 구한다.(버전의 정수 부분) / 리턴 타입 : String |
getMinorVersion() |
서버가 지원하는 서블릿 규약의 마이너 버전을 구한다.(버전의 소수 부분) / 리턴 타입 : String |
예제를 통해 알아보자.
서블릿 규약의 메이저와 마이너 버전이 2와 5로 출력됬는데 서블릿 2.5규약을 지원한다는 것을 알 수 있다.
- 로그 메시지 기록하기
: 웹 컨테이너가 사용하는 로그 파일에 로그 메시지를 기록하는 메서드이다.
log(String msg) |
로그 메시지 msg를 기록한다. / 리턴 타입 : void |
log(String msg, Throwable throwable) |
로그 메시지와 예외 정보를 기록한다. / 리턴타입 : void |
또한, JSP가 자체적으로 제공하는 log() 메서드도 있다. 예제를 통해 알아보자.
JSP가 제공하는 log() 메서드의 경우 'jsp:' 라는 문구가 추가된 것을 확인할 수 있다.
* 로그 메시지가 기록되는 파일은 웹 컨테이너에 따라 다르다. 또한 application.log() 메서드를 사용 할 때와 JSP의 log() 메서드를 사용할 때 기록되는 로그 메시지의 포맷은 사용하는 웹 컨테이너에 따라 달라질 수 있다.
- 웹 어플리케이션 자원구하기
: JSP 는 절대 경로를 사용하여 자원을 읽어올 수 있지만 변경할 JSP 코드가 많을 경우엔 유지 보수에 어려움이 발생한다. 이런 문제를 해결할 수 있도록 자원에 접근할 수 있는 메서드를 제공한다.
getRealPath(String path) |
지정한 경로에 해당하는 자원의 경로를 리턴. / 리턴 타입 : String |
getResource(String path) |
지정한 경로에 해당하는 자원의 URL 객체를 리턴. / 리턴 타입 : java.net.URL |
getResourceAsStream(String path) |
지정한 경로에 해당하는 자원으로부터 데이터를 읽어올 수 있는 InputStream을 리턴한다. / 리턴 타입 : java.io.InputStream |
예제를 통해 알아보자.
URL 객체를 리턴하는 applicatin.getResource() 메서드를 사용해서 같은 결과를 출력할 수 있는데 위의 소스에서 다음의 두 가지를 수정해 주면 된다.
▶ <%@ page import="java.net.URL"%> 추가
▶ Line 24 를 다음과 같이 수정
URL url = application.getResource(resourcePath);
br = new BufferedReader(new InputStreamReader(url.openStream()));
* 웹 어플리케이션의 디렉터리 경로가 변경되더라도 application 기본 객체를 사용하면 웹 어플리케이션 내에서의 경로를 변경할 필요가 없다.
JSP 기본 객체와 영역
웹 어플리케이션은 다음과 같이 4개의 영역(Scope)를 가지고 있다.
* PAGE 영역 : 하나의 JSP 를 처리할 경우 사용되는 영역. / pageContext 기본객체
* REQUEST 영역 : 하나의 HTTP 요청을 처리할 때 사용되는 영역 / request 기본객체
(URL이 넘어가는 경우 등 페이지의 변화가 일어날 때)
* SESSION 영역 : 하나의 웹 브라우저와 관련된 영역 / session 기본객체
* APPLICATION 영역 : 하나의 웹 어플리케이션과 관련된 영역 / application 기본객체
* PAGE 와 REQUEST 영역의 차이점
PAGE 영역은 하나의 JSP 페이지만을 포함한다. 반면에 REQUEST 영역은 하나의 요청을 처리하는 데 사용되는 모든 JSP 페이지를 포함한다.
각 영역에 대해서 기본 객체가 어떻게 매핑되는지 보여주는 그림이다.
- PAGE 영역
: 웹 브라우저의 요청을 처리하는 JSP 페이지는 새로운 PAGE 영역에 해당하며 pageContext 기본 객체를 가지게 된다.
- REQUEST 영역
: 웹 브라우저의 요청은 request 기본 객체와 관련된다. 요청을 할 때마다 새로운 request 기본 객체가 생성된다.
- SESSION 영역
: 서로 다른 두 개의 웹 브라우저가 같은 JSP 페이지를 사용해도 두 웹 브라우저는 서로 다른 session 영역에 포함되며, 다른 session 기본 객체를 사용한다.
- APPLICATION 영역
: 모든 JSP는 한 개의 application 기본 객체를 공유하고, application 영역에 포함된다.
기본 객체의 속성 사용하기
4 개의 기본 객체들이 가지고 있는 속성은 각각의 기본 객체가 존재하는 동안에 사용이 가능하며, JSP 사이에서 정보를 주고 받거나 공유하기 위한 목적으로 사용된다.
속성은 <속성이름, 속성값> 의 형태를 가지며, 4개의 기본 객체는 서로 다른 이름을 가진 속성을 여러 개 포함할 수 있다.
다음 메서드를 이용하여 각 객체의 속성을 추가, 변경, 삭제를 할 수 있다.
setAttribute(String name, Object value) |
이름이 name인 속성의 값을 value로 지정한다. / 리턴 타입 : void |
getAttribute(String name) |
이름이 name인 속성의 값을 구한다. 지정한 이름의 속성이 존재하지 않을 경우 null 반환 / 리턴 타입 : Object |
removeAttribute(String name) |
이름이 name인 속성을 삭제한다. / 리턴 타입 : void |
getAttributeNames() |
속성의 이름 목록을 구한다. (pageContext 기본 객체는 제공 안 함) / 리턴 타입 : java.util.Enumeration |
기본 객체에 속성값을 추가해주는 JSP 페이지를 예제를 통해 살펴보자.
다음과 같은 폼을 가지는 페이지와 파라미터를 받아 속성값을 추가해주는 페이지를 만들어준다.
페이지를 실행해주고 폼을 입력해주면 다음과 같은 화면이 출력된다.
또한, getAttribute() 와 getAttributeNames() 메서드를 사용하여 application 기본 객체에 저장되어 있는 모든 속성의 이름과 값을 출력할 수 있다.
* 유지 보수 과정에서 다른 서버로 교체하게 될 경우 톰캣이 제공하는 속성을 사용한 JSP 코드를 변경해 주어야 한다. 또한, 같은 서버라도 버전에 따라 속성이 변경될 수 있다. 따라서 특정 WAS 에서만 제공하는 속성은 사용하지 않는 것이 좋다.
- 속성의 값 타입
: 속성값은 기본 데이터 타입을 제외한 나머지 모든 클래스 타입이 올 수 있다. 예를 들면 다음과 같다.
▶ session.setAttribute("session_start", new java.util.Date());
▶ session.setAttribute("memberid", "freestrokes");
▶ application.setAttribute("application_temp", new File("c:\temp\test.txt"));
이렇게 저장한 속성값들을 읽어올 때는 getAttribute() 메서드를 사용하는데 타입에 맞게 형변환을 해주어야 한다.
▶ Date date = (Date)session.getAttribute("session_start");
▶ String memberID = (String)session.getAttribute("memberid");
▶ File tempDir = (File)application.getAttribute("application_temp");
* 속성값으로 기본 데이터 타입을 설정 할 경우에는 래퍼 타입을 사용해야 한다.
- 속성의 활용 방법
: 각 기본 객체별로 속성의 쓰임새가 다른데 다음 표를 통해 알아보자.
pageContext |
하나의 JSP 페이지 내에서 공유될 값을 저장. 주로 커스텀 태그에서 새로운 변수를 추가할 때 사용. |
request |
모든 JSP 페이지에서 공유될 값을 저장. 주로 하나의 요청을 처리하는 데 사용되는 페이지 사이에서 정보를 전달하기 위해 사용. |
session |
한 사용자와 관련된 정보를 JSP 페이지 들이 공유하기 위해서 사용. (로그인 정보) |
application |
모든 사용자와 관련해서 공유할 정보를 저장. 임시 디렉터리 경로와 같은 웹 어플리케 이션의 설정 정보를 저장. |
다음과 같이 알아두자.
* request / session 기본 객체는 속성을 저장하기 위해 가장 많이 사용.
▶ request 기본 객체는 MVC(Model-View-Controller) 패턴에 기반을 두고 사용.
▶ session 기본 객체는 로그인, 로그아웃과 같은 사용자의 인증 정보를 저장할 때 사용.
좀 더 세부적인 내용에 대해서는 이후에 포스팅을 이어나가면서 자세하게 설명하도록 하겠다.
각 객체별로 메서드 명도 서로 비슷하고 기능도 비슷한 경우가 많기 때문에 잘 구별해서 알아둬야 하겠다. 이상으로 포스팅을 마친다.