2013년 9월 7일 토요일

[Head First]Servlets & JSP 내용정리-7장

Chapter.07 - JSP가 되어보자


JSP가 서블릿되기


JSP 요소들

  • 스크립틀릿(scriptlet) : <% %>
  • 지시자(directive) : <%@ %>
  • 표현식(expression) : <%= %>
  • 선언문(declaration) : <%! %>

내장 객체들

               API _____ 내장객체
         JspWriter _____ out
HttpServletRequest _____ request
HttpServletResponse _____ response
       HttpSession _____ session
    ServletContext _____ application
     ServletConfig _____ config
      JspException _____ exception
       PageContext _____ pageContext
            Object _____ page
** JspWriter와 PrinterWriter는 커스템 개발에서 기능상 차이가 있음.

설명들

  • MyJSP.jsp -> MyJSP_jsp.java -> MyJSP_jsp.class -> MyJSP_jsp Servlet
  • <% %> : 스크립틀릿 (scriptlet), 자바코드를 작성할 수 있다.
  • 지시자 : 컨테이너가 페이지를 자바 코드로 변환할 때 특별한 지시를 내릴 수 있도록 고안됨.
  • tomcat 환경의 JSP에서 생성된 servlet 코드 위치
    • $jsp_src_loc : jsp source location path 위치 변수
    • $tomcat_home : 톰캣 설치 홈
    • $eclipse_dev_plugin_home : 이클립스 개발 플러그인 홈
    • $serv_name : 서버명 , $webapp_name : web 어플리케이션 명
    • $jsp_src_loc = work/Catalina/$serv_name/$webapp_name/org/apache/jsp
    • 원래 환경 : $tomcat_home/$jsp_src_loc
    • eclipse 개발 환경 : $eclipse_dev_plugin_home/$jsp_src_loc
      $eclipse_dev_plugin_home = $workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1

page Directive(지시자) : 패키지를 import 할 때 사용됨.

  • 예1) 패키지 하나만 import할 경우 <%@ page import=”java.util.*” %>
  • 예2) 여러 패키지를 import를 할 경우 : <%@ page import=”java.util.*,java.io.*” %>
     혹은
    <%@ page import=”java.util.*” %>
            
    <%@ page import=”java.io.*” %>

Directive (지시자들) : <%@ ~ 으로 시작함.

  1. page : 페이지 환경을 정의 함. 하위 속성으로 13개 존재함.
    예) 문자 인코딩, 응답 컨덴츠 타입 등
  2. taglib : JSP에서 이용 가능한 태크 라이브러리를 지정함.
  3. include : 변환 시점에 현재 페이지에 포함할 코드난 문서를 정의

표현식 (JSP Expression) : out.println()를 대처 하기 위해서 사용된다.

  • <%= %> , 세미 콜론은 사용되지 않는다. out.print 구문에 들어가기 때문에
    <%= Counter.getCount() %> --> out.print(Counter.getCount()); 변환됨.
  • 절대 표현식에 세미 콜론을 넣지 않는다.
  • void를 리턴하는 메소드는 사용할 수 없음.

JSP 선언문 : 서비스 메소드나 여타 메소드의 바깥 쪽에 위치하게 함.

주석 : <%-- JSP Comment --%> , 자바소스 코드 주석으로 변경됨.

생성된 서블릿의 API

  • 톰캣에서 JSP 상속 클래스 : org.apache.jasper.runtime.HttpJspBase
  • 주요메소드
    • jspInit() : 서블릿 init() 메소드에서 호출함. (재정의 해도됨.)
    • jspDestory() : 서블릿의 destory() 메소드에서 호출함.(재정의 해도됨.)
    • _jspService() : 서블릿의 service() 메소드에서 호출함. (재정의 하면 안됨.) 그럼 ‘_’ 가 메소드 이름에 있음.

변환과 컴파일은 단한번만 이루어짐.
** 미리 컴파일하는 방법도 있음 : ?jsp_precompile=true|false , 컨테이너 마다 틀림 ,JSP 2.0에서 제시됨.

JSP 초기화

