今天來整理一下Listener監聽器
為本書的範圍ch5
因為ServletContext只能提供字串類的初始參數
無法將物件類的型態傳入DD裡面
因此Listener就是要負責偵聽Context初始化前
先去執行一個獨立的類別
去解析所要的參數,取出其內容
照本書的例子是說明使用在建立資料庫連接的部分
主要需要下列部分:
XXXXServletContextListener
=>實作ServletContextListener interface
會從DD裡取出初始參數,並呼叫目標類別,設定在新的Object
目標屬性的類別
=>設定SrevletContext的屬性
XXXXServlet
=>繼承HttpServlet,使用目標屬性去呼叫其方法取得屬性
DD設定檔(web.xml)
=>設定一個初始參數給listener,供XXXXServletContextListener使用
Context只是其中一種的Listener
Listener總共有分成八種interface:
ServletContextAttributesListener
內容:可確認Web應用程式Context中的屬性新增或刪除取代
事件類型:ServletContextAttributesEvent
ServletContextListener
內容:可確認Context是否被建立或是destory
事件類型:ServletContextEvent
ServletRequestListener
內容:可記錄每次的request
事件類型:ServletRequestEvent
HttpSessionListener
內容:紀錄正在活動的Session
事件類型:HttpSessionEvent
HttpSessionAttributeListener
內容:提供Session屬性被新增移除或取代的method
事件類型:HttpSessionBindingEvent
HttpSessionActivationListener
內容:提供類別Session被移到另一個JVM時(或從別的JVM移入),提供相關的method
事件類型:HttpSessionEvent
HttpSessionBindingListener
內容:當此類別物件被Bind到某個Session或是從Session移除時,提供相關的method
事件類型:HttpSessionBindingEvent
ServletRequestAttributeListener
內容:提供Request屬性被新增移除或取代的method
事件類型:ServletRequestAttributeEvent
屬性
一種Object,被設定在三種ServletAPI上(Context,Request,Session)
設定的方法皆須透過物件的method
所以在取出內容時需做轉型的動作
較重要的部分為每個屬性存在的scope
屬性就像被釘在佈告欄上的物件
主要有兩個重要問題
誰能到看到或張貼這個佈告欄?還有它能存在多久?
參數
屬於一種字串String
設定在DD的值
可直接透過getParameter(String s)或getInitParameter(String s)呼叫
Scope: WEB application的每個部分都可以使用存取
因為Context屬於全域變數的概念
意即每個Servlet(就是多個thread)都可以使用它
所以他不是thread-safe的
因此會在呼叫getServletContext()時,加上synchronized
synchronized(getServletContext()){
getServletContext().setAttribute("XXX","XXX");
}
Scope: 同樣的ServletRequest才可以使用存取
只有Request是thread-safe的
會利用RequestDispatcher去做分派(使用forward方法)
ArrayList.setAttribute("xxxx",objResult);
RequestDispatcher view = request.getRequestDisoatcher("show.jsp")
view.forward(request,response);
關於RequestDispatcher的路徑參數
在使用上也有點差異:
透過ServletRequest取得
若路徑有加上/,代表從Container的跟目錄算起
若沒有,則會從request的同一層去找相關的JSP
request.getRequestDispatcher("/Index.jsp").forward(request, response);
//不管多加幾個斜線,container就是會從根目錄開始去找
request.getRequestDispatcher("Index.jsp").forward(request, response);
//會從request的同一層目錄去找對應的JSP
透過ServletContext取得
不能指定要不要加上斜線
必須用/開頭表示路徑
RequestDispatcher result = getServletContex.getRequestDispatcher("/Index.jsp");
//必須用/開頭表示路徑
result.forward(request, response);
forward(request, response)
確認回應會將所有結果傳回client
若在這之前已經先將結果傳送出去了(eg. OutputStream 的flush())
則不能再使用此方式用forward去處理
會得到IllegalStateException
Scope:同樣的HttpSession才可以使用存取
雖然Session只對一個client
但一個client有可能有多個Session(eg.開多個瀏覽器)
和Context相同,加上synchronized
synchronized(session)){
session.setAttribute("XXX","XXX");
}
今天先將此部分先簡單的做整理
後續在去做補充及實際的練習