Servlet監聽器詳解及舉例


監聽器就是一個實現特定接口的普通java程序,這個程序專門用於監聽另一個java對象的方法調用或屬性改變,當被監聽對象發生上述事件后,監聽器某個方法將立即被執行。

監聽器原理

監聽原理
1、存在事件源
2、提供監聽器
3、為事件源注冊監聽器
4、操作事件源,產生事件對象,將事件對象傳遞給監聽器,並且執行監聽器相應監聽方法

監聽器典型案例:監聽window窗口的事件監聽器
例如:swing開發首先制造Frame**窗體**,窗體本身也是一個顯示空間,對窗體提供監聽器,監聽窗體方法調用或者屬性改變:
* 關閉窗體時,調用windowListener 的windowclosing() , 傳遞windowEvent參數,表示窗體關閉事件對象
* 事件對象操作事件源,獲得事件源狀態

自定義監聽器

以上內容可以用下圖解釋:

這里寫圖片描述

通過person.addPersonListener(new PersonListener(){})使事件源與監聽器間產生聯系。

事件源(在事件源方法中創建事件對象):

監聽器(參數是事件對象)

事件對象(通過事件對象可以獲得事件源)

測試方法

對上的匿名類補充:匿名內部類的作用是創建一個實現接口的匿名類對象,含義是創建一個繼承自PersonListener的匿名類的對象),通過new表達式返回的引用被自動向上轉型為對PersonListener的引用

Servlet監聽器

不需要配置,但是監聽器仍需要進行注冊
在Servlet規范中定義了多種類型的監聽器,它們用於監聽的事件源分別為 ServletContext, HttpSessionServletRequest 這三個域對象。

Servlet監聽器分為三大類
1、數據域對象創建和銷毀監聽器
2、數據域對象和屬性變更監聽器
3、綁定到 HttpSession 域中的某個對象的狀態的事件監聽器

(一)數據域對象創建銷毀監聽器 — 監聽三個與對象 (三個監聽器)

1、ServletContextListener : 用來監聽ServletContext對象的創建和銷毀
監聽創建
監聽銷毀
* ServletContext對象代表全局唯一對象,每個web工程會產生一個ServletContext,服務器啟動創建,服務器關閉銷毀

編寫監聽器
步驟一:編寫類實現特定監聽器接口
步驟二:注冊監聽器,不是通過事件源,而是在web.xml 進行配置
監聽器和Servlet、Filter不同,不需要url配置,監聽器執行不是由用戶訪問的,監聽器 是由事件源自動調用的

servletContext域對象何時創建和銷毀

  • 創建:服務器啟動針對每一個web應用創建servletcontext
  • 銷毀:服務器關閉前先關閉代表每一個web應用的servletContext

ServletContextListener主流應用:
第一個:在服務器啟動時,對一些對象進行初始化,並且將對象保存ServletContext數據范圍內(因為在監聽器內可以獲得事件源對象) — 全局數據

  • 例如:創建數據庫連接池

第二個:對框架進行初始化 例如:Spring框架初始化通過ServletContextListener (因為監聽器代碼在服務器啟動時執行)

  • Spring框架(配置文件隨服務器啟動加載) org.springframework.web.context.ContextLoaderListener

第三個:實現任務調度,啟動定時程序 (Timer、TimerTask) 使一個程序,定時執行

比如說每天晚上十二點給過生日的人進行生日祝福,中國移動對賬戶進行同步,會在服務器使用較少的時間,例如凌晨之類,啟動一段程序,進行同步

java.util.Timer 一種線程設施,用於安排以后在后台線程中執行的任務。可安排任務執行一次,或者定期重復執行。
Timer提供了啟動定時任務方法 schedule
* schedule(TimerTask task, Date firstTime, long period) 用來在指定一個時間啟動定時器,定期循環執行
* schedule(TimerTask task, long delay, long period) 用來在當前時間delay多少毫秒后啟動定時器
停止定時器,timer.cancel取消任務

2、HttpSession 數據對象創建和銷毀監聽器 —– HttpSessionListener

監聽Session對象創建
監聽Session對象銷毀