초기화 파라미터 설정
<servlet>
 <servlet-name>MyTestInit</servlet-name>
 <jsp-file>/TestInit.jsp</jsp-file>
 <init-param>
   <param-name>email</param-name>
   <param-value>cosmoslight.huni@gmail.com</param-value>
 </init-param>
</servlet>

jspInit() 재정의하기
<%!
 public void jspInit(){
   ServletConfig sConfig = getServletConfig();
   ------------------------------------------
   나중에 서블릿으로 변경될것을 미리 하고 getServletConfig()를 호출할 수 있음.
   String email = sConfig.getInitParameter(“email”);
   ServletContext ctx = getServletContext();
   ctx.setAttribute(“mail”,email);
   -------------------------------
   application 생존 범위로 설정 한다.
 }
%>

JSP내에 있는 속성들..

범위
Servlet에서
JSP에서 (내장객체를 사용)
Application
getServletContext().setAttribute(“foo”,barObj);
application.setAttribute(“foo”,barObj);
Request
request.setAttribute(“foo”,barObj);
request.setAttribute(“foo”,barObj);
Session
request.getSession().setAttribute(“foo”,barObj);
session.setAttribute(“foo”,barObj);
Page
제공하지 않음.
pageContext.setAttribute(“foo”,barObj);


PageContext클래스 로 할 수 있는 일들

  • 속성 접근 (변경 및 설정)
  • 내장 객체 얻기
  • 속성 변경 예제
    • page 생존 범위 설정 : <% pageContext.setAttribute(“foo”,new Float(3.141592)); %>
    • page 생존 범위 읽기 : <%= pageContext.getAttribute(“foo”) %>
    • session 생존 범위 설정 :
      <% pageContext.setAttribute(“foo”,fooObj,PageContext.SESSION_SCOPE); %>
    • session 생존 범위 읽기 :
    • <%= pageContext.getAttribute(“foo”,PageContext.SESSION_SCOPE) %>
      <%= session.getAttribute(“foo”) %> 와 동일
    • application 생존 범위 읽기 :
      <%= pageContext.getAttribute(“foo”,PageContext.APPLICATION_SCOPE) %>
      <%= application.getAttribute(“foo”) %> 와 동일
    • 어떤 생존 범위인지 모르는 속성 찾기 : <%= pageContext.findAttribute(“foo”)%>
      찾는 순서는 page 부터 가장 작은 범위로 부터 큰 범위로 즉 page > request > session > application

page 지시자 속성

  1. import : 생성된 서블릿 클래스에 추가될 자바 import문을 정의
    • 기본값
    • javax.servlet
    • javax.servlet.http
    • javax.servlet.jsp
  2. isThreadSafe : 생성된 서블릿 클래스가 SingleThreadModel을 구현 할지 결정함. 기존값 true
    • true - 스레드 안전 함. (SingleThreadModel이 아님)
    • false - SingleThreadModel 임.
  3. contentType : MIME 타입과 문자 인코딩을 설정. 기본값은 ?
  4. isELIgnored : EL 표현식을 무시할 것인지 결정, 기본값은 false
  5. isErrorPage : 현재 페이지가 JSP 오류 처리용 페이지인지를 정의 합니다. 기본값은 false
    만약 true 이면 내장 예외사항 객체(Throwable)를 사용할 수 있음.
  6. errorPage : 이 페이지에서 잡지 못한 예외사항을 보낼 오류 페이지 URL를 정의. URL로 정의된 페이지는 바로 위의 속성 true 이어야 함(isErrorPage)
  7. language : scriplet,표현식, 선언문에 사용할 스크립팅 언어를 정의. 현재 java 유일
  8. extends : JSP가 상속할 부모 클래스를 정의함.
  9. session : 내장 session 객체를 가질지 여부를 결정. 기본값 true
  10. buffer ; 내장 out 객체(JspWriter) 버퍼링을 어떻게 관리할지 결정
  11. autoFlush : 자동적으로 버퍼링된 출력을 비울 것인지(flush)를 결정 합니다. 기본값 true
  12. info : 변환될 페이지에 포함할 String 값을 기술 합니다. 이 값을 나중에 getServletInfo() 메소드로 접근할 수 있음.
  13. pageEncoding : JSP 문자 인코딩을 합니다. 기본값으 “ISO-8859-1” (contentType이나 XML 문서문법에서 정의 하지 않은 경우에만 기본값이 적용됨.)

