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

監聽器是一個專門用於對其餘對象身上發生的事件或狀態改變進行監聽和相應處理的對象,當被監視的對象發生狀況時,當即採起相應的行動。監聽器其實就是一個實現特定接口的普通java程序,這個程序專門用於監聽另外一個java對象的方法調用或屬性改變,當被監聽對象發生上述事件後,監聽器某個方法當即被執行。java

上述概念設計到3個名詞概念:web

  • 1.事件源:即誰產生的事件
  • 2.事件對象:即產生了什麼事件
  • 3.監聽器:監聽事件源的動做

因爲事件源能夠產生多個動做(即產生多個事件),而監聽器中的每個方法監聽一個動做,故每一個監聽器中都有不少方法。tomcat

1.JavaWeb中的監聽器

1.1概念

JavaWeb中的監聽器是Servlet規範中定義的一種特殊類,它用於監聽web應用程序中的ServletContext、HttpSession和 ServletRequest這三大域對象的建立、銷燬事件以及監聽這些域對象中的屬性發生修改的事件。服務器

1.2JavaWeb中監聽器的分類

在Servlet規範中定義了多種類型的監聽器(一共8個監聽器),它們用於監聽的事件源分別爲ServletContext,HttpSession和ServletRequest這三個域對象。Servlet規範針對這三個對象上的操做,又把多種類型的監聽器劃分爲三種類型:session

  • 1.域對象的生命週期監聽:監聽域對象自身的建立和銷燬。這個監聽器須要實現相應的監聽器接口:ServletContextListener、HttpSessionListener、ServletRequestListener。
  • 2.域對象的屬性監聽:監聽域對象中屬性的增長和刪除。這個監聽器須要實現的監聽器接口爲:ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener
  • 3.感知監聽(都與HttpSession域對象有關):監聽綁定到HttpSession域中的某個JavaBean對象的狀態的監聽器。這個監聽器須要實現的監聽器接口:HttpSessionBindingListener、HttpSessionActiveationListener.

1.3第一類:域對象的生命週期監聽

事件源爲:三大域
事件對象爲:建立與銷燬
監聽器爲:實現了ServletContextListener、HttpSessionListener、ServletRequestListener這三個接口的監聽器ide

1.3.1ServletContext的生命週期監聽

public class AListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent sce)
    {
      //在項目啓動時調用
    }

    public void contextDestroyed(ServletContextEvent sce)
    {
      //在項目關閉時調用
    }
}

在web.xml文件中對該監聽器進行配置:
this

1.3.2HttpSession的生命週期監聽

代碼同上述基本一致:google

public class AListener implements HttpSessionListener{

    public void sessionCreated(HttpSessionEvent sce)
    {
      //在會話產生時調用
    }

    public void sessionDestroyed(HttpSessionEvent sce)
    {
      //在會話關閉時調用
    }
}

一樣須要在web.xml文件中進行配置:
spa

1.3.3ServletRequest的生命週期

代碼同上述基本一致:設計

public class AListener implements ServletRequestListener{

    public void rquestInitialized(ServletRequestEvent sce)
    {
      //在請求產生時調用
    }

    public void requestDestroyed(ServletRequestEvent sce)
    {
      //在請求關閉時調用
    }
}

一樣須要在web.xml文件中進行配置:

1.3.4對各個監聽器接口的方法中出現的類介紹

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

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

ServletRequestEvent類:類中有兩個方法,getServletContext()用於返回一個ServletContext對象,getServletRequest()用於返回一個ServletRequest對象。

1.4第二類:域對象的屬性監聽

事件源:三大域
事件對象:屬性的增長與刪除
監聽器:實現了ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener接口的監聽器

1.4.1ServletContext的屬性監聽

public class AListener implements ServletContextAttributeListener{

    public void attributeAdded(ServletcontextAttribute scab){
      //給ServletContext對象添加屬性時調用
    }

    public void attributeRemoved(ServletContextAttributeEvent scab){
    //給ServletContext對象刪除屬性時調用
    }

    public void attributeReplaced(ServletContextAttributeEvent scab){
    //給ServletContext對象替換屬性值時調用
    }
}

一樣須要在web.xml文件中對AListener進行配置。

1.4.2HttpSession的屬性監聽

public class AListener implements HttpSessionAttributeListener{

    public void attributeAdded(HttpSessionAttribute scab){
      //給HttpSession對象添加屬性時調用
    }

    public void attributeRemoved(HttpSessionAttributeEvent scab){
    //給HttpSession對象刪除屬性時調用
    }    

