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)處理的對象,當(dāng)被監(jiān)視的對象發(fā)生情況時,立即采取相應(yīng)的行動。監(jiān)聽器其實就是一個實現(xiàn)特定接口的普通java程序,這個程序?qū)iT用于監(jiān)聽另一個java對象的方法調(diào)用或?qū)傩愿淖儯?dāng)被監(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中刪除的事件。

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

當(dāng)對象從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對象可以感知自己被活化(反序列化)和鈍化(序列化)的事件。

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

當(dāng)綁定到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的信息,當(dāng)你正在訪問某個網(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通過序列化的方法保存到硬盤文件中。當(dāng)用戶再使用session時,Tomcat還會把鈍化的對象再活化session,所謂活化就是把硬盤文件中的session在反序列化中放回內(nèi)存。當(dāng)session被tomcat鈍化時,sesseion中存儲的對象也被鈍化,當(dāng)session被活化時,也會把session中存儲的對象(javabean對象)活化。如果某個類(javabean對象)實現(xiàn)了HttpSessionActiveationListener接口后,當(dāng)對象隨著session被鈍化和活化時,下面兩個方法就會被調(diào)用:

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

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

2018.3.19更

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

2018.4.21更:如果群1已滿或者無法加入,請加Java學(xué)習(xí)交流2群:305335626 。群2作為群1的附屬群,除了日常的技術(shù)交流、資料分享、學(xué)習(xí)方向指明外,還會在每年互聯(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容