스크립틀릿은 협업 개발시 비프로그램머가 보기 아주 어렵다.

EL :


  • 정의 : 표현식 언어(Expression Language) , JSP 2.0 이후 부터 공식적으로 지원
  • 형식 : ${....}
  • JSP에서 스크립팅항목을 사용하지 못하게 하는 방법 : <scripting-invalid>
  • EL을 무시하도록 만들기 (EL은 기본적으로 가능 상태) : <el-ignored> 나 <%@ page isELIgnored 속성
    페이지 지시자가 DD 보다 우선 순위를 가짐.
    <web-app ...>
     <jsp-config>
       <jsp-property-group>
       <url-pattern>*.jsp</url-pattern>
       <scripting-invalid>true</scripting-invalid>
       <el-ignored>true</el-ignored>
     </jsp-config>
    </web-app>
    ** <%@ page isScriptingEnabled=”false” %> JSP 2.0 초안 존재하다가 최종 스펙에서 삭제됨.

    EL 기능 설정 문제

    DD의 설정
    el-ignored
    page 설정
    isELIgnored
    EL 기능함
    EL 무시됨
    명시되지 않음
    명시되지 않음
    V

    false
    명시되지 않음
    V

    true
    명시되지 않음

    V
    false
    명시되지 않음
    V

    false
    true

    V
    true
    false
    V


    스크립팅 가능 여부

    DD설정
    scripting-invalid
    스크립팅
    기능함
    스크립팅
    무시됨
    명시되지 않음
    V

    true

    V
    false
    V


[Head First]Servlets & JSP 내용정리-6장

