JavaWeb三大組件之監(jiān)聽器(Listener)

title: JavaWeb三大組件之監(jiān)聽器(Listener)
tags: JavaWeb 監(jiān)聽器
categories: JavaWeb 監(jiān)聽器


監(jiān)聽器是一個專門用于對其他對象身上發(fā)生的事件或狀態(tài)改變進行監(jiān)聽和相應(yīng)處理的對象,當被監(jiān)視的對象發(fā)生情況時钉蒲,立即采取相應(yīng)的行動竭贩。監(jiān)聽器其實就是一個實現(xiàn)特定接口的普通java程序,這個程序?qū)iT用于監(jiān)聽另一個java對象的方法調(diào)用或?qū)傩愿淖兒万剑敱槐O(jiān)聽對象發(fā)生上述事件后,監(jiān)聽器某個方法立即被執(zhí)行。

上述概念設(shè)計到3個名詞概念:

  • 1.事件源:即誰產(chǎn)生的事件
  • 2.事件對象:即產(chǎn)生了什么事件
  • 3.監(jiān)聽器:監(jiān)聽事件源的動作

由于事件源可以產(chǎn)生多個動作(即產(chǎn)生多個事件)梧奢,而監(jiān)聽器中的每一個方法監(jiān)聽一個動作担神,故每個監(jiān)聽器中都有很多方法楼吃。

1.JavaWeb中的監(jiān)聽器

1.1概念

JavaWeb中的監(jiān)聽器是Servlet規(guī)范中定義的一種特殊類,它用于監(jiān)聽web應(yīng)用程序中的ServletContext妄讯、HttpSession和 ServletRequest這三大域?qū)ο蟮膭?chuàng)建孩锡、銷毀事件以及監(jiān)聽這些域?qū)ο笾械膶傩园l(fā)生修改的事件。

1.2JavaWeb中監(jiān)聽器的分類

在Servlet規(guī)范中定義了多種類型的監(jiān)聽器(一共8個監(jiān)聽器)捞挥,它們用于監(jiān)聽的事件源分別為ServletContext浮创,HttpSession和ServletRequest這三個域?qū)ο蟆ervlet規(guī)范針對這三個對象上的操作砌函,又把多種類型的監(jiān)聽器劃分為三種類型:

  • 1.域?qū)ο蟮纳芷诒O(jiān)聽:監(jiān)聽域?qū)ο笞陨淼膭?chuàng)建和銷毀斩披。這個監(jiān)聽器需要實現(xiàn)相應(yīng)的監(jiān)聽器接口:ServletContextListener、HttpSessionListener讹俊、ServletRequestListener垦沉。
  • 2.域?qū)ο蟮膶傩员O(jiān)聽:監(jiān)聽域?qū)ο笾袑傩缘脑黾雍蛣h除。這個監(jiān)聽器需要實現(xiàn)的監(jiān)聽器接口為:ServletContextAttributeListener仍劈、HttpSessionAttributeListener厕倍、ServletRequestAttributeListener
  • 3.感知監(jiān)聽(都與HttpSession域?qū)ο笥嘘P(guān)):監(jiān)聽綁定到HttpSession域中的某個JavaBean對象的狀態(tài)的監(jiān)聽器。這個監(jiān)聽器需要實現(xiàn)的監(jiān)聽器接口:HttpSessionBindingListener贩疙、HttpSessionActiveationListener.

1.3第一類:域?qū)ο蟮纳芷诒O(jiān)聽

事件源為:三大域
事件對象為:創(chuàng)建與銷毀
監(jiān)聽器為:實現(xiàn)了ServletContextListener讹弯、HttpSessionListener况既、ServletRequestListener這三個接口的監(jiān)聽器

1.3.1ServletContext的生命周期監(jiān)聽

public class AListener implements ServletContextListener{
    
    public void contextInitialized(ServletContextEvent sce)
    {
    //在項目啟動時調(diào)用
    }
    
    public void contextDestroyed(ServletContextEvent sce)
    {
    //在項目關(guān)閉時調(diào)用
    }
}

在web.xml文件中對該監(jiān)聽器進行配置:

image

1.3.2HttpSession的生命周期監(jiān)聽

代碼同上述基本一致:

public class AListener implements HttpSessionListener{
    
    public void sessionCreated(HttpSessionEvent sce)
    {
    //在會話產(chǎn)生時調(diào)用
    }
    
    public void sessionDestroyed(HttpSessionEvent sce)
    {
     //在會話關(guān)閉時調(diào)用
    }
}

同樣需要在web.xml文件中進行配置:

image

1.3.3ServletRequest的生命周期

代碼同上述基本一致:

public class AListener implements ServletRequestListener{
    
    public void rquestInitialized(ServletRequestEvent sce)
    {
    //在請求產(chǎn)生時調(diào)用
    }
    
