javaweb學習總結(四十四)——監聽器(Listener)學習

一、監聽器介紹

1.1、監聽器的概念

  

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

1.2、監聽器案例——監聽window窗口的事件監聽器

1 package me.gacl.listener.demo;

2

3 import java.awt.Frame;

4 import java.awt.event.WindowEvent;

5 import java.awt.event.WindowListener;

6

7 public class Demo1 {

8

9 /**

10 *java的事件監聽機制

11 *1、事件監聽涉及到三個組件:事件源、事件對象、事件監聽器

12 *2、當事件源上發生某一個動作時,它會調用事件監聽器的一個方法,并在調用該方法時把事件對象傳遞進去,

13 * 開發人員在監聽器中通過事件對象,就可以拿到事件源,從而對事件源進行操作。

14 */15 public static void main(String[] args) {

16

17 Frame f = new Frame();

18 f.setSize(400, 400);

19 f.setVisible(true);

20

21 //注冊事件監聽器22 f.addWindowListener(new WindowListener(){

23

24 public void windowActivated(WindowEvent e) {

25

26 }

27

28 public void windowClosed(WindowEvent e) {

29

30 }

31

32 /**

33 * 當window窗體關閉時就會WindowListener這個監聽器監聽到,

34 * 監聽器就會調用windowClosing方法處理window窗體關閉時的動作

35 */36 public void windowClosing(WindowEvent e) {

37 //通過事件對象e來獲取事件源對象38 Frame f = (Frame) e.getSource();

39 System.out.println(f+"窗體正在關閉");

40 f.dispose();

41 }

42

43 public void windowDeactivated(WindowEvent e) {

44

45 }

46

47 public void windowDeiconified(WindowEvent e) {

48

49 }

50

51 public void windowIconified(WindowEvent e) {

52

53 }

54

55 public void windowOpened(WindowEvent e) {

56

57 }

58 });

59 }

60 }

1.3、設計一個可以被別的對象監聽的對象

  我們平時做開發的時候,我們是寫監聽器去監聽其他對象,那么我們如果想設計一個對象,讓這個對象可以被別的對象監聽又該怎么做呢,可以按照嚴格的事件處理模型來設計一個對象,這個對象就可以被別的對象監聽,事件處理模型涉及到三個組件:事件源、事件對象、事件監聽器。

  下面我們來按照事件處理模型來設計一個Person對象,具體代碼如下:

1 package me.gacl.observer;

2

3 /** 4 * @ClassName: Person(事件源)

5 * @Description: 設計一個Person類作為事件源,這個類的對象的行為(比如吃飯、跑步)可以被其他的對象監聽

6 * @author: 孤傲蒼狼

7 * @date: 2014-9-9 下午9:26:06

8 *

9 */

10 public class Person {

11 /** 12 * @Field: listener

13 * 在Person類中定義一個PersonListener變量來記住傳遞進來的監聽器

14 */

15 private PersonListener listener;

16

17 /** 18 * @Method: eat

19 * @Description: 設計Person的行為:吃

20 * @Anthor:孤傲蒼狼

21 *

22 */

23 public void eat() {

24 if (listener != null) {

25 /** 26 * 調用監聽器的doeat方法監聽Person類對象eat(吃)這個動作,將事件對象Event傳遞給doeat方法,

27 * 事件對象封裝了事件源,new Event(this)中的this代表的就是事件源

28 */ 29 listener.doeat(new Event(this));

30 }

31 }

32

33 /** 34 * @Method: run

35 * @Description: 設計Person的行為:跑

36 * @Anthor:孤傲蒼狼

37 *

38 */

39 public void run() {

40 if (listener != null) {

41 /** 42 * 調用監聽器的dorun方法監聽Person類對象run(跑)這個動作,將事件對象Event傳遞給doeat方法,

43 * 事件對象封裝了事件源,new Event(this)中的this代表的就是事件源

44 */ 45 listener.dorun(new Event(this));

46 }

47 }

48

49 /** 50 * @Method: registerListener

51 * @Description: 這個方法是用來注冊對Person類對象的行為進行監聽的監聽器

52 * @Anthor:孤傲蒼狼

53 *

54 * @param listener

55 */

56 public void registerListener(PersonListener listener) {

57 this.listener = listener;

58 }

59 }

