메뉴 건너뛰기

Dev tips

JSP 내부 객체와 액션 태그

taknim 2005.10.26 18:57 조회 수 : 8185 추천:1707

이번 강의는 JSP 내부 객체와 액션 태그에 대해 알아보도록 하죠!! 자,, 그럼 일단 앞의 강의를 다시 한번 생각해 보고 본 강의에 임하겠습니다. JSP도 JAVA라는 객체 지향적 언어를 이용한 스크립트 언어라고 생각합시다. 그럼 일단 JSP가 스크립틀릿 형식으로 동작하더라도 내부적으로는 JAVA의 객체와 전혀 상관없는 것이 아니지요. 앞장에서 공부한 바와 같이, JSP란 이전의 Servlet을 이용한 웹 애플리케이션 개발이 JAVA를 모르는 사람들에게는 너무 어려워서 기존의 스크립트 언어와 비슷하게 개발된 것이지요. 본론을 얘기하자면 Servlet에서 사용되는 객체들을 JSP에서는 쉽게 생성하여 사용할 수 있도록 JSP 컨테이너 회사들이 미리 만들어 놓았다는 것입니다. 물론 지금 얘기한 것을 이해하지 못하 더라도 기존의 ASP나 PHP처럼 사용하여 웹애플리케이션을 구축할 수 있습니다. 하지만 안다고 나쁠 건 없죠.(사실은 알아야만 한답니다.^^ )


1.내부 객체

<표 4_1> HTTP 애플리케이션을 위한 JSP 내부 객체와 API들
객체
class or interface
설명
  page   javax.servlet.jsp.HttpJspPage   페이지의 인스턴스
  config   javax.servlet.ServletConfig   서블릿 구성테이터
  request   javax.servlet.http.HttpServletRequest   요청 데이터(매개변수를 포함)
  response   javax.servlet.http.HttpServletResponse   요청 데이터
  out   javax.servlet.jsp.JspWriter   페이지 컨텐트 출력용 스트림
  session   javax.servlet.http.HttpSession   사용자마다의 세션데이터
  application   javax.servlet.ServletContext   모든 애플리케이션 페이지가 공유하는 데이터
  pageContext   javax.servlet.jsp.PageContext   페이지가 처리되는 시점에서의 외부 환경(context) 데이터
  exception   java.lang.Throwable   처리되지 않은 에러나 예외
<표 4_2> 객체의 속성을 저장하고 읽어내는 공통 메소드
Method
설명
  setAttribute(key, value)   주어진 key(이름 등)에 속성값을 연결한다.
  getAttributeNames()   현재의 세션에 관련된 모든 속성의 이름을 뽑아낸다.
  getAttribute(key)   주어지 key에 연결된 속성값을 얻어낸다.
  removeAttribute(key)   주어진 key에 연결된 속성값을 제거한다.

 

1.1 서블릿 관련 내부 객체(Servlet-related Object)
    -JSP를 Servlet으로 구현하는 객체입니다.

▶page 내부 객체
JSP 스크립팅 언어가 JAVA일 때는 거의 사용되지 않습니다.
예)pageTest.jsp
<%@ page info=페이지에 대한 정보를 담을 수 있습니다 contentType=text/html;charset=euc-kr%>
페이지 정보:
<%= ((javax.servlet.jsp.HttpJspPage)page).getServletInfo() %>


이렇게 하면 요 밑처럼 브라우저에서 보여지겠지요.


▶config 내부 객체(javax.servlet.ServletConfig)매개변수이름과 값(value)로 저장할 수 있습니다.

-getInitParameterNames() : 요렇게 매개변수 이름을 불러올 수 있답니다.
-getInitParameter(name) : name으로 저장된 매개변수의 값을 가져 온답니다.

예) <%! static private DbConnectionPool pool = null; public void jspInit(){ if(pool == null){ String userName = config.getInitParameter(interjigi); String password = config.getInitParameter(happy); pool = DbConnectionPool.getPool(this,username,password); } } %>
위의 예제는 앞으로 배울 db 연결에 대한 내용입니다. 지금은 모르셔도 되니까 다른 내용은 신경쓰지 마시고 getInitParameter()를 이용하여 어떻게 매개변수의 값을 불러오는지만 보시고 넘어갑시다.
참고로 위의 예제는 일정부분만 추출한 코드이므로 test하지 마세요.(~~아마 error만 생길 걸요~~)
좀더 설명하자면 jsp에서가 아닌 servlet 파일을 작성할 때는 많이 쓰이는 객체지요.
컨테이너가 생성해 놓은 해당 Servlet의 정보를 가지고 있는 객체이므로 config 객체의 정보를 이용하여 애플리케이션을제어하는 것이 가능하답니다.
앞으로 배울 내용이니 한번 듣고 흘리세요...

1.2 입력/출력용 내부 객체(Input/Output object)

▶request 내부 객체
--아주 중요하고 자주 쓰이는 객체이므로 잘 알아두셔야 함다.^^

request 객체는 현재 jsp 페이지 처리를 시작하게 한 요청정보를 가지고 있습니다.
물론 javax.servlet.ServletRequest 인터페이스를 구현해야 합니다.
여기서 ServletRequest 인터페이스는 http,ftp 등의 모든 프로토콜에 대한 request class의 인터페이스입니다.
우린 주로 http 프로토콜만을 사용하니까 javax.servlet.ServletRequest 인터페이스의 sub class인 javax.servlet.http.HttpServletRequest class를 구현해 사용하면 되겠지요.
혹시 인터페이스가 뭐야 하시는 분은 없겠지요...
뭐 모르셔도 되기까 그냥 넘어가도록 합시다.

