개발입문/Servlet&JSP

[헤드퍼스트 Servlet&JSP] 7-2. JSP LifeCycle 및 내장객체 사용

haloaround 2017. 2. 18. 12:21


JSP 는 서블릿이 됩니다.


컨테이너는 JSP 파일을 HttpJspPage 인터페이스를 구현한 서블릿 클래스로 변환하여 생성합니다. 그래서 이전에 서블릿에서 할 수 있었던 것을 모두 JSP에서도 할 수 있어야 합니다. (그래야 동일한 역할을 맡길 수 있죠!) 감사하게도 Servlet 에서 사용하던 것들은 JSP로 1:1 대응됩니다. (방식도 살짝만 다릅니다.)


그러니 서블릿이 참조했던 많은 리소스들에도 접근할 수 있어야 합니다.

그 외 서블릿 파라미터를 활용해 초기화할 수도 있어야 하고- JSP로 만들어진 서블릿 초기화(jspInit), 파괴(Destory) 할때의 커스텀 소스도 구현할 수 있어야합니다.



학습목표

JSP 는 서블릿이 됩니다.


템플릿 텍스트 (HTML)


스크립팅 요소 (Scripting Element)

주석, 지시자, 선언문, 스크립틀릿, 표현식


표준 액션 및 커스텀 액션


표현식 언어 EL (Expression Language) 


JSP 가 Servlet이 되기까지 




JSP LifeCycle
컨테이너는 JSP 파일을 HttpJspPage 인터페이스를 구현한 서블릿 클래스로 변환하여 생성합니다.

jspInit()
서블릿의 init() 메소드에서 호출

jspDestroy()
서블릿의 destroy() 메소드에서 호출

_jspService()
서블릿의 service() 메소드에서 호출, 재정의 불가
웹 컨테이너가 .jsp 코드로 변환, 생성할 것입니다. 


Servlet Lifecycle


(복습) JSP File to Servlet


단, .jsp 에서 .java로 변환 .class 컴파일 은 딱 한번만 하면 됩니다. 그 후에는 웹 컨테이너가 .class 를 바로 로딩해서 인스턴스화 하면 jspInit() 메소드가 실행되면서 서블릿 역할을 할 수 있게 됩니다. 그리고 요청이 들어올때 마다 새로운 스레드를 만들어서 _jspService() 메소드를 실행합니다. (나중에 jspDestroy()를 통해 메모리에 로딩한 서블릿 자원을 철수시킵니다.)




JSP 를 DD 에 선언

DD 에 <servlet-class> 대신 <jsp-file> 태그, 대상 클래스 파일(물론 .jsp) 을 넣어줍니다.

서블릿 클래스이긴 한데~ JSP 로 만들어진 서블릿 클래스이라고 명시합니다.


<web-app>

<servlet>

<servlet-name>MyTestInit</servlet-name>

//<servlet-class>/TestInit</servlet-class>

<jsp-file>/TestInit.jsp</jsp-file>

<init-param>

<param-name>email></param-name>

<param-value>ikickedbutt@wickedlysmart.com</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>MyTestInit</servlet-name>

<url-pattern>/TestInit.jsp</url-pattern>

</servlet-mapping>

</web-app>



JSP 초기화하기

Q. .jspInit() .jspDestroy()를 오버라이딩 구현하고 싶다면!

A. Servlet 클래스 멤버로 jspInit(), jspDestory() 메소드를 재정의하면 된다. <%! ... %>

.class 가 로딩된 후- jspInit()가 오버로딩 되어있을 경우 servlet 역할을 하는 이 jsp 가 초기화될 때 Servlet 의 init() 메소드가 jspInit() 메소드를 호출, 오버라이딩 구현합니다.


<%!

public void jspInit() {

ServletConfig sConfig = getServletConfig();

String emailAddr = sConfig.getInitParameter("email");

ServletContext ctx = getServletContext();

ctx.setAttribute("mail", emailAddr);

}

%>




JSP 내에 속성들

서블릿에서 사용했던 3가지 리소스 모두  static 하게 ServletConfig, ServletContext 를 불러올 수 있습니다. 속성에 대한 게터 메소드, 세터 메소드는 모두 동일합니다.


여기서! Page 만 예외입니다.


 

서블릿에서 

JSP에서 (내장객체) 

 Application

 getServletContext().setAttribute("foo",barObj); 

application.setAttribute("foo", barObj); 

 Request

 request.setAttribute("foo",barObj); 

request.setAttribute("foo",barObj); 

 Session

 session.setAttribute("foo",barObj); 

 session.setAttribute("foo",barObj);

 Page

 - 

 pageContext.setAttribute("foo",barObj); 





pageContext로 속성 접근하기


JSP 에서는 pageContext 내장 객체만 가지고도 모든 생존범위 속성을 읽고 설정할 수 있습니다. pageContext 클래스는 하위에 속성의 범위 4개를 statif final 변수로 가지고 있습니다.

Servlet 의 request, session, application(context), 그리고 page, pageContext 객체 


 왜 이렇게 pageContext를 모두 다 품어야했던지는... 나중에 다시 본대요.


 PageContext 

 APPLICATION_SCOPE

 PAGE_SCOPE

 REQUEST_SCOPE

 SESSION_SCOPE

 getRequest()

 getServiceConfig()

 getServletContext()

 getSession()


<% Float one = new Float(42.5); %>

<%= pageContext.getAttribute("foo")>

<% pageContext.setAttribute("foo", one, PageContext.SESSION_SCOPE); %>

<%= pageContext.findAttribute("foo") %>

page > request > session >application


PageContext Docs

http://docs.oracle.com/javaee/6/api/javax/servlet/jsp/PageContext.html




[JspPage Docs]


Interface JspPage


https://docs.oracle.com/cd/E17802_01/products/products/jsp/2.1/docs/jsp-2_1-pfd2/javax/servlet/jsp/JspPage.html


Interface HttpJspPage


https://docs.oracle.com/cd/E17802_01/products/products/jsp/2.1/docs/jsp-2_1-pfd2/javax/servlet/jsp/HttpJspPage.html