60

61 /** 62 * @ClassName: PersonListener(事件監聽器)

63 * @Description: 設計Person類(事件源)的監聽器接口

64 * @author: 孤傲蒼狼

65 * @date: 2014-9-9 下午9:28:06

66 *

67 */

68 interface PersonListener {

69

70 /** 71 * @Method: doeat

72 * @Description: 這個方法是用來監聽Person對象eat(吃)這個行為動作,

73 * 當實現類實現doeat方法時就可以監聽到Person類對象eat(吃)這個動作

74 * @Anthor:孤傲蒼狼

75 *

76 * @param e

77 */

78 void doeat(Event e);

79

80 /** 81 * @Method: dorun

82 * @Description: 這個方法是用來監聽Person對象run(跑)這個行為動作,

83 * 當實現類實現dorun方法時就可以監聽到Person類對象run(跑)這個動作

84 * @Anthor:孤傲蒼狼

85 *

86 * @param e

87 */

88 void dorun(Event e);

89

90 }

91

92 /** 93 * @ClassName: Event(事件對象)

94 * @Description:設計事件類,用來封裝事件源

95 * @author: 孤傲蒼狼

96 * @date: 2014-9-9 下午9:37:56

97 *

98 */

99 class Event {

100

101 /**102 * @Field: source

103 * 事件源(Person就是事件源)

104 */

105 private Person source;

106

107 public Event() {

108

109 }

110

111 public Event(Person source) {

112 this.source = source;

113 }

114

115 public Person getSource() {

116 return source;

117 }

118

119 public void setSource(Person source) {

120 this.source = source;

121 }

122 }

  經過這樣的設計之后,Peron類的對象就是可以被其他對象監聽了。測試代碼如下:

1 package me.gacl.observer;

2

3 public class PersonTest {

4

5 /** 6 * @Method: main

7 * @Description: 測試Person類

8 * @Anthor:孤傲蒼狼

9 *

10 * @param args

11 */12 public static void main(String[] args) {

13 //

14 Person p = new Person();

15 //注冊監聽p對象行為的監聽器16 p.registerListener(new PersonListener() {

17 //監聽p吃東西這個行為18 public void doeat(Event e) {

19 Person p = e.getSource();

20 System.out.println(p + "在吃東西");

21 }

22 //監聽p跑步這個行為23 public void dorun(Event e) {

24 Person p = e.getSource();

25 System.out.println(p + "在跑步");

26 }

27 });

28 //p在吃東西29 p.eat();

30 //p在跑步31 p.run();

32 }

33 }

運行結果:

  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規范針對這三個對象上的操作,又把多種類型的監聽器劃分為三種類型:

  1. 監聽域對象自身的創建和銷毀的事件監聽器。

  2. 監聽域對象中的屬性的增加和刪除的事件監聽器。

  3. 監聽綁定到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、編寫監聽器,代碼如下:

1 package me.gacl.web.listener;

2

3 import javax.servlet.ServletContextEvent;

4 import javax.servlet.ServletContextListener;

5

6 /** 7 * @ClassName: MyServletContextListener

8 * @Description: MyServletContextListener類實現了ServletContextListener接口,

9 * 因此可以對ServletContext對象的創建和銷毀這兩個動作進行監聽。

10 * @author: 孤傲蒼狼

11 * @date: 2014-9-9 下午10:26:16

12 *

13 */

14 public class MyServletContextListener implements ServletContextListener {

15

16 @Override

17 public void contextInitialized(ServletContextEvent sce) {

18 System.out.println("ServletContext對象創建");

19 }

20

21 @Override

22 public void contextDestroyed(ServletContextEvent sce) {

23 System.out.println("ServletContext對象銷毀");

24 }

25 }

  2、在web.xml文件中注冊監聽器

  我們在上面的中講到,要想監聽事件源,那么必須將監聽器注冊到事件源上才能夠實現對事件源的行為動作進行監聽,在JavaWeb中,監聽的注冊是在web.xml文件中進行配置的,如下:

1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="3.0"

3 xmlns="http://java.sun.com/xml/ns/javaee"

4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

6 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 7 <display-name></display-name>

8 <welcome-file-list> 9 <welcome-file>index.jsp</welcome-file>10 </welcome-file-list>11