1) 표 4.2에 있는 메소드들은 모든 내부 객체에서 사용되는 메소드

2) 요청 매개변수를 읽어 내는 메소드

3) HTTP 헤더를 읽어내는 메소드

4) 기타 메소드

<표 4_3> 요청 매개변수 엑세스에 사용되는 메소드.

Method
설명
  setParameterNames()   모든 요청 매개변수의 이름을 반환한다.
  getParameter(name)   하나의 요청 매개변수의 첫째 값을 반환한다.
  getParameterValues(name)   하나의 요청 매개변수에 대한 모든 값을 뽑아낸다.

 

<표 4_4> 요청 헤더 엑세스에 사용되는 메소드.

Method
설명
  getHeaderNames()   들어온 요청에 대한 모든 헤더의 이름을 반환한다.
  getHeader(name)   하나의 요청 헤더 값을 문자열로 반환한다.
  getHeaders(name)   하나의 요청 헤더에 대한 모든 값을 반환한다.
  getIntHeader(name)   하나의 요청 헤더 값을 정수로 반환한다.
  getDateHeader(name)   하나의 요청 헤더 날짜 값을 반환한다.
  geCookies()   들어온 요청에 대한 모든 쿠키를 뽑아 낸다.

 

1)모든 내부 객체에서 사용되는 메소드.

 - setAttribute(key, value) : String key에 Object value를 연결한다.
 - getAttribute(key) : String key에 연결된 Object value를 반환한다.
 - java.util.Enumeration getAttributeNames() : 현재의 세션에 관련된 모든 속성의 이름을 뽑아낸다.
 - removeAttribute(key) : String key에 연결된 Object value를 제거한다.

예)

   attributeTest.jsp


<%@ page contentType=text/html;charset=euc-kr %>
<%
String AttributeTest1 = It is test;
Integer AttributeTest2 = new Integer(9);
request.setAttribute(test1,AttributeTest1);
request.setAttribute(test2,AttributeTest2);
%>



AttributeTest입니다.



<%
String Attribute1 = (String)request.getAttribute(test1);
String Attribute2 = ((Integer)request.getAttribute(test2)).toString();
java.util.Enumeration er = request.getAttributeNames();
out.println(AttributeTest1 : + Attribute1);
out.println(

);
out.println(AttributeTest2 : + Attribute2);
out.println(

);
while(er.hasMoreElements()){
String attributeName = (String)er.nextElement();
out.println(attributeName : + attributeName);
out.println(

);
}
%>


자, 서버 디렉토리에 저장하셨나요?
그럼 브라우저에 다음과 같은 화면이 출력되겠죠.

2)요청 매개변수를 읽어내는 메소드

- java.util.Enumeration getParameterNames() : 모든 요청 매개변수의 이름을 Enumeration type으로 반환한다.
- String getParameter(String name) : String name에 연결된 요청매개변수의 String value를 반환한다.
   requestTest.htm


request Test....



Test

   requestTest.jsp

<%@ page contentType=text/html;charset=euc-kr %>
<%
java.util.Enumeration er = request.getParameterNames();
while(er.hasMoreElements()){
String requestParamName = (String)er.nextElement();
String requestParamValue = request.getParameter(requestParamName);
out.println(requestParamName);
out.println( : );
out.println(requestParamValue);
out.println(

);
}
%>

위의 코드를 보시면 알겠지만 일단 requestTest.htm에서 http request가 생성이 되지요. 사용자가 브라우저를 통해 requestTest.jsp를 요청하고 매개이름을 interjigi, zezz, Jsys 로 하고 value는 각각 good, bad, nothing으로 request 정보에 덧붙여 보냅니다. 그럼 각각의 이름과 이름에 대한 value가 request객체에 저장이 됩니다.
그럼getParameterName() 메소드를 써서 모든 매개변수이름을 Enumeration type으로 받아옵니다. 또한, getParameter() 메소드를 사용하여 각각의 이름에 대한 value를 받아와서 출력해 주는 것이지요.
주의할 것은 반환되는 type이 Enumeration 이라는 것입니다. Enumeration에 대한 것은 API를 참고하시구요.
전 친절하니까 Enumeration에 대해 조금 설명하지요.
   참고
Enumeration는 객체를 저장하는 객체라고나 할까요...
name를 String type으로 하여 해당 name에 대한 객체를 object type으로 저장합니다.
즉, name=name 이고 해당 객체는 request 객체라고 하면 name:request라는 식으로 저장하는 거지요.
물론 여기서 객체는 모든 type이 될 수 있습니다.
저장된 객체의 type을 안다면 해당 type으로 casting하면 저장된 본래 객체의 기능을 모두 사용할 수 있습니다.
-- boolean hasMoreElements() : 더 이상의 객체가 있는지 없는지를 판단하여줍니다. 더 이상 없으면 boolean false 값을 반환합니다.
-- Object nextElement() : 다음 객체를 가져옵니다.
그럼 Enumeration type로 받아온 객체를 String type으로 casting하여 사용하면 됩니다.
위의 두 파일을 컨테이너에 저장하고 일단 requestTest.htm을 브라우저에서 불러보세요.
그럼 하이퍼링크가 하나 있을건데 그걸 클릭하시면 다음과 같은 결과가 출력됩니다.

