Upload
hyeonseok-yang
View
339
Download
3
Embed Size (px)
DESCRIPTION
HeadFirst JSP&servlet chapter5 Study contents
Citation preview
Head First JSP & Servlet Chapter5 Study
ServletContext & Listener
NHN NEXT HumanDesignProject Team WildGoose
Context/Servlet Parameter & Attribute
Servlet/Context Init Parameter 란?
서블릿의 초기화에 필요한 데이터 web.xml에 존재하며
서블릿 초기화시에 불러오게 된다
변경될 가능성이 있는 문자열(ex. 관리자의 이메일)을 소스코드 밖에서 관리하고 싶으니까
Servlet/Context Init Parameter의 필요성
웹 어플리케이션의 모든 서블릿에서 사용 가능한 일종의 전역 객체같은 것
!Parameter가 문자열을 다룬다면 Attribute는 객체를 다룰 수 있다
Context Attribute 란?
!!
Parameter !
Attribute
Type !
String !
Object
Parameter vs. Attribute
Who add !
Container !
Listener
Where is Info !
web.xml !
Your code
Status !
Static !
Dynamic
Servlet 초기화 Parameter 설정
<web-app> <servlet> <servlet-name>SearchArticles</servlet-name> <servlet-class>next.wildgoose.SearchArticles</servlet-class> <init-param> <param-name>updated-date</param-name> <param-value>2014-04-06</param-value> </init-param> </servlet> <servlet> <servlet-name>SearchReporters</servlet-name> <servlet-class>next.wildgoose.SearchReporters</servlet-class> <init-param> <param-name>updated-date</param-name> <param-value>2014-04-01</param-value> </init-param> </servlet> </web-app>
정적으로 저장되는 Servlet 초기 설정 변수
public class SearchArticles extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) {! ServletConfig sc = getServletConfig();! // web.xml에 저장된 init-param에 접근 String updated_date = sc.getInitParameter(“updated-date”) // web.xml에 저장된 모든 init-param들의 이름을 확인 Enumeration<String> initParams = sc.getInitParameterNames();! }}
Servlet Parameter 접근정적으로 저장되는 Servlet 초기 설정 변수
Servlet마다 초기화 Attribute 설정동적으로 저장되는 초기 설정 변수
따로 존재하지 않음 !
그냥 Servlet 코드 안에 작성
Servlet Parameter Attribute
Set in web.xmlServlet Instance Variable
in your codeGetgetServletConfig() .getInitParameter (“param-name”)
중간 정리
하지만 !
웹 서버 내의 모든 Servlet이 같은 정보를 사용하고 싶다면
1. Servlet마다 같은 init-param 추가
2. 모든 Servlet이 공유하는 영역에 parameter/attribute 추가
모든 Servlet이 공유하는 영역 !
Servlet Context
Context 초기화 Parameter 설정정적으로 저장되는 Context 초기 설정 변수
<web-app> <servlet> <servlet-name>SearchArticles</servlet-name> <servlet-class>next.wildgoose.SearchArticles</servlet-class> <init-param> <param-name>updated-date</param-name> <param-value>2014-04-06</param-value> </init-param> </servlet> <context-param> <param-name>db-name</param-name> <param-value>wildgoose</param-value> </context-param> </web-app>
public class SearchArticles extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) {! ServletContext sc = getServletContext(); // Servlet parameter는 getServletConfig()! // web.xml에 저장된 context-param에 접근 String db_name = sc.getInitParameter(“db-name”); // web.xml에 저장된 모든 context-param들의 이름을 확인 Enumeration<String> initParams = sc.getInitParameterNames(); }}
Context Parameter 접근정적으로 저장되는 Context 초기 설정 변수
Context 초기화 Attribute 설정동적으로 저장되는 초기 설정 변수
Listener가 넣어줌 !
Listener를 구현해야 함
public class SearchArticles extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) { ServletContext sc = getServletContext(); DatabaseConnector dbCon = (DatabaseConnector) sc.getAttribute(“connector”); // getAttribute는 Object를 반환하므로 형변환이 꼭 필요함 dbCon.doSomething(); }}
Context Attribute 접근동적으로 저장되는 Context 초기 설정 변수
Context Parameter Attribute
Set in web.xml in ContextListener
GetgetServletContext() .getInitParameter (“param-name”)
(type casting) getServletContext()
.getAttribute (“attr-name”)
중간 정리
Servlet Listener
Listener를 구현하기 전에… !
!
큰 그림 확인
Tomcat 시작 &
초기화
ServletContext 객체 생성 web.xml의 context-param 확인 ServletContext에 parameter 추가 !ServletContextListener 생성 객체를 Context에 추가 !ServletConfig 객체 생성 web.xml의 init-param 확인 ServletConfig에 parameter 추가 !ServletConfig에 ServletContext 추가 (모든 설정은 Config에 있고, 전체 설정은 Config 내부 Context 참조)
Servlet 초기화 Servlet에 ServletConfig 전달
Listener가
나머지는 Tomcat이
실행
Web.xml
<web-app> <servlet> <servlet-name>SearchArticles</servlet-name> <servlet-class>next.wildgoose.SearchArticles</servlet-class> <init-param> <param-name>updated-date</param-name> <param-value>2014-04-06</param-value> </init-param> </servlet> <context-param> <param-name>db-name</param-name> <param-value>wildgoose</param-value> </context-param> </web-app>
<web-app> <servlet> <servlet-name>SearchArticles</servlet-name> <servlet-class>next.wildgoose.SearchArticles</servlet-class> <init-param> <param-name>updated-date</param-name> <param-value>2014-04-06</param-value> </init-param> </servlet> <context-param> <param-name>db-name</param-name> <param-value>wildgoose</param-value> </context-param> </web-app>
Web.xml
ServletContext
ServletContext {“db-name”:”wildgoose”}
ServletContext
ServletContext Listener
ServletContext Event
{“db-name”:”wildgoose”}
ServletContext
ServletContext Listener
con
{“db-name”:”wildgoose”}
ServletContext
ServletContext Listener
con
{“db-name”:”wildgoose”}
ServletContext
ServletContext Listener
con
요청 대기
{“db-name”:”wildgoose”}
ServletContext
ServletContext Listener
con
SearchArticles.java SearchArticles.jsp 요청
{“db-name”:”wildgoose”}
<web-app> <servlet> <servlet-name>SearchArticles</servlet-name> <servlet-class>next.wildgoose.SearchArticles</servlet-class> <init-param> <param-name>updated-date</param-name> <param-value>2014-04-06</param-value> </init-param> </servlet> <context-param> <param-name>db-name</param-name> <param-value>wildgoose</param-value> </context-param> </web-app>
Web.xml
ServletContext
<web-app> <servlet> <servlet-name>SearchArticles</servlet-name> <servlet-class>next.wildgoose.SearchArticles</servlet-class> <init-param> <param-name>updated-date</param-name> <param-value>2014-04-06</param-value> </init-param> </servlet> <context-param> <param-name>db-name</param-name> <param-value>wildgoose</param-value> </context-param> </web-app>
Web.xml
ServletConfig
ServletContext
ServletConfig
ServletContext
{“updated-date”:”2014-04-06”}
con
ServletContext Listener
Server가 종료될 때까지 계속 살아있다가 ServletContext가 사라지는 Event를 전달받고 Connection 종료
물론, 종료 코드도 구현해야
SearchArticles.java SearchArticles.jsp 요청
{“db-name”:”wildgoose”}
ServletConfig
ServletContext
{“updated-date”:”2014-04-06”}
con
ServletContext Listener
Server가 종료될 때까지 계속 살아있다가 ServletContext가 사라지는 Event를 전달받고 Connection 종료
물론, 종료 코드도 구현해야
SearchArticles.java SearchArticles.jsp 요청
{“db-name”:”wildgoose”}
Listener 구현
Web.xml<web-app> <servlet> <servlet-name>SearchArticles</servlet-name> <servlet-class>next.wildgoose.SearchArticles</servlet-class> <init-param> <param-name>updated-date</param-name> <param-value>2014-04-06</param-value> </init-param> </servlet> <context-param> <param-name>db-name</param-name> <param-value>wildgoose</param-value> </context-param> <listener> <listener-class>next.wildgoose.MyContextListener</listener-class> </listener> </web-app>
public class MyContextListener extends ServletContextListener {! public void contextInitialized(ServletContextEvent event) { ServletContext sc = event.getServletContext(); String db_name = sc.getInitParameter(“db-name”); // Static한 정보는 Parameter에서 가져옴 DatabaseConnector dbCon = new DatabaseConnector(db_name); sc.setAttribute(“connector”, dbCon); // Attribute에는 객체를 넘길 수 있음 }! public void contextDestroyed(ServletContextEvent event) { ServletContext sc = event.getServletContext(); DatabaseConnector dbCon = (DatabaseConnector) sc.getAttribute(“connector”); dbCon.close() // 컨텍스트가 종료될 때 처리해야할 일 }}
기타 Listener들
HttpRequestListener !
HttpSessionListener !
HttpSessionAttributeListener !
ServletContextAttributeListener !
ServletRequestAttributeListener
세션의 생성/파괴 감지 사용자 수 감지 가능
!!
Attribute의 추가, 제거, 수정을 감지
!
나머지는 Head First 참고
요청이 들어올 때 감지
한편, !
Context Attribute는 여러 서블릿이 동시에 접근할 수 있고
값이 변할 수 있다
YOU KNOW !
THE PROBLEM
public class SearchArticles extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) { ServletContext sc = getServletContext(); Object object = new Object(); synchronized(sc) { // servletContext 에 락을 걸어줘야 안전! sc.setAttribute(“blabla”, object); } }}
비슷한 문제 !
서블릿의 인스턴스 변수는 여러 스레드가 동시에 접근할 수 있고
값이 변할 수 있다
public class SearchArticles extends HttpServlet {! ArrayList<Article> articles; // 이렇게 쓰지 말라는 뜻! protected void doGet(HttpServletRequest request, HttpServletResponse response) { // DO SOMETHING }}
우린 이미 잘 하고 있습니다
public class SearchArticles extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) {! String search_query = null; search_query = new String(request.getParameter("q")); request.setAttribute("search_query", search_query); RequestDispatcher rd = null; rd = request.getRequestDispatcher(“SearchArticles.jsp") rd.forward(request, response); }}
구글신의 도움으로