深入分析JavaWeb Item38 -- 監聽器(Listener)快速學習
一、監聽器介紹1.1、監聽器的概念
監聽器是一個專門用於對其他對象身上發生的事件或狀態改變進行監聽和相應處理的對象,當被監視的對象發生情況時,立即採取相應的行動。監聽器其實就是一個實現特定介面的普通java程式,這個程式專門用於監聽另一個java對象的方法調用或屬性改變,當被監聽對象發生上述事件後,監聽器某個方法立即被執行。
1.2、監聽器案例——監聽window視窗的事件監聽器
package me.gacl.listener.demo;import java.awt.Frame;import java.awt.event.WindowEvent;import java.awt.event.WindowListener;public class Demo1 { /** *java的事件監聽機制 *1、事件監聽涉及到三個組件:事件來源、事件對象、事件監聽器 *2、當事件來源上發生某一個動作時,它會呼叫事件監聽器的一個方法,並在調用該方法時把事件對象傳遞進去, * 開發人員在監聽器中通過事件對象,就可以拿到事件來源,從而對事件來源進行操作。 */ public static void main(String[] args) { Frame f = new Frame(); f.setSize(400, 400); f.setVisible(true); //註冊事件監聽器 f.addWindowListener(new WindowListener(){ public void windowActivated(WindowEvent e) { } public void windowClosed(WindowEvent e) { } /** * 當window表單關閉時就會WindowListener這個監聽器監聽到, * 監聽器就會調用windowClosing方法處理window表單關閉時的動作 */ public void windowClosing(WindowEvent e) { //通過事件對象e來擷取事件來源對象 Frame f = (Frame) e.getSource(); System.out.println(f+"表單正在關閉"); f.dispose(); } public void windowDeactivated(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowOpened(WindowEvent e) { } }); }}
1.3、設計一個可以被別的對象監聽的對象
我們平時做開發的時候,我們是寫監聽器去監聽其他對象,那麼我們如果想設計一個對象,讓這個對象可以被別的對象監聽又該怎麼做呢,可以按照嚴格的事件處理模型來設計一個對象,這個對象就可以被別的對象監聽,事件處理模型涉及到三個組件:事件來源、事件對象、事件監聽器。
下面我們來按照事件處理模型來設計一個Person對象,具體代碼如下:
package me.gacl.observer;/*** @ClassName: Person(事件來源)* @Description: 設計一個Person類作為事件來源,這個類的對象的行為(比如吃飯、跑步)可以被其他的對象監聽* @author: 孤傲蒼狼* @date: 2014-9-9 下午9:26:06**/ public class Person { /** * @Field: listener * 在Person類中定義一個PersonListener變數來記住傳遞進來的監聽器 */ private PersonListener listener; /** * @Method: eat * @Description: 設計Person的行為:吃 * @Anthor:孤傲蒼狼 * */ public void eat() { if (listener != null) { /** * 調用監聽器的doeat方法監聽Person類對象eat(吃)這個動作,將事件對象Event傳遞給doeat方法, * 事件對象封裝了事件來源,new Event(this)中的this代表的就是事件來源 */ listener.doeat(new Event(this)); } } /** * @Method: run * @Description: 設計Person的行為:跑 * @Anthor:孤傲蒼狼 * */ public void run() { if (listener != null) { /** * 調用監聽器的dorun方法監聽Person類對象run(跑)這個動作,將事件對象Event傳遞給doeat方法, * 事件對象封裝了事件來源,new Event(this)中的this代表的就是事件來源 */ listener.dorun(new Event(this)); } } /** * @Method: registerListener * @Description: 這個方法是用來註冊對Person類對象的行為進行監聽的監聽器 * @Anthor:孤傲蒼狼 * * @param listener */ public void registerListener(PersonListener listener) { this.listener = listener; }}/*** @ClassName: PersonListener(事件監聽器)* @Description: 設計Person類(事件來源)的監聽器介面* @author: 孤傲蒼狼* @date: 2014-9-9 下午9:28:06**/ interface PersonListener { /** * @Method: doeat * @Description: 這個方法是用來監聽Person對象eat(吃)這個行為動作, * 當實作類別實現doeat方法時就可以監聽到Person類對象eat(吃)這個動作 * @Anthor:孤傲蒼狼 * * @param e */ void doeat(Event e); /** * @Method: dorun * @Description: 這個方法是用來監聽Person對象run(跑)這個行為動作, * 當實作類別實現dorun方法時就可以監聽到Person類對象run(跑)這個動作 * @Anthor:孤傲蒼狼 * * @param e */ void dorun(Event e);}/*** @ClassName: Event(事件對象)* @Description:設計事件類別,用來封裝事件來源* @author: 孤傲蒼狼* @date: 2014-9-9 下午9:37:56**/ class Event { /** * @Field: source * 事件來源(Person就是事件來源) */ private Person source; public Event() { } public Event(Person source) { this.source = source; } public Person getSource() { return source; } public void setSource(Person source) { this.source = source; }}
經過這樣的設計之後,Peron類的對象就是可以被其他對象監聽了。測試代碼如下:
package me.gacl.observer;public class PersonTest { /** * @Method: main * @Description: 測試Person類 * @Anthor:孤傲蒼狼 * * @param args */ public static void main(String[] args) { // Person p = new Person(); //註冊監聽p對象行為的監聽器 p.registerListener(new PersonListener() { //監聽p吃東西這個行為 public void doeat(Event e) { Person p = e.getSource(); System.out.println(p + "在吃東西"); } //監聽p跑步這個行為 public void dorun(Event e) { Person p = e.getSource(); System.out.println(p + "在跑步"); } }); //p在吃東西 p.eat(); //p在跑步 p.run(); }}
運行結果:
me.gacl.observer.Person@4a5ab2在吃東西
me.gacl.observer.Person@4a5ab2在跑步
二、JavaWeb中的監聽器
2.1、基本概念
JavaWeb中的監聽器是Servlet規範中定義的一種特殊類,它用於監聽web應用程式中的ServletContext, HttpSession和 ServletRequest等域對象的建立與銷毀事件,以及監聽這些域對象中的屬性發生修改的事件。
2.2、Servlet監聽器的分類
在Servlet規範中定義了多種類型的監聽器,它們用於監聽的事件來源分別為ServletContext,HttpSession和ServletRequest這三個域對象
Servlet規範針對這三個對象上的操作,又把多種類型的監聽器劃分為三種類型:
監聽域對象自身的建立和銷毀的事件監聽器。 監聽域對象中的屬性的增加和刪除的事件監聽器。 監聽綁定到HttpSession域中的某個對象的狀態的事件監聽器。
2.3、監聽ServletContext域對象的建立和銷毀
ServletContextListener介面用於監聽ServletContext對象的建立和銷毀事件。實現了ServletContextListener介面的類都可以對ServletContext對象的建立和銷毀進行監聽。
當ServletContext對象被建立時,激發contextInitialized (ServletContextEvent sce)方法。
當ServletContext對象被銷毀時,激發contextDestroyed(ServletContextEvent sce)方法。
ServletContext域對象建立和銷毀時機:
建立:伺服器啟動針對每一個Web應用建立ServletContext
銷毀:伺服器關閉前先關閉代表每一個web應用的ServletContext
範例:編寫一個MyServletContextListener類,實現ServletContextListener介面,監聽ServletContext對象的建立和銷毀
1、編寫監聽器,代碼如下:
package me.gacl.web.listener;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;/*** @ClassName: MyServletContextListener* @Description: MyServletContextListener類實現了ServletContextListener介面,* 因此可以對ServletContext對象的建立和銷毀這兩個動作進行監聽。* @author: 孤傲蒼狼* @date: 2014-9-9 下午10:26:16**/ public class MyServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("ServletContext對象建立"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("ServletContext對象銷毀"); }}
2、在web.xml檔案中註冊監聽器
我們在上面的中講到,要想監聽事件來源,那麼必須將監聽器註冊到事件來源上才能夠實現對事件來源的行為動作進行監聽,在JavaWeb中,監聽的註冊是在web.xml檔案中進行配置的,如下:
index.jsp ServletContextListener監聽器 me.gacl.web.listener.MyServletContextListener
經過這兩個步驟,我們就完成了監聽器的編寫和註冊,Web伺服器在啟動時,就會自動把在web.xml中配置的監聽器註冊到ServletContext對象上,這樣開發好的MyServletContextListener監聽器就可以對ServletContext對象進行監聽了。
2.4、監聽HttpSession域對象的建立和銷毀
HttpSessionListener 介面用於監聽HttpSession對象的建立和銷毀
建立一個Session時,激發sessionCreated (HttpSessionEvent se) 方法
銷毀一個Session時,激發sessionDestroyed (HttpSessionEvent se) 方法。
範例:編寫一個MyHttpSessionListener類,實現HttpSessionListener介面,監聽HttpSession對象的建立和銷毀
1、編寫監聽器,代碼如下:
package me.gacl.web.listener;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;/*** @ClassName: MyHttpSessionListener* @Description: MyHttpSessionListener類實現了HttpSessionListener介面,* 因此可以對HttpSession對象的建立和銷毀這兩個動作進行監聽。* @author: 孤傲蒼狼* @date: 2014-9-9 下午11:04:33**/ public class MyHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { System.out.println( se.getSession() + "建立了!!"); } /* HttpSession的銷毀時機需要在web.xml中進行配置,如下: * 1 這樣配置就表示session在1分鐘之後就被銷毀 */ @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("session銷毀了!!"); }}
2、在web.xml檔案中註冊監聽器
HttpSessionListener監聽器 me.gacl.web.listener.MyHttpSessionListener 1
當我們訪問jsp頁面時,HttpSession對象就會建立,此時就可以在HttpSessionListener觀察到HttpSession對象的建立過程了,我們可以寫一個jsp頁面觀察HttpSession對象建立的過程。
如下:index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
一訪問JSP頁面,HttpSession就建立了,建立好的Session的Id是:${pageContext.session.id}
運行結果如下:
2.5、監聽ServletRequest域對象的建立和銷毀
ServletRequestListener介面用於監聽ServletRequest 對象的建立和銷毀
Request對象被建立時,監聽器的requestInitialized(ServletRequestEvent sre)方法將會被調用
Request對象被銷毀時,監聽器的requestDestroyed(ServletRequestEvent sre)方法將會被調用
ServletRequest域對象建立和銷毀時機:
建立:使用者每一次訪問都會建立request對象
銷毀:當前訪問結束,request對象就會銷毀
範例:編寫一個MyServletRequestListener類,實現ServletRequestListener介面,監聽ServletRequest對象的建立和銷毀
1、編寫監聽器,代碼如下:
package me.gacl.web.listener;import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;/*** @ClassName: MyServletRequestListener* @Description: MyServletRequestListener類實現了ServletRequestListener介面,* 因此可以對ServletRequest對象的建立和銷毀這兩個動作進行監聽。* @author: 孤傲蒼狼* @date: 2014-9-9 下午11:50:08**/ public class MyServletRequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println(sre.getServletRequest() + "銷毀了!!"); } @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println(sre.getServletRequest() + "建立了!!"); }}
2、在web.xml檔案中註冊監聽器
ServletRequestListener監聽器 me.gacl.web.listener.MyServletRequestListener
測試結果如下:
從運行結果中可以看到,使用者每一次訪問都會建立request對象,當訪問結束後,request對象就會銷毀。
以上就是對監聽器的一些簡單講解。