interjigi : good
Jsys : nothing
zezz : bad

- String[] getParameterValues(String name) : String name의 매개변수에 대한 모든 value를 String[] type으로 반환한다.

   getParameterTest.htm




getParameter() Test....






Test



   getParameterTest.jsp


<%@ page contentType=text/html;charset=euc-kr %>
<%
String parameterValues1[] = request.getParameterValues(interjigi);
out.println(parameterValues1.length+

);
for(int i = 0; i < parameterValues1.length; i++){
out.println(interjigi);
out.println( : );
out.println(parameterValues1[i]);
out.println(

);
}
%>

위의 두 파일을 컨테이너에 저장하고 일단 getParameterTest.htm을 브라우저에서 불러옵니다. 그리고는 select box에서 선택하고 싶은 것들을 선택합니다.
저는 good 와 to 를 선택하였습니다.
다들 아시죠.. select box에서 control 키를 누르면서 선택하면 다중 선택되는 거..
그리고는 submit button을 클릭하면 다음과 같은 결과가 출력되겠죠.

3)HTTP 헤더를 읽어내는 메소드.

- Enumeration getHeaderNames() : 요청에 대한 모든 Header의 이름을 얻어낸다.
- String getHeader(String name) : String name에 연결된 Heaer의 value를 반환한다.
- Enumeration getHeaders(String name) : String name에 연결된 모든 Header value 를 Enumeration type으로 반환한다.
- int getIntHeader(String name) : String name에 연결된 Header의 value를 정수로 반환한다. int로 변환 못하는 값일 경우 NumberFormatException 이 발생.
- long getDateHeader(String name) : String name에 연결된 Header 날짜 값을 반환.date로 변환 못하는 값일 경우 IllegalArgumentException 이 발생.
- Cookie[] getCookies() : 요청에 대한 모든 Cookie를 Cookie[] type으로 반환.
   getParameterTest.htm




getParameter() Test....






Test



   getHeaderTest.jsp


<%@ page contentType=text/html;charset=euc-kr %>
<%
Cookie cookie1 = new Cookie(test1,hello);
Cookie cookie2 = new Cookie(test2,good);
Cookie cookie3 = new Cookie(test3,morning);
response.addCookie(cookie1);
response.addCookie(cookie2);
response.addCookie(cookie3);
java.util.Enumeration er = request.getHeaderNames();
while(er.hasMoreElements()){
String cookieHeaderName = (String)er.nextElement();
out.println( HeaderName: + cookieHeaderName);
out.println( || value : + request.getHeader(cookieHeaderName));
out.println(

);
//out.println(

);
}
out.println(Cookie name and value

);
Cookie cookie[] = request.getCookies();
for(int i = 0; i < cookie.length; i++){
out.println(+cookie[i].getName()+ : );
out.println(cookie[i].getValue());
out.println(

);
}
%>

위의 파일을 브라우저로 요청하게 되면 다음과 같은 결과가 나타납니다.


4)기타 메소드들.

- String getMethod() : 요청의 HTTP 메소드를 반환.(예 : GET, POST, ..)
- String getRequestURI() : 요청 URL을 반환함. 질의 문자열은 제외(예를 들어 요청 URL이 http://www.interjigi.com/Header.jsp?a=3&b=ttt&c=ppp 라면
         http://www.interjigi.com/Header.jsp 만 반환)
- String getQueryString() : 요청 URL 다음의 질의 문자열을 반환.
- HttpSession getSession(boolean create) : 요청의 세션을 HttpSession type으로 반환. 세션이 없을때 boolean create를 true로 하면 새로이 생성하여 반환.
- RequestDispatcher getRequestDispatcher(String path) : String path로 지정된 local URL에 대한 요청 전달(dispatcher)자를 생성.
- String getRemoteHost() : 요청을 보낸 Host의 완전 형태 이름을 반환.
- String getRemoteUser() : 요청을 보낸 사용자의 이름(있으면) 반환.

기타 메소드들은 그냥 알고 계십시요. 그리구 getRequestDispatcher(String path)는 자주 쓰이고 중요한 메소드입니다.
앞으로 강의가 계속 되면 상세하게 설명해 드릴테니 그 때까지 참으세요.^^

▶response 내부 객체

response 내부 객체는 reqeust 내부 객체에 대한 응답으로 사용자에게 보내어지는 정보를 나타냅니다.
최상위 interface는 javax.servlet.Servlet-Response interface를 구현하고 있습니다.
우린 HTTP 프로토콜을 주로 상대(?)하니까 javax.servlet.http.HttpServletResponse 인터페이스를 구현하여 사용하면 됩니다.
1) 응답 컨텐트 설정에 필요한 메소드.
- setContentType(String type) : 응답 컨텐트의 MIME 타입과 문자 encoding 을 설정.
- String getCharacterEncoding() : 응답 컨텐트의 문자 인코딩 방식을 String type으로 반환.
2) 응답 헤더 헤더 세팅을 위한 메소드.
- addCookie(Cookie cookie) : Cookie cookie를 응답에 추가.
cf) Cookie cookie = new Cookie(String cookieName, String cookieValue) : cookieName을 이름으로 가지고 cookieValue를 value로 가지는 cookie 생성.
- boolean containsHeader(String name) : String name을 이름으로 가지는 응답 헤더가 있는지 boolean 형으로 반환.
- setHeader(String name, String value) : String name을 이름으로 가지는 헤더에 String value를 저장함.
- setIntHeader(String name, int value) : String name을 이름으로 가지는 헤더에 int value를 저장함.
- setDateHeader(String name, long date) : String name을 이름으로 가지는 헤더에 long 형의 date를 저장함.
- addHeader(String name, String value) : String name을 이름으로 가지는 헤더에 String value를 추가하여 저장.
- addIntHeader(String name, int value) : String name을 이름으로 가지는 헤더에 int value를 추가하여 저장.
- addDateHeader(String name, long date) : String name을 이름으로 가지는 헤더에 long 형의 date를 추가하여 저장함.
3)응답 상태 코드 설정 메소드
- setStatus(int sc) : 응답의 상태 코드 중 에러가 아닌 경우 설정. int sc 값은 stats code를 나타내는 상수이다.
- sendError(int sc, String msg) : 응답의 상태 코드(int sc)와 에러 메세지(String msg)를 설정.
- sendRedirect(String url) : 다른 url을 요청하도록 브라우저에 응답을 보냄. 상대경로를 url 로 사용하여도 컨테이너는 브라우저에 응답을 보내기 전에 절대 경로로 변환시켜 보냄.
- String encodeRedirectURL(String url)
: sendRedirect(String url) 에 사용되는 url 에 세션정보를 포함시켜 인코딩하여 반환. url에 session 정보를 넣을 필요가 있으면 session 정보를 넣어서 인코딩함. url 이 Redirect 될 때 세션 정보 등이 포함될 필요가 없으면 아무 변화없이 절대 경로만 String 으로 반환.
   sendRedirectTest.jsp