    public void attributeReplaced(HttpSessionAttributeEvent scab){
    //給HttpSession對象替換屬性值時調用
    }
}

一樣須要在web.xml中對AListener進行配置。

1.4.3ServletRequest的屬性監聽

public class AListener implements ServletRequestAttributeListener{

    public void attributeAdded(ServletRequestAttribute scab){
      //給ServletRequest對象添加屬性時調用
    }

    public void attributeRemoved(ServletRequestAttributeEvent scab){
    //給ServletRequest對象刪除屬性時調用
    }

    public void attributeReplaced(ServletRequestAttributeEvent scab){
    //給ServletRequest對象替換屬性值時調用
    }
}

一樣須要在web.xml中對AListener進行配置。

1.4.4對各個監聽器接口的方法中出現的類介紹

ServletContextAttributeEvent類:該類對象有三個方法,getSevletContext()用於返回一個ServletContext,getName()用於返回屬性名,getValue()用於返回屬性值。

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

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

1.5感知監聽器

保存在Session域中的對象能夠有多種狀態:綁定(session.setAttribute(「bean」,Object))到Session中,隨Session對象持久化到一個存儲設備中;從Session域中解除(session.removeAttribute(「bean」))綁定,隨Session對象從一個存儲設備中恢復。

Servlet 規範中定義了兩個特殊的監聽器接口」HttpSessionBindingListener和HttpSessionActivationListener」來幫助JavaBean 對象瞭解本身在Session域中的這些狀態,實現這兩個接口的類不須要 web.xml 文件中進行註冊。

1.5.1HttpSessionBindingListener接口

實現了HttpSessionBindingListener接口的JavaBean對象能夠感知本身被綁定到Session中和 Session中刪除的事件。

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

當對象從HttpSession對象中解除綁定時,web服務器調用該對象的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實現了HttpSessionBindingListener接口,那麼這個JavaBean對象能夠感知本身被綁定到Session中和從Session中刪除的這兩個操做。

1.5.2HttpSessionActivationListener接口

實現了HttpSessionActivationListener接口的JavaBean對象能夠感知本身被活化(反序列化)和鈍化(序列化)的事件。

當綁定到HttpSession對象中的javabean對象將要隨HttpSession對象被鈍化(序列化)以前,web服務器調用該javabean對象的void sessionWillPassivate(HttpSessionEvent event) 方法。這樣javabean對象就能夠知道本身將要和HttpSession對象一塊兒被序列化(鈍化)到硬盤中。

當綁定到HttpSession對象中的javabean對象將要隨HttpSession對象被活化(反序列化)以後,web服務器調用該javabean對象的void sessionDidActive(HttpSessionEvent event)方法。這樣javabean對象就能夠知道本身將要和 HttpSession對象一塊兒被反序列化(活化)回到內存中。(javabean隨着HttpSession對象一塊兒被活化的前提是該javabean對象除了實現該接口外還應該實現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一塊兒從硬盤反序列化(活化)回到內存了,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的信息,當你正在訪問某個網頁時若此時服務器關閉(關閉時才生成這個文件)又打開(打開後這個文件會消失),你依舊能正常訪問該網頁。(故說session有重生的效果)。
若想廢掉session的序列化,須要在tomcat/conf/context.xml中添加<Manager pathname=「」/>

3.session的鈍化與活化

Tomcat會在session一段時間內不被使用時鈍化session對象,所謂鈍化session,就是把session經過序列化的方法保存到硬盤文件中。當用戶再使用session時,Tomcat還會把鈍化的對象再活化session,所謂活化就是把硬盤文件中的session在反序列化中放回內存。當session被tomcat鈍化時,sesseion中存儲的對象也被鈍化,當session被活化時,也會把session中存儲的對象(javabean對象)活化。若是某個類(javabean對象)實現了HttpSessionActiveationListener接口後,當對象隨着session被鈍化和活化時,下面兩個方法就會被調用:

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

鈍化時會在tomcat/work/Catalina/localhost/項目/mysession/文件下生成一個後綴爲.session的文件,網頁中一個被鈍化的session就對應一個.session文件(而上面的序列化是一個.ser文件存在全部的session),在活化時此文件也不會消失(不一樣於上述的.ser文件消失)。
固然要看到上述效果,應該先配置tomcat鈍化session的參數,在tomcat/conf/catalina/localhost目錄下,添加如下配置內容(google一下吧)。

相關文章
相關標籤/搜索