12 <!-- 注冊針對ServletContext對象進行監聽的監聽器 -->13 <listener>14 <description>ServletContextListener監聽器</description>15 <!--實現了ServletContextListener接口的監聽器類 -->16 <listener-class>me.gacl.web.listener.MyServletContextListener</listener-class>17 </listener>18

19 </web-app>

  經過這兩個步驟,我們就完成了監聽器的編寫和注冊,Web服務器在啟動時,就會自動把在web.xml中配置的監聽器注冊到 ServletContext對象上,這樣開發好的MyServletContextListener監聽器就可以對ServletContext對象進 行監聽了。

2.4、監聽HttpSession域對象的創建和銷毀

  HttpSessionListener 接口用于監聽HttpSession對象的創建和銷毀

  創建一個Session時,激發sessionCreated (HttpSessionEvent se) 方法

  銷毀一個Session時,激發sessionDestroyed (HttpSessionEvent se) 方法。

范例:編寫一個MyHttpSessionListener類,實現HttpSessionListener接口,監聽HttpSession對象的創建和銷毀

  1、編寫監聽器,代碼如下:

1 package me.gacl.web.listener;

2

3 import javax.servlet.http.HttpSessionEvent;

4 import javax.servlet.http.HttpSessionListener;

5

6 /** 7 * @ClassName: MyHttpSessionListener

8 * @Description: MyHttpSessionListener類實現了HttpSessionListener接口,

9 * 因此可以對HttpSession對象的創建和銷毀這兩個動作進行監聽。

10 * @author: 孤傲蒼狼

11 * @date: 2014-9-9 下午11:04:33

12 *

13 */

14 public class MyHttpSessionListener implements HttpSessionListener {

15

16 @Override

17 public void sessionCreated(HttpSessionEvent se) {

18 System.out.println( se.getSession() + "創建了!!");

19 }

20

21 /* HttpSession的銷毀時機需要在web.xml中進行配置,如下:

22 * <session-config>

23 <session-timeout>1</session-timeout>

24 </session-config>

25 這樣配置就表示session在1分鐘之后就被銷毀

26 */27 @Override

28 public void sessionDestroyed(HttpSessionEvent se) {

29 System.out.println("session銷毀了!!");

30 }

31 }

  2、在web.xml文件中注冊監聽器

1 <!--注冊針對HttpSession對象進行監聽的監聽器--> 2 <listener> 3 <description>HttpSessionListener監聽器</description> 4 <listener-class>me.gacl.web.listener.MyHttpSessionListener</listener-class> 5 </listener> 6 <!-- 配置HttpSession對象的銷毀時機 --> 7 <session-config> 8 <!--配置HttpSession對象的1分鐘之后銷毀 --> 9 <session-timeout>1</session-timeout>10 </session-config>

  當我們訪問jsp頁面時,HttpSession對象就會創建,此時就可以在HttpSessionListener觀察到HttpSession對象的創建過程了,我們可以寫一個jsp頁面觀察HttpSession對象創建的過程。

如下:index.jsp

1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %> 2

3 <!DOCTYPE HTML> 4 <html> 5 <head> 6 <title>HttpSessionListener監聽器監聽HttpSession對象的創建</title> 7 </head> 8

9 <body>10 一訪問JSP頁面,HttpSession就創建了,創建好的Session的Id是:${pageContext.session.id}

11 </body>12 </html>

運行結果如下:

  

2.5、監聽ServletRequest域對象的創建和銷毀

  ServletRequestListener接口用于監聽ServletRequest 對象的創建和銷毀

  Request對象被創建時,監聽器的requestInitialized(ServletRequestEvent sre)方法將會被調用

  Request對象被銷毀時,監聽器的requestDestroyed(ServletRequestEvent sre)方法將會被調用

  ServletRequest域對象創建和銷毀時機:

    創建:用戶每一次訪問都會創建request對象

    銷毀:當前訪問結束,request對象就會銷毀

范例:編寫一個MyServletRequestListener類,實現ServletRequestListener接口,監聽ServletRequest對象的創建和銷毀

  1、編寫監聽器,代碼如下:

1 package me.gacl.web.listener;

2

3 import javax.servlet.ServletRequestEvent;

4 import javax.servlet.ServletRequestListener;

5