<%@ page contentType=text/html;charset=euc-kr %>


setRedirect Test입니다.


<%
String url = response.encodeRedirectURL(requestTest.htm);
//out.println(url);
response.sendRedirect(url);
%>

위와 같이 sendRedirectTest.jsp를 컨테이너의 application directory에 저장하고 브라우저에서 sendRedirectTest.jsp을 요청하면 브라우저에는 requestTest.htm 이 보여집니다. 사실은 일단 sendRedirectTest.jsp 가 로딩되고 다시 requestTest.htm 으로 url을 재요청하는 것이 너무 순식간에 벌어지기 때문에 그렇게 보여질 뿐이죠.
암튼 sendRedirect() 는 자주 쓰일 수 있답니다.
여기서는 encodeRedirectURL()을 사용하여 반환된 String url을 sendRedirect() 메소드의 인자로 사용하였지만 그냥 response.sendRedirect(requestTest.htm);을 사용해도 결과는 같습니다.
그리고 중간에 주석 처리된 out.println(url) 은 response.sendRedirect(url)을주석처리하고 브라우저로 확인해 보면 다음과 같이 requestTest.htm의 절대경로가 출력될 것 입니다.

▶ out 내부 객체.
java.io 를 공부하신 분은 이해가 잘 되실 겁니다.
실제 내부객체에서 사용하는 response, request, out 은 쉽게 말하면 객체 변수지요.
그러니 jsp 파일이 아니고 servlet 라면 res, req, outing 처럼 프로그래머 자신이 정하는 변수죠.
단지 여러분이 사용하는 컨테이너가 이렇게 response, request, out 으로 지정해 놓은 것 뿐입니다.
물론 sun 사의 스펙에 따라서 컨테이너 회사들이 만들어 놓았겠죠.
만일 컨테이너 마다 사용하는 변수명이 틀리면 많은 혼란이 오겠지요.
자,, 여기까지는 그냥 함 얘기해 본 것이구요 이제부터가 본론입니다.
JSP에서 out 내부객체는 javax.servlet.jsp.JspWriter class type의 인스턴스(객체)입니다.
io를 공부하신 분은 아시겠지만 java.io.Writer 추상클래스를 확정해 놓은 것이죠.
print() 와 println() 메소드를 모두 구현해 놓았습니다. 좀더 상세한 내용은 API 를 참조하세요.

메소드

- boolean isAutoFlush() : 출력 버퍼가 완전히 찼을 때 자동으로 flush 되면 true를 반환,예외가 발생하면 false를 반환합니다.
* page 지시자에서 autoFlush 속성을 어떻게 지정했는가에 따라서 틀려지겠지요.
<%@ page autoFlush=true %>로 설정했으면 true를 반환. <%@ page autoFlush=false %>로 설정했으면 false를 반환. - int getBufferSize() : 출력 버퍼의 size를 int byte 로 반환.예) 12 byte 면 int 12를 반환.
- int getRemaining() : 출력 버퍼에서 사용되고 남은 부분의 size를 int byte로 반환.
- clearBuffer() : 출력 버퍼에 담긴 내용을 모두 버리고 비움.
- clear() : 출력 버퍼를 비우고 그전에 버퍼가 출력되었으면 IOException 발생시킴.
- flush() : 출력 버퍼와 출력 스트림을 flush 시킴.
- close() : 출력 스트림을 닫으며 동시에 flush 시킴.