Chapter.06 - 세션관리(대화 상태 유지하기)


  1. 클라이언트를 구분하기위해서 IP는 사용할수 없다. (NAT 사용하면 동일하다)
  2. HTTPS나 ID 요청은 꼭 필요할 때만 사용하도록 합니다.
  3. 클라이언트에게 필요한 것은 유일한 세션ID 가 필요하다.
  4. 클라이언트와 컨테이너 사이에 세션ID를 공유하는 방법 - Cookie
  5. 컨테이너가 모든 Cookie 작업을 수행 합니다.
    • Response 객체에 세션 Cookie 보내기 / 받기
      즉 HttpSession session = request.getSession();에서 getSession 부분에서 쿠기 생성 및 관련 모든 작업을 수행함.
    • session.isNew() : 세션이 새로 생성되었으면 true 입니다.
  6. Request 객체 이외 세션을 얻는 다른 방법은?
    HttpSessionEvent 혹은 HttpSessionBindingEvent에서 얻을 수 있음.
    HttpSessionListener 인터페이스 구현에서 아래와 같이
    public void sessionCreated(HttpSessionEvent event){
    HttpSesssion session = event.getSession();
    }
  7. 이미 만들어진 세션을 원할때
    getSession(boolean)에서 getSession(false)를 호출하면 되고 만약 존재하지 않으면 null을 리턴 합니다.
  8. 클라이언트가 Cookie를 사용하지 않는 경우에도 작동하도록 하는 방법
    URL 재작성 : URL + ;jessionid=1234567
    관련 메소드 : response.encodeURL(“”)
    public void doGet(HttpServletRequest request....){
     HttpSession session = request.getSession();
     out.println(“<a href=\””+response.encodeURL(“/BeerTest.do”)+”\”>click me</a>”);
    }

    • JSP로 보내고 세션은 계속 유지 하고 싶은 경우 : response.encodeRedirectURL(“$URL”);  
      JSP에서는 JSTL 태그 <c:URL>

    주요 HttpSession 메소드
    메소드명
    하는 일이 무얼까요?
    어떤 경우에 쓸가요?
    getCreationTime()
    세션이 생성된 시간을 리턴함.
    세션이 얼마나 오래 되었는지 알고 싶을 때.
    특정 시간만 세션을 사용하도록 제한하는데 사용될 수 있다. (로그인 후 10만 사용)
    getLastAccessedTime()
    이 세션으로 들어온 마지막 요청 시간을 리턴합니다.(밀리초 단위)
    클라이언트가 언제 마지막으로 세션에 접근 했는지 알고 싶을때. 클라이언트가 장시간 사용이 없을 경우, 메일을 보내 다시 사용하러 올것인지 물어 볼때 사용할 수 있겠죠.
    setMaxInactiveInterval()
    해당 세션에 대한 요청과 요청간의 최대 허용시간 (초 단위)을 지정
    클라이언트의 요청이 정해진 시간이 지나도 들어 오지 않을 경우. 해당 세션을 제거하기 위하여 사용함. 서버 상에 짝 잃은 세션을 최소화하기 위해 사용합니다.
    getMaxInactiveInterval()
    해당 세션에 대한 요청과 요청간의 최대 허용시간 (초 단위)을 리턴합니다.
    세션이 얼마나 오랫동안 비활성화 상태였는지, 여전히 살아있기는 한지 알고 싶을 때. 세션이 invalidate() 되기까지 시간이 얼마나 남았는지 알기 위하여 사용할 수도 있습니다.
    invalidate()
    세션을 종료합니다. 이 작업에는 현재 세션에 저장된 모든 세션 속성을 제거하는(unbind) 작업이 포함됩니다.
    클라이언트가 비활성화이거나 세션작업이 완료되어 강제로 세션을 종료할 때(예를 들면 장바구니 결제를 완료했을때). 세션 객체 자체는 컨테이너가 내부적으로 재사용합니다. 여기에 대해선 여려분의 신경쓸 필요가 없죠.
    invalidate()는 세션ID가 더 이상 존재하지 않으니, 관련 속성을 세션 객체에서 제거하라는 의미입니다.

    세션이 종료되는 세 가지 이유
    • 시간이 다 되어서(타임 아웃)
    • 개발자 세션 객체에 invalidate() 메소드를 실행하는 경우
    • 애플리케이션이 다운되는 경우(문제가 생겨 다운되거나, 언디플로이(undeploy)되는 경우).

    DD에서 세션 타임아웃을 설정하기 및 특정세션만 타임 아웃 설정하기
    <web-app ...>
     <session-config>
         <session-timeout>15</session-timeout>
         -------------------------------------
         15는 분을 의미 합니다.
     </session-config>
    </web-app>

    특정 세션만 타임 아웃 설정하는 코드
    session.setMaxInactiveInterval(20*60);  //여기서는 초단위 임.
                                  -----
    만약 0 초 이면 바로 타임 아웃 처리를 합니다.

    세션 관련 리스너들
    시나리오
    리스너
    인터페이스/메소드
    이벤트 타입
    일반적으로 구현하는
    클래스
    얼마나 많은 동시 사용자가 있는지 알고 싶을 때. 즉 활성화된 세션들 뒤를 캐고 싶을 때
    HttpSessionListener
    (javax.servlet.http)
    sessionCreated
    sessionDestroyed
    HttpSessionEvent
    An attribute class
    Some other class
    세션이 다른 VM으로 옮겨가는 것을 알고 싶을 때
    HttpSessionActivationListener
    (javax.servlet.http)
    sessionDidActivate
    sessionWillPassivate
    HttpSessionEvent
    An attribute class
    Some other class
    속성 클래스(속성의 값으로 사용되는 클래스)가 있고,이 타입의 클래스가 세션에 바인딩되거나 제거될 때를 알고 싶을 때.
    HttpSessionBindingListener
    (javax.servlet.http)
    valueBound
    valueUnbound
    HttpSessionBindingEvent
    An attribute class
    Some other class
    속성을 세션에 추가,제거, 대체를할 때를 아록 싶을 때
    HttpSessionAttributeListener
    (javax.servlet.http)
    attributeAdded
    attributeRemoved
    attributeReplaced
    HttpSessionBindingEvent
    An attribute class
    Some other class