    public void requestDestroyed(ServletRequestEvent sce)
    {
    //在請求關(guān)閉時調(diào)用
    }
}

同樣需要在web.xml文件中進行配置:


image

1.3.4對各個監(jiān)聽器接口的方法中出現(xiàn)的類介紹

ServletContextEvent類:類中有一個方法getServletContext(),該方法返回ServletContext對象。

HttpSessionEvent類:類中有一個方法getSession()组民,該方法返回一個HttpSession對象棒仍。

ServletRequestEvent類:類中有兩個方法,getServletContext()用于返回一個ServletContext對象臭胜,getServletRequest()用于返回一個ServletRequest對象莫其。

1.4第二類:域?qū)ο蟮膶傩员O(jiān)聽

事件源:三大域
事件對象:屬性的增加與刪除
監(jiān)聽器:實現(xiàn)了ServletContextAttributeListener、HttpSessionAttributeListener耸三、ServletRequestAttributeListener接口的監(jiān)聽器

1.4.1ServletContext的屬性監(jiān)聽

public class AListener implements ServletContextAttributeListener{
    
    public void attributeAdded(ServletcontextAttribute scab){
    //給ServletContext對象添加屬性時調(diào)用
    }
    
    public void attributeRemoved(ServletContextAttributeEvent scab){
    //給ServletContext對象刪除屬性時調(diào)用
    }
    
    public void attributeReplaced(ServletContextAttributeEvent scab){
    //給ServletContext對象替換屬性值時調(diào)用
    }
}

同樣需要在web.xml文件中對AListener進行配置乱陡。

1.4.2HttpSession的屬性監(jiān)聽

public class AListener implements HttpSessionAttributeListener{
    
    public void attributeAdded(HttpSessionAttribute scab){
    //給HttpSession對象添加屬性時調(diào)用
    }
    
    public void attributeRemoved(HttpSessionAttributeEvent scab){
    //給HttpSession對象刪除屬性時調(diào)用
    }   
    
    public void attributeReplaced(HttpSessionAttributeEvent scab){
    //給HttpSession對象替換屬性值時調(diào)用
    }
}

同樣需要在web.xml中對AListener進行配置。

1.4.3ServletRequest的屬性監(jiān)聽

public class AListener implements ServletRequestAttributeListener{
    
    public void attributeAdded(ServletRequestAttribute scab){
    //給ServletRequest對象添加屬性時調(diào)用
    }
    
    public void attributeRemoved(ServletRequestAttributeEvent scab){
    //給ServletRequest對象刪除屬性時調(diào)用
    }
    
    public void attributeReplaced(ServletRequestAttributeEvent scab){
    //給ServletRequest對象替換屬性值時調(diào)用
    }
}

同樣需要在web.xml中對AListener進行配置仪壮。

1.4.4對各個監(jiān)聽器接口的方法中出現(xiàn)的類介紹

ServletContextAttributeEvent類:該類對象有三個方法憨颠,getSevletContext()用于返回一個ServletContext,getName()用于返回屬性名睛驳,getValue()用于返回屬性值烙心。

HttpSessionBindingEvent類:該類對象有兩個方法,getName()用于獲取屬性名乏沸,getValue()用于獲取屬性值淫茵。

ServletRequestAttributeEvent類:該類對象有兩個方法,getName()用于獲取屬性名蹬跃,getValue()用于獲取屬性值匙瘪。

1.5感知監(jiān)聽器

保存在Session域中的對象可以有多種狀態(tài):綁定(session.setAttribute("bean",Object))到Session中,隨Session對象持久化到一個存儲設(shè)備中;從Session域中解除(session.removeAttribute("bean"))綁定,隨Session對象從一個存儲設(shè)備中恢復(fù)蝶缀。

Servlet 規(guī)范中定義了兩個特殊的監(jiān)聽器接口"HttpSessionBindingListener和HttpSessionActivationListener"來幫助JavaBean 對象了解自己在Session域中的這些狀態(tài)丹喻,實現(xiàn)這兩個接口的類不需要 web.xml 文件中進行注冊。

1.5.1HttpSessionBindingListener接口

實現(xiàn)了HttpSessionBindingListener接口的JavaBean對象可以感知自己被綁定到Session中和 Session中刪除的事件翁都。

當對象被綁定到HttpSession對象中時碍论,web服務(wù)器調(diào)用該對象的void valueBound(HttpSessionBindingEvent event)方法。

當對象從HttpSession對象中解除綁定時柄慰,web服務(wù)器調(diào)用該對象的void valueUnbound(HttpSessionBindingEvent event)方法鳍悠。