1.3 외부 환경 객체

▶session 내부 객체.
session이 무엇인가? 하고 생각되시는 분이 계실지 모르겠군요.
ASP나 PHP를 공부하셨던 분은 잘 아실텐데..
그럼 간략하게 설명하도록 하죠.
session 이란?
일단 HTTP 프로토콜에 대한 단점으로 상태가 없다 는 것을 생각해 볼 수 있습니다.
HTTP 서버는 클라이언트의 상태에 대해서는 전혀 관심이 없다는 것입니다.
이미 접속해 있던 브라우저에서 같은 요청을 다시 해도 새로운 클라이언트로 인식한다는 것입니다.
요즘 인터넷 애플리케이션들은 거의다 사용자의 정보를 확인해서 사용자에 합당하고 필요한 자료만을 공급합니다.
하지만 HTTP 프로토콜은 이런 사용자의 정보를 확인할 방법이 없다는것이지요.
회원 확인을 해야 개인 성향에 맞는 서비스도 공급할 수도 있는 것입니다.
이런 HTTP 프로토콜의 단점을 보안하고자 HTTP 쿠키가 도입된 것입니다.
하지만 쿠키도 단점이 있지요.
일단 사용자 컴퓨터의 하드 디스크에 쿠키 정보를 기록하기 때문에 사용자가 쿠키를 허용하지 않으면 안되구요.
또, 보안상 다른 사람이 사용자의 정보가 누출될 수도 있답니다.
이러한 단점을 보안하기 위해 Session 이라는 것이 나오게 되었지요.
새로운 클라이언트가 접속할 때 각 접속 클라이언트 별로 다른 클라이언트와 구별할 수 있는 session 정보를 생성해서 서버에서 저장하고 있는거죠.
그럼 session 정보를 이용하여 사용자 식별을 한번만 하고도 그 정보를 계속해서 사용할 수 있고, 사용자에 따라 개별적인 서비스 제공이 가능해집니다.
말이 길었지만 정리하도록 합시다.
session 이란 각 클라이언트에 대한 상태를 저장하고 있는 것이라고 생각하면 되겠네요.
참, session 을 너무 자주 사용하는 것은 자제하시는 것이 좋을 겁니다.
왜냐구요?
당근 서버가 그 정보를 저장하고 있는데 동시 사용자가 매~~우 많으면 부하가 많이 걸려서 서버가 잘 돌아가지 않겠죠.
휴,, 제가 적고도 무슨 말인지 명확하지가 않군요.
하지만 이해하셨을 거라 믿고 그만 줄이겠습니다.
그럼 session 객체에 대해 본격적으로 알아보도록 합시다.
session 객체는 javax.servlet.http.HttpSession 인터페이스를 구현한 객체입니다.
메소드)
- String getId() : session ID를 반환한다.
- long getCreationTime() : session 이 만들어지는 시간을 반환한다.
- long getLastAccessedTime() : 해당 session에 대한 요청 중 최근에 요청받은 시간을 반환한다.
- setMaxInactiveInterval(int interval) : session 이 유지될 수 있는 바로 이전 요청과 현재 요청의 도달 시간차의 최대값(초)를 설정.
- int getMaxInactiveInterval(): session 이 유지될 수 있는 최대값(초)를 반환.
- boolean isNew() : 서버가 session을 생성하였으나 클라인언트가 받아들이지 않은 상태이면 true 반환. 즉,서버에서 session ID가 생성되었지만 클라이언트가 아직 session ID를 인식못하는 그 때가 최초 생성된 상태이므로 true가 반환된다는 말로 생각됩니다.(제 생각입니다.^^)
- invalidate() : 현재 session을 지우고 session에 연결된 객체를 해제한다.
cf)session 객체도 내부 객체이므로 setAttribute(String key, Object value) 메소드를 사용하여 객체를 연결할 수 있습니다.
   sessionTest.htm








 
















I      D



PassWord









   sessionTest.jsp


<%@ page contentType=text/html;charset=euc-kr session=true %>
<%
String id = request.getParameter(id);
String password = request.getParameter(password);
String sessionId = session.getId();
long createTime = session.getCreationTime();
long lastAccessedTime = session.getLastAccessedTime();
session.setMaxInactiveInterval(60*60*15);
int interval = session.getMaxInactiveInterval();
boolean isNew = session.isNew();
%>




현재 session에 대한 정보입니다.




<%
out.println(id : + id);
out.println(

);
out.println(password : + password);
out.println(

);
out.println(sessionID : + sessionId);
out.println(

);
out.println(createTime : + createTime);
out.println(

);
out.println(lastAccessedTime : + lastAccessedTime);
out.println(

);
out.println(interval : + interval);
out.println(

);
out.println(isNew : + isNew);
out.println(

);
%>
session 객체에 사용자의 정보를 저장하고

그 정보를 이용해서 사용자를 확인합니다. 


<%
if(id.equals(interjigi) && password.equals(babo)){
session.setAttribute(id, id);
session.setAttribute(password, password);
%>

interjigi 님 안녕하세요!

환영합니다!


 



주인님 페이지로

<%
}
else{
%>

주인님이 아니시군요!

나가주세요!!

<%
}
%>



   sessionTest2.jsp


<%@ page contentType=text/html;charset=euc-kr session=true %>
<%
String id = ;
String password = ;
if(session.getAttribute(id) != null && session.getAttribute(password) != null){
id = (String)session.getAttribute(id);
password = (String)session.getAttribute(password);
}
%>





<%
if(id.equals(interjigi) && password.equals(babo)){
%>
여기에 interjigi만 갈 수 있는 링크를 만들어 주면 되겠죠.


<%
}
else{
%>
여기에는 interjigi가 아니라는 메시지 또는 request.sendRedirect(String path)를
사용해서 login 페이지로 URL Redirect 시키면 되겠죠.
왜냐구요?
음,, 그건 사용자가 이 페이지의 URL을 알면 걍 여기 URL을 브라우저의
주소창에 URL을 입력하고 들어오면 막을 길이 없잖아요.
그러므로.. 이렇게 하는 것이 당연하죠.

<%
}
%>


이번 예는 약간은 복잡해 보일지 모르지만 어려운 내용은 아닙니다.
처음 sessionTest.htm 에서 사용자가 login 하면 id 와 password 의 value가 sessionTest.jsp로 전송됩니다.
그럼 sessionTest.jsp 에서는 request.getParameter(Strint name) 메소드를 사용하여 전송된 정보를 확인합니다.
정보가 일치하면 session.setAttribute(String key, Object value)를 사용하여 session 객체에 정보를 저장합니다.
그리고, 사용자가 확인이 되면 개별적인 service 페이지로 갈 수 있는 link 를 보여주는 거죠.
물론 정보가 틀리면 경고 메세지를 보여주면 되죠.
sessionTest2.jsp 에서는 혹시 사용자들이 sessionTest2.jsp 의 URL을 알게되어서 login 과정없이 접속할 경우를 대비해서 session.getAttribute(String key) 메소드를 이용하여 제어를 하게 됩니다.
쉽죠?
제가 여러분을 너무 과소평가하는 것은 아닌지 모르겠습니다.
하지만 이 강의는 모두 초보를 위한 것이니까 고수님들은 다른 강의를 보세요.

▶ application 내부 객체 javax.servlet.ServletContext 인터페이스를 구현.
애플리케이션이란 URL 에 따라 묶인 JSP 페이지들의 단위라고 할 수 있습니다.
컨테이너에 따라 다르지만 보통 URL의 첫째 디렉토리 이름을 애플리케이션으로 간주합니다.
예를 들자면,
http://www.interjigi.com/board 라는 디렉토리가 있다고 합시다.
여기서 board 라는 디렉토리는 컨테이너에 여러분들이 직접 만든 것이라 생각합시다.
그럼 board에는 list.jsp , read.jsp 등의 jsp 파일이 있겠죠.
이 때 컨테이너는 이 모든 jsp 파일들을 board 애플리케이션으로 간주한다는 얘기입니다.
각각의 컨테이너를 보면 모두 환경 파일이 있답니다.
그냥 여러분들이 사용하는 web-apps, default-app 등의 root 디렉토리도 모두 환경 파일에 설정이 되어 있습니다.
이제껏 여러분들이 무심코 사용하던 그 디렉토리도 하나의 애플리케이션이라구 생각해도 됩니다.
resin, tomcat, Jrun 모두 그 파일에 설정이 되어있습니다. 보통 resin에서는 resin.conf 파일이며 tomcat은 web.xml로 되어있을 겁니다.
Jrun은 admin 서버에 접속하여 GUI 환경으로 설정이 가능하구요.
다음에 다시 설명드릴 기회가 있을 테니 여기서 줄이기로 하지요.
즉, 하나의 상호연결된 JSP 페이지들을 모아서 하나의 디렉토리에 저장하며 그 JSP 페이지들은 하나의 애플리케이션이 되는 것이죠.
애플리케이션 자체와 서버(컨테이너)에 대한 정보 등을 가지고 있는 것이 바로 application 내부 객체입니다.
여기서 혼동이 올 수 있답니다.
http://www.interjigi.com/board/list.jsp
http://www.interjigi.com/board/drama/index.jsp
http://www.interjigi.com/board/tv/index.jsp
라고 디렉토리 구성이 되어 있으면 모두 board 애플리케이션으로 묶인다는 거죠.
이런 점을 Web Application Descriptor(웹 애플리케이션 설명자) 파일이란 것을 사용하면 방지할 수 있답니다.
Web Application Descriptor 에 대한 내용은 진도가 많이 나가고 난 후 설명드리죠.
EJB와 함께 설명 될 것 입니다.

메소드)
- String getServerInfo() : 컨테이너의 이름과 버전을 반환.
- int getMajorVersion() : 현재 서블릿 컨테이너의 서블릿 API의 주 버전을 반환.
- int getMinorVersion() : 현재 서블릿 컨테이너의 서블릿 API의 부 버전을 반환.
- String getMimeType(String file) : String file의 mime type을 반환.
- java.net.URL getResource(String path) : String path에 해당하는 URL 객체를 반환. path에 해당하는 URL의 컨텐트를 액세스 할 수 있는 URL 객체 반환.
- java.io.InputStream getResourceAsStream(String path) : String path에 해당하는 URL의 컨텐츠를 읽을 수 있는 InputStream 을 반환.
- String getRealPath(String path) : local URL을 local 파일 시스템 내의 경로 이름으로 바꾸어 준다.
- ServletContext getContext(String uripath) : String uripath 에 대한 application의 외부환경 정보를 반환.
- RequestDispatcher getRequestDispatcher(String path) : 지정된 local URL에 대한 dispatcher을 생성.
- log(String msg) : String msg를 log 파일에 쓴다.
- log(Throwable throwable, String msg) : String msg를 log 파일에 쓰고 지정된 Throwable typed의 Error또는 Exception의 stacktrace 결과를 함께 쓴다.
   참고
application 객체도 내부 객체이므로 setAttribute(String key, Object value) 메소드를 이용하여 value 객체를 저장할 수 있습니다.
그럼 session 내부 객체 때와 application 내부 객체를 사용할 때의 차이점을 아시겠나요?
session은 해당 jsp 페이지가 어느 application이냐는 생각지 않는거죠. 즉, 접속 클라이언트 1당 특유의 id 값을 가지니까 그 정보를 다른 클라이언트들은 사용할 수가 없습니다. 하지만, application 객체는 해당 application에 접속한 클라이언트 모두가 공통으로 사용할 수 있는 정보를 저장하는거죠.
session 내부 객체 사용의 예는 앞에서 설명했고 application 내부 객체에 사용할 수 있는 예를 들어보죠.
JDBC 까지 진도가 나가면 배우시겠지만 DB 연동을 하게 되면 해당 DB 시스템에 접속을 하게 되죠. 하지만, 해당 페이지에 그냥 DB connection 을 적어놓으면 그 페이지에 접속하는 클라이언트마다 각각의 접속을 가지게 되죠.그럼 당연히 부하도 많이 걸리구요.
이 때 application 객체에 DB connection 객체를 저장하여 두면 모두가 하나의 DB connection 객체를 공유하게 되는 거죠.
또 한가지는 보통 counter를 만들때 사용합니다.
counter라는 것은 해당 application에 현재까지 사용자가 접속했냐는 것을 저장하고 계속 접속 숫자를 늘려가는 것이잖아요.
그럼 당연히 그 애플리케이션에 접속한 사람들은 같은 시간에 같은 counter 숫자를 보도록 해야겠죠.
그 때 application 객체를 사용합니다.
물론 counter의 공정성을 생각하여 counter 숫자가 올라가는 것은 session 객체에서 제어를 하고 저장된 counter 숫자는 application 객체에 저장되는 거랍니다.
자세한 logic은 다음에 설명드리죠.
너무 앞선 건 아닌지 모르겠군요.
   application.jsp


<%@ page contentType=text/html;charset=euc-kr %>
<%
String serverNameVersion = application.getServerInfo();
int majorVersion = application.getMinorVersion();
int minorVersion = application.getMinorVersion();
String mimeType = application.getMimeType(applicationTest.htm);
String realPath = application.getRealPath(/);

out.println(serverNameVersion : +serverNameVersion);
out.println(

);
out.println(majorVersion : +majorVersion);
out.println(

); out.println(minorVersion : +minorVersion);
out.println(

);
out.println(mimeType : + mimeType);
out.println(

);
out.println(realPath : +realPath);
%>

제 경우에는 Jrun 3.0을 사용하고 있습니다. 그럼 다음과 같은 결과가 나오겠죠.
   결과

serverNameVersion : JRun 3.0 3.00.3694

majorVersion : 2

minorVersion : 2

mimeType : text/html

realPath : C:\Program Files\Allaire\JRun\servers\default\default-app

여기서 mimeType은 컨테이너가 알 수 있는 Type이면 해당 type을 출력하고 알 수 없는 type이면 null이 출력 됩니다.
보통 컨테이너들은 text/html, image/gif 는 일반적으로 지원을 하죠. 다른 mime type을 지원하게 하려면 환경 파일을 수정해야 합니다.
realPath는 해당 가상 경로를 절대경로로 바꾸어서 나타냅니다. 여기서 /는 defalt-application 의 root 디렉토리를 나타냅니다. 파일 업로드시 파일의 경로를 db에 저장할 때 사용될 수 있습니다.

▶ pageContext 내부 객체.
javax.servlet.jsp.PageContext class를 구현.
pageContext는 다른 내부 객체를 액세스 할 수 있고 또한 속성도 얻어낼 수 있다. 또한, 페이지간의 제어를 할 수 있는 객체이다.

메소드)