6 /** 7 * @ClassName: MyServletRequestListener

8 * @Description: MyServletRequestListener類實現了ServletRequestListener接口,

9 * 因此可以對ServletRequest對象的創建和銷毀這兩個動作進行監聽。

10 * @author: 孤傲蒼狼

11 * @date: 2014-9-9 下午11:50:08

12 *

13 */

14 public class MyServletRequestListener implements ServletRequestListener {

15

16 @Override

17 public void requestDestroyed(ServletRequestEvent sre) {

18 System.out.println(sre.getServletRequest() + "銷毀了!!");

19

20 }

21

22 @Override

23 public void requestInitialized(ServletRequestEvent sre) {

24 System.out.println(sre.getServletRequest() + "創建了!!");

25 }

26 }

  2、在web.xml文件中注冊監聽器

1 <!--注冊針對ServletRequest對象進行監聽的監聽器-->2 <listener>3 <description>ServletRequestListener監聽器</description>4 <listener-class>me.gacl.web.listener.MyServletRequestListener</listener-class>5 </listener>

測試結果如下:

  

  從運行結果中可以看到,用戶每一次訪問都會創建request對象,當訪問結束后,request對象就會銷毀。

?

  以上就是對監聽器的一些簡單講解。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249027.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249027.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249027.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

第一期沖刺01

1、我昨天的成就 確定了軟件所滿足的需求 2、遇到什么困難 跟航哥有太多想要實現的&#xff0c;但后續慢慢找到了重點 3、今天的任務 安裝安卓studio 配置好編程所需要的環境 轉載于:https://www.cnblogs.com/zjm15511858030/p/11065660.html

vue無縫滾動的插件開發填坑分享

寫插件的初衷 1.項目經常需要無縫滾動效果&#xff0c;當時寫jq的時候用用msClass這個老插件&#xff0c;相對不上很好用。2.后來轉向vue在vue-awesome沒有找到好的無縫滾動插件&#xff0c;除了配置swiper可以實現但是相對來說太重了&#xff0c;于是自己造了個輪子。 3.在這分…

Spring 注解 @Resource和@Autowired

Resource和Autowired兩者都是做bean的注入使用。 其實Resource并不是Spring的注解&#xff0c;他的包是javax.annotation.Resource 需要導入。但是Spring支持該注解的注入。 共同點&#xff1a;兩者都可以寫在字段和setter方法上。兩者如果都寫在字段上&#xff0c;就不需要寫…

洛谷 P1091 合唱隊型

很容易想到維護一個最長上升子序列和一個最長下降子序列。然后枚舉一個點k&#xff0c;取所有以k結尾的最長上升子序列和以k開頭的最長下降子序列的長度的和中最大的&#xff0c;表示留下的人數。再用總人數減去這個&#xff0c;等于出隊人數 另外類似的一道題&#xff1a;最長…

PHP常用的自定義函數

PHP常用的自定義函數 目錄 php常用自定義函數類下載php 設置字符編碼為utf-8路徑格式化(替換雙斜線為單斜線)轉碼打印輸出api返回信息字符串截取 方法一:方法二:數組 字符串 對象 json格式的字符串互轉強制類型轉換php序列化serialize與返回序列化unserialeze創建日志文件獲取i…

Spring注解@Component、@Repository、@Service、@Controller區別

很長時間沒做web項目都把以前學的那點框架知識忘光了&#xff0c;今天把以前做的一個項目翻出來看一下發現用Component標記一個組件&#xff0c;而網上有的用Service標記組件&#xff0c;我暈就查了一下資料&#xff1a; Spring 2.5 中除了提供 Component 注釋外&#xff0c;還…

春第十周作業

作業&#xff1a; 這個作業屬于那個課程C語言程序設計II這個作業要求在哪里https://edu.cnblogs.com/campus/zswxy/software-engineering-class2-2018/homework/3162我在這個課程的目標是閱讀并學習這個作業在那個具體方面幫助我實現目標知道了我們以后工作所需的是雇主所需的參…

在原生js中的事件監聽方法

一、傳統事件綁定方法我們在學習的時候&#xff0c;最初接觸的事件綁定方式大多是傳統事件綁定方法。傳統事件綁定方法事例如下&#xff1a; window.οnlοadfunction(){alert("頁面已加載"); } document.getElementById("btn").οnclickfunction(){alert(…

MySql修改數據庫編碼為UTF8

mysql 創建 數據庫時指定編碼很重要&#xff0c;很多開發者都使用了默認編碼&#xff0c;亂碼問題可是防不勝防。制定數據庫的編碼可以很大程度上避免倒入導出帶來的亂碼問題。 網頁數據一般采用UTF8編碼&#xff0c;而數據庫默認為latin 。我們可以通過修改數據庫默認編碼方式…

第六次作業(C語言)

心得體會 該題主要涉及知識點有&#xff1a;1、函數的定義&#xff1b;2、函數的調用&#xff08;即prime函數的調用&#xff09;&#xff1b;3、素數的判斷&#xff1b;4、大小排序。 看到題時我首先想到了嵌套循環&#xff0c;可是仔細一看題目要求的是用prime函數的調用&…

Javascript系列——對象元素的數組去重實現

概要 這是一篇記錄文&#xff0c;記錄數組操作對象去重的實現。 需求 有這樣一個數組 [{_id: 123,name: 張三 },{_id: 124,name: 李四 },{_id: 123,name: 張三 }] 實際上我們只需要 [{_id: 123,name: 張三 },{_id: 124,name: 李四 }] 去重 簡單數組的去重 Array.from(new Set([…

關于__getattribute__

先看一個案例 class Tree(object):def __init__(self,name):self.namenameself.cateplantdef __getattribute__(self, item):if item大樹:print(log 大樹)return 我愛大樹else:return object.__getattribute__(self,item)aaTree(rrrr) print(aa.name) print(aa.cate) 運行結果…

通過Navicat for MySQL遠程連接的時候報錯mysql 1130的解決方法

來源&#xff1a;互聯網 作者&#xff1a;佚名 時間&#xff1a;10-16 18:41:20 【大 中 小】 錯誤代碼是1130&#xff0c;ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server 是無法給遠程連接的用戶權限問題 Navicat for mysql 1130錯誤 用…

Java Language Changes for Java SE 9

Java9引入了module模塊的概念&#xff0c;是類與接口和數據資源的一種封裝&#xff0c;并可以聲明與其他模塊的依賴關系。這里總結一下Java9帶來的新特性。更簡練的try-with-resources語句final Resource resource1 new Resource("resource1");//a final resourceRe…

ProtocolHandler繼承體系

轉載于:https://www.cnblogs.com/GooPolaris/p/10815072.html

mysql數據庫存儲過程及調用方法

mysql數據庫存儲過程及調用方法 mysql5.0以后就支持存儲過程了&#xff0c;目前mysql的6.0Alpha版也已經推出。6.0不僅支持大型數據庫如oracle等的絕大部分功 能&#xff0c;如存儲過程、視圖、觸發器、job等等&#xff0c;而且修正了這些功能所存在的bug&#xff0c;其中6.0.1…

紅蜻蜓

日本人なら一度は耳にしたことのある曲でしょう。忘れかけている里山の風景が目に浮かびます。このあたりは昔養蠶が盛んで、何処へ行っても桑畑があったものでしたが、最近はとんと見かけません。小さい頃、よく桑の実をつんで食べたものでした。&#xff08;このあたりでは&q…

elastic學習筆記

要點 不同工具之間版本匹配很重要由點及面&#xff0c;先實踐起來再學細節的原理和使用 技術棧 laravel5.5框架scout組件elasticsearch6.3.0搜索引擎輔助 elasticsearch-head 查看集群數據可視化 中文分詞插件Ik介紹 laravel是一款現代化的php框架es是搜索引擎es-head是管理查看…

mysql 存儲過程中limit

mysql 存儲過程中limit 1、mysql的高版本&#xff08;5.5&#xff09;&#xff0c;存儲過程中的limit可以使用變量&#xff0c;如下&#xff1a;select * from student limit iStart,iNum; 2、mysql的低版本&#xff08;5.1&#xff09;&#xff0c;存儲過程中的limit不能使用…

高頻ES6

var promise new Promise((resolve, reject)> {if (操作成功) {resolve (value)}else{reject(error)} }) promise.than(function (value) {/*成功*/}, function(value) {/*失敗*/}) Promise是異步編程的一種解決方案, 比傳統的解決方案--回調函數和事件更加強大.由社區最早…