17public class JavaBeanDemo1 implements HttpSessionBindingListener {
18 
19     private String name;
20     
21     @Override
22     public void valueBound(HttpSessionBindingEvent event) {
23         System.out.println(name+"被加到session中了");
24     }
25 
26     @Override
27     public void valueUnbound(HttpSessionBindingEvent event) {
28         System.out.println(name+"被session踢出來了");
29     }
30 
31     public String getName() {
32         return name;
33     }
34 
35     public void setName(String name) {
36         this.name = name;
37     }
38 
39     public JavaBeanDemo1(String name) {
40         this.name = name;
41     }
42 }

上述的JavaBeanDemo1這個javabean實現(xiàn)了HttpSessionBindingListener接口,那么這個JavaBean對象可以感知自己被綁定到Session中和從Session中刪除的這兩個操作坐搔。

1.5.2HttpSessionActivationListener接口

實現(xiàn)了HttpSessionActivationListener接口的JavaBean對象可以感知自己被活化(反序列化)和鈍化(序列化)的事件藏研。

當綁定到HttpSession對象中的javabean對象將要隨HttpSession對象被鈍化(序列化)之前,web服務(wù)器調(diào)用該javabean對象的void sessionWillPassivate(HttpSessionEvent event) 方法概行。這樣javabean對象就可以知道自己將要和HttpSession對象一起被序列化(鈍化)到硬盤中蠢挡。

當綁定到HttpSession對象中的javabean對象將要隨HttpSession對象被活化(反序列化)之后,web服務(wù)器調(diào)用該javabean對象的void sessionDidActive(HttpSessionEvent event)方法。這樣javabean對象就可以知道自己將要和 HttpSession對象一起被反序列化(活化)回到內(nèi)存中业踏。(javabean隨著HttpSession對象一起被活化的前提是該javabean對象除了實現(xiàn)該接口外還應(yīng)該實現(xiàn)Serialize接口)禽炬。

27 public class JavaBeanDemo2 implements HttpSessionActivationListener,
28         Serializable {
29 
30      
31     private static final long serialVersionUID = 7589841135210272124L;
32     private String name;
33     
34     @Override
35     public void sessionWillPassivate(HttpSessionEvent se) {
36         
37         System.out.println(name+"和session一起被序列化(鈍化)到硬盤了,session的id是:"+se.getSession().getId());
38     }
39 
40     @Override
41     public void sessionDidActivate(HttpSessionEvent se) {
42         System.out.println(name+"和session一起從硬盤反序列化(活化)回到內(nèi)存了勤家,session的id是:"+se.getSession().getId());
43     }
44 
45     public String getName() {
46         return name;
47     }
48 
49     public void setName(String name) {
50         this.name = name;
51     }
52 
53     public JavaBeanDemo2(String name) {
54         this.name = name;
55     }
56 }

既然這里談到了session的序列化(鈍化)瞎抛,反序列化(活化)那我們就來具體聊聊。

2.session序列化(鈍化)

在session上線時却紧,會在tomcat/work/Catalina/localhost/項目名/下生成一個sessions.ser文件,里面存放了所有session的信息胎撤,當你正在訪問某個網(wǎng)頁時若此時服務(wù)器關(guān)閉(關(guān)閉時才生成這個文件)又打開(打開后這個文件會消失)晓殊,你依舊能正常訪問該網(wǎng)頁。(故說session有重生的效果)伤提。
若想廢掉session的序列化,需要在tomcat/conf/context.xml中添加<Manager pathname=“”/>

3.session的鈍化與活化

Tomcat會在session一段時間內(nèi)不被使用時鈍化session對象巫俺,所謂鈍化session,就是把session通過序列化的方法保存到硬盤文件中肿男。當用戶再使用session時介汹,Tomcat還會把鈍化的對象再活化session,所謂活化就是把硬盤文件中的session在反序列化中放回內(nèi)存舶沛。當session被tomcat鈍化時嘹承,sesseion中存儲的對象也被鈍化,當session被活化時如庭,也會把session中存儲的對象(javabean對象)活化叹卷。如果某個類(javabean對象)實現(xiàn)了HttpSessionActiveationListener接口后,當對象隨著session被鈍化和活化時坪它,下面兩個方法就會被調(diào)用:

public void sessionWillPassivate(HttpSessionEvent se):當對象感知被活化時調(diào)用本方法骤竹。  
public void sessionDidActivate(HttpSessionEvent se):當對象感知被鈍化時調(diào)用本方法。

鈍化時會在tomcat/work/Catalina/localhost/項目/mysession/文件下生成一個后綴為.session的文件往毡,網(wǎng)頁中一個被鈍化的session就對應(yīng)一個.session文件(而上面的序列化是一個.ser文件存在所有的session)蒙揣,在活化時此文件也不會消失(不同于上述的.ser文件消失)。
當然要看到上述效果开瞭,應(yīng)該先配置tomcat鈍化session的參數(shù)懒震,在tomcat/conf/catalina/localhost目錄下,添加以下配置內(nèi)容(google一下吧)惩阶。

2018.3.19更

歡迎加入我的Java交流1群:659957958挎狸。群里目前已有1800人,每天都非扯峡活躍锨匆,但為了篩選掉那些不懷好意的朋友進來搞破壞,所以目前入群方式已改成了付費方式,你只需要支付9塊錢恐锣,即可獲取到群文件中的所有干貨以及群里面各位前輩們的疑惑解答茅主;為了鼓勵良好風氣的發(fā)展,讓每個新人提出的問題都得到解決土榴,所以我將得到的入群收費收入都以紅包的形式發(fā)放到那些主動給新手們解決疑惑的朋友手中诀姚。在這里,我們除了談技術(shù)玷禽,還談生活赫段、談理想;在這里矢赁,我們?yōu)槟愕膶W習方向指明方向糯笙,為你以后的求職道路提供指路明燈;在這里撩银,我們把所有好用的干貨都與你分享给涕。還在等什么,快加入我們吧额获!

2018.4.21更:如果群1已滿或者無法加入够庙,請加Java學習交流2群:305335626 。群2作為群1的附屬群抄邀,除了日常的技術(shù)交流耘眨、資料分享、學習方向指明外撤摸,還會在每年互聯(lián)網(wǎng)的秋春招時節(jié)在群內(nèi)發(fā)布大量的互聯(lián)網(wǎng)內(nèi)推方式毅桃,話不多說,快上車吧准夷!

4.聯(lián)系

If you have some questions after you see this article,you can tell your doubts in the comments area or you can find some info by clicking these links.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钥飞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子衫嵌,更是在濱河造成了極大的恐慌读宙,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件楔绞,死亡現(xiàn)場離奇詭異结闸,居然都是意外死亡,警方通過查閱死者的電腦和手機酒朵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進店門桦锄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蔫耽,你說我怎么就攤上這事结耀。” “怎么了?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵图甜,是天一觀的道長碍粥。 經(jīng)常有香客問我,道長黑毅,這世上最難降的妖魔是什么嚼摩? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮矿瘦,結(jié)果婚禮上枕面,老公的妹妹穿的比我還像新娘。我一直安慰自己缚去,他們只是感情好膊畴,可當我...
    茶點故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著病游,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稠通。 梳的紋絲不亂的頭發(fā)上衬衬,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天,我揣著相機與錄音改橘,去河邊找鬼滋尉。 笑死,一個胖子當著我的面吹牛飞主,可吹牛的內(nèi)容都是我干的狮惜。 我是一名探鬼主播,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼碌识,長吁一口氣:“原來是場噩夢啊……” “哼碾篡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起筏餐,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤开泽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后魁瞪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體穆律,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年导俘,在試婚紗的時候發(fā)現(xiàn)自己被綠了峦耘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡旅薄,死狀恐怖辅髓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤利朵,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布律想,位于F島的核電站,受9級特大地震影響绍弟,放射性物質(zhì)發(fā)生泄漏技即。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一樟遣、第九天 我趴在偏房一處隱蔽的房頂上張望而叼。 院中可真熱鬧,春花似錦豹悬、人聲如沸葵陵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脱篙。三九已至,卻和暖如春伤柄,著一層夾襖步出監(jiān)牢的瞬間绊困,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工适刀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留秤朗,地道東北人。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓笔喉,卻偏偏與公主長得像取视,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子常挚,可洞房花燭夜當晚...
    茶點故事閱讀 43,576評論 2 349

推薦閱讀更多精彩內(nèi)容

  • ?監(jiān)聽器是一個專門用于對其他對象身上發(fā)生的事件或狀態(tài)改變進行監(jiān)聽和相應(yīng)處理的對象作谭,當被監(jiān)視的對象發(fā)生情況時,立即采...
    xdoyf閱讀 4,809評論 0 5
  • 監(jiān)聽器是一個專門用于對其他對象身上發(fā)生的事件或狀態(tài)改變進行監(jiān)聽和相應(yīng)處理的對象奄毡,當被監(jiān)視的對象發(fā)生情況時丢早,立即采取...
    joshul閱讀 261評論 0 1
  • 本文包括:1、Listener簡介2秧倾、Servlet監(jiān)聽器3怨酝、監(jiān)聽三個域?qū)ο髣?chuàng)建和銷毀的事件監(jiān)聽器4、監(jiān)聽三個域?qū)?..
    廖少少閱讀 6,044評論 6 28
  • 監(jiān)聽器(listener) 監(jiān)聽器簡介 :監(jiān)聽器就是一個實現(xiàn)特定接口的普通java程序那先,這個程序?qū)iT用于監(jiān)聽另一個...
    奮斗的老王閱讀 2,500評論 0 53
  • 找不到一個可以聊天的人农猬,真的很悲哀。