- Object getPage() : 해당 페이지에 대한 서블릿 인스턴스를 반환.
- ServletRequest getRequest() : 해당 페이지의 최초 요청객체(request 객체)를 반환.
- ServletResponse getResponse() : 해당 페이지의 응답객체(response 객체)를 반환.
- JspWriter getOut() : out 내부 객체를 반환.
- HttpSession getSession() : session 내부 객체를 반환.
- ServletConfig getServletConfig() : 서블릿 구성 객체인 config 내부 객체를 반환.
- ServletContext getServletContext() : 해당 페이지의 서블릿이 실행되는 외부 환경 객체, context 객체를 반환.
- Exception getException() : 에러 페이지가 있을 때 해당 페이지에 넘겨지는 exception 객체를 반환.
- forward(String relativeUrlPath) : String relativeUriPath을 상대경로로 하는 다른 local URL로 요청을 전달.
- include(String relativeUrlPath) : String relativeUriPath을 상대경로로 하는 다른 local URL을 처리한 결과를 해당 페이지에 포함시킴.
- setAttribute(String name, Object o, int scope) : int scope에서 String name에 Object value를 연결한다.
- java.util.Enumeration getAttributeNamesInScope(int scope) : 해당 scope에 결합되어 있는 모든 속성의 이름을 enumeration type로 반환.
- Object getAttribute(String name, int scope) : 해당 scope에 결합되어 있는 속성 중 String name를 이름으로 갖는 Object value를 반환.
- removeAttribute(String name, int scope) : 해당 scope에 결합되어 있는 속성 중 String name를 이름으로 갖는 속성의 Object value를 제거.
- Object findAttribute(String name) : page, request, session, application scope중에 순서대로 String name을 이름으로 갖는 속성을 찾고 해당 Object value를 반환.
- int getAttributesScope(String name) : String name을 이름으로 가지는 속성이 지정된 scope를 반환.
-scope는 PageContext에 상수로 정의되어 있으므로 위 메소드 중 scope를 사용하려면 다음 중 하나를 사용하면 된다.
-setAttribute() 와 getAttribute() 중 int scope를 인자로 가지지 않는 메소드도 사용할 수 있습니다.
   SCOPE

PAGE_SCOPE : pageContext 객체에 저장된 변수에 대한 scope.

REQUEST_SCOPE : request 객체에 저장된 변수에 대한 scope.

SESSION_SCOPE : session 객체에 저장된 변수에 대한 scope.

APPLICATION_SCOPE : application 객체에 저장된 변수에 대한 scope.

1.4 Error 처리 내부 객체.

▶exception 내부 객체.
session 객체처럼 page 지시자에서 isErrorPage속성을 true로 지정해야만 사용할 수 있다.

메소드)
- String getMessage() : 발생한 Exception을 설명해주는 메세지를 반환.
- printlnStackTrace(PrintWriter out) : Exception 발생시 stack을 추적하여 PrintWriter out 출력 스트림을 통해 출력.
- String toString() : 발생한 Exception 이름과 error 메세지를 함께 출력.

2. Action(액션) -JSP 태그.

2.1 forward 액션.
-local 서버 안에서 한 jsp 페이지에서 다른 페이지로 제어를 완전히 넘길 때 사용.
-브라우저의 주소창에는 forward 되기 전의 URL이 표시됨.
-요청 시점값을 사용할 수 있다.

<% String = test %>


이런 식으로 forward될 url을 해당 페이지가 요청될 때 동적으로 생성할 수 있다는 말입니다.

-컨테이너는 제어가 옮겨지는 페이지에게 pageContext 객체를 새로 만들어 줍니다.
이 때, request 객체와 session 객체는 제어가 옮겨지기 전의 페이지가 가지고 있던 request 객체와 session 객체와 동일하며 appllication 객체는 기존 페이지와 제어가 옮겨진 페이지가 같은 application에 속하는 지에 따라 다릅니다.

- 태그를 사용하여 request 객체에 요청매개변수를 추가할 수 있다. 단, 이미 존재하는 요청매개변수일 경우 최근의 값으로 추가된다.
request.getParameter() 메소드를 사용하여 요청 매개변수의 값을 호출하면 가장 최근의 값 하나만 반환된다.





   주의할 점
- 액션을 사용하기 전에 출력 buffer이 flush가 되면 안됨.
-버퍼 출력이 허용되지 않는 페이지의 경우 , 액션을 컨텐트 출력 부분 앞에 둘 것.
-리소스를 해제하는 등의 끝정리 코드도 태그의 앞에 둘 것.
모든 출력이라던지 리소스의 사용이 완전히 종결된 후 를 사용하란 말입니다.

2.2. include 액션.
- 와 다른 점은 제어를 완전히 옮기는 않는다는 점입니다. include한 페이지로 임시적으로 제어를 옮겼다가 그 실행 결과를 해당 페이지에 포함합니다.
-page 지시자에서의 include와는 다르죠. page 지시자에서 include를 지시하면 include될 파일과 기존의 파일을 합쳐서 1개의 파일로 합친 후 실행합니다. 하지만 에서는 파일을 합치지 않고 컨텐트를 출력할 때 include한 파일의 출력과 기존 파일의 출력을 합칩니다.

여기서 flush를 true로 하는 것은 현재 jsp spec 1.1 따르기 때문입니다.
-역시 forward 액션과 마찬가지로 태그를 상요하여 매개변수를 추가할 수 있습니다.
   참고 : page 지시자로 include 할 때와 include 액션을 사용할 때의 장단점.
1) page 지시자로 include 할 경우.
장점
-지역변수의 공유
-실행 시간면에서 조금 더 효율적.
-페이지가 합쳐진 후 컴파일 되므로 출력 버퍼링에 제약이 없다.
단점.
-페이지가 합쳐진 후 컴파일 되므로 include된 파일이 나중에 수정되더라도 자동 컴파일 되지 않는다.
-정적 컨텐트만 include할 수 있다.

2) include 액션을 사용할 경우.
장점.
-include 되는 파일이 나중에 수정되면 자동재컴파일 된다.
-클래스의 크기가 page 지시자에 비해 작다.
-매개변수을 추가할 수 있다.
-정적이 컨텐트 뿐만 아니라 servlet, CGI 등의 다른 형식 파일도 include 할 수 있다.

출처 : www.jspstudy.co.kr