Session何時創建:request.getSession()
Session何時銷毀:關閉服務器,Session過期,session.invalidate
*Session過期時間通過web.xml配置(tomcat配置文件中),默認時間30分鍾

配置:

HttpSession監聽器

現有如下JSP頁面:

1.jsp

2.jsp

訪問1.jsp時會執行監聽器原因:因為如果觀察jsp的源碼,封閉式英語培訓jsp會被預處理成.java代碼(在tomcat中work文件夾下,參見http://blog.csdn.net/megustas_jjc/article/details/53462025),我們打開這個.java代碼的源碼:

這里寫圖片描述

其中的getSession的實現實際就是request.getSession()

3、HttpServletRequest對象的創建和銷毀監聽器 —- ServletRequestListener

—-監聽request對象創建
監聽request對象銷毀

Request何時創建:請求發起時創建
Request何時銷毀:響應結束時銷毀

例如:每次刷新界面都會創建銷毀一次

注意(創建銷毀次數由請求次數決定):
使用forward —- request創建銷毀幾次 —– 一次
使用sendRedirect —- request創建銷毀兩次 (兩次請求)

(二)ServletContext/HttpSession/ServletRequest中保存數據 創建、修改、移除監聽器

ServletContextAttributeListener 監聽ServletContext中屬性變化
HttpSessionAttributeListener 監聽HttpSession中屬性變化
ServletRequestAttributeListener 監聽ServletRequest中屬性變化

attributeAdded 監聽屬性添加 —- 當數據范圍對象沒有該屬性,第一次添加時調用執行
attributeRemoved 監聽屬性移除 —- 從一個數據范圍對象刪除一個已經存在屬性執行
attributeReplaced 監聽屬性替換 —– 當一個數據范圍已經存在一個屬性,向數據范圍添加相同名稱屬性觸發替換方法

例如,此處我們用HttpSessionAttributeListener舉例(ServletContextListener與ServletRequestListener同理):

JSP頁面

監聽器

注冊

注意:獲得返回值通過session.getAttribute(se.getName())

(三)被綁定Session對象,自我狀態感知監聽器

保存在 Session 域中的對象可以有多種狀態:綁定到 Session 中;從 Session 域中解除綁定;隨 Session 對象持久化到一個存儲設備中(鈍化);隨 Session 對象從一個存儲設備中恢復(活化

被存放Session的Java對象,感知自我四種狀態變化
1、被綁定
2、被解除綁定
3、被鈍化 —– 數據從內存序列化硬盤
4、被活化 —- 數據從硬盤重新加載回內存

HttpSessionBindingListener實現接口的java對象,感知自己被綁定到Session或者從Session中解除綁定
HttpSessionActivationListener實現接口的java對象,感知從內存被鈍化硬盤上,雅思托福的區別從硬盤活化到內存中
實現這兩個接口的類不需要 web.xml 文件中進行注冊,都是由Session自主完成的,例如在存儲對象的時候會自動調用綁定

HttpSessionBindingListener
* 綁定對象方法 —-
* 解除綁定方法 —–、當Session對象銷毀時,當中所有綁定對象解除綁定

JSP頁面:

HttpSessionActivationListener
* 感知對象被活化
* 感知對象被鈍化
使用場景:Session保存數據,很長一段時間沒用,但是不能銷毀Session對象,不想占用服務器內存資源 —– 鈍化(將服務器內存中數據序列化硬盤上)

JSP界面

讀取數據

注意

鈍化和活化應該由tomcat服務器 自動進行 —- 配置tomcat

配置context有幾個位置?
1、tomcat/conf/context.xml 對所有虛擬主機 所有web工程生效
2、tomcat/conf/Catalina/localhost/context.xml 對當前虛擬主機所有web工程生效
3、當前工程/META-INF/context.xml 對當前工程有效

鈍化后 it315目錄在哪里?在“tomcat/work/Catalina/localhost/項目名”目錄中

java對象如果想實現序列化,需要實現Serializable接口(因此上述Bean2實現Serializable接口,才可以被鈍化,並之后進行活化並讀取)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM