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)聽器進行配置:
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文件中進行配置:
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文件中進行配置:
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.