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

一、監聽域對象中屬性的變更的監聽器

  域對象中屬性的變更的事件監聽器就是用來監聽 ServletContext, HttpSession, HttpServletRequest 這三個對象中的屬性變更信息事件的監聽器。

   這三個監聽器接口分別是ServletContextAttributeListener, HttpSessionAttributeListener 和ServletRequestAttributeListener,這三個接口中都定義了三個方法來處理被監聽對象中的屬性的增加,刪除和替換的事件, 同一個事件在這三個接口中對應的方法名稱完全相同,只是接受的參數類型不同。

1.1、attributeAdded 方法

  當向被監聽對象中增加一個屬性時,web容器就調用事件監聽器的attributeAdded方法進行響應,這個方法接收一個事件類型的參數,監聽器可以通過這個參數來獲得正在增加屬性的域對象和被保存到域中的屬性對象

  各個域屬性監聽器中的完整語法定義為:

1 public void attributeAdded(ServletContextAttributeEvent scae)

2 public void attributeReplaced(HttpSessionBindingEvent hsbe)

3 public void attributeRmoved(ServletRequestAttributeEvent srae)

1.2、attributeRemoved 方法

  當刪除被監聽對象中的一個屬性時,web容器調用事件監聽器的attributeRemoved方法進行響應

  各個域屬性監聽器中的完整語法定義為:

1 public void attributeRemoved(ServletContextAttributeEvent scae)

2 public void attributeRemoved (HttpSessionBindingEvent hsbe)

3 public void attributeRemoved (ServletRequestAttributeEvent srae)

1.3、attributeReplaced 方法

  當監聽器的域對象中的某個屬性被替換時,web容器調用事件監聽器的attributeReplaced方法進行響應

  各個域屬性監聽器中的完整語法定義為:

1 public void attributeReplaced(ServletContextAttributeEvent scae)

2 public void attributeReplaced (HttpSessionBindingEvent hsbe)

3 public void attributeReplaced (ServletRequestAttributeEvent srae)

1.4、ServletContextAttributeListener監聽器范例:

  編寫ServletContextAttributeListener監聽器監聽ServletContext域對象的屬性值變化情況,代碼如下:

1 package me.gacl.web.listener;

2

3 import java.text.MessageFormat;

4

5 import javax.servlet.ServletContextAttributeEvent;

6 import javax.servlet.ServletContextAttributeListener;

7

8 /** 9 * @ClassName: MyServletContextAttributeListener

10 * @Description: ServletContext域對象中屬性的變更的事件監聽器

11 * @author: 孤傲蒼狼

12 * @date: 2014-9-11 下午10:53:04

13 *

14 */

15 public class MyServletContextAttributeListener implements16 ServletContextAttributeListener {

17

18 @Override

19 public void attributeAdded(ServletContextAttributeEvent scab) {

20 String str =MessageFormat.format(

21 "ServletContext域對象中添加了屬性:{0},屬性值是:{1}"

22 ,scab.getName()

23 ,scab.getValue());

24 System.out.println(str);

25 }

26

27 @Override

28 public void attributeRemoved(ServletContextAttributeEvent scab) {

29 String str =MessageFormat.format(

30 "ServletContext域對象中刪除屬性:{0},屬性值是:{1}"

31 ,scab.getName()

32 ,scab.getValue());

33 System.out.println(str);

34 }

35

36 @Override

37 public void attributeReplaced(ServletContextAttributeEvent scab) {

38 String str =MessageFormat.format(

39 "ServletContext域對象中替換了屬性:{0}的值"

40 ,scab.getName());

41 System.out.println(str);

42 }

43 }

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

1 <listener>2 <description>MyServletContextAttributeListener監聽器</description>3 <listener-class>me.gacl.web.listener.MyServletContextAttributeListener</listener-class>4 </listener>

  編寫ServletContextAttributeListenerTest.jsp測試頁面

1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML> 3 <html> 4 <head> 5 <title>ServletContextAttributeListener監聽器測試</title> 6 </head> 7

8 <body> 9 <%10 //往application域對象中添加屬性

11 application.setAttribute("name", "孤傲蒼狼");

12 //替換application域對象中name屬性的值

13 application.setAttribute("name", "gacl");

14 //移除application域對象中name屬性

15 application.removeAttribute("name");

16 %>17 </body>18 </html>

運行結果如下:

  

  從運行結果中可以看到,ServletContextListener監聽器成功監聽到了ServletContext域對象(application)中的屬性值的變化情況。

1.5、ServletRequestAttributeListener和HttpSessionAttributeListener監聽器范例:

  編寫監聽器監聽HttpSession和HttpServletRequest域對象的屬性值變化情況,代碼如下:

1 package me.gacl.web.listener;

2

3 import java.text.MessageFormat;

4

5 import javax.servlet.ServletRequestAttributeEvent;

6 import javax.servlet.ServletRequestAttributeListener;

7 import javax.servlet.http.HttpSessionAttributeListener;

8 import javax.servlet.http.HttpSessionBindingEvent;

9

10 public class MyRequestAndSessionAttributeListener implements11 HttpSessionAttributeListener, ServletRequestAttributeListener {

12

13 @Override

14 public void attributeAdded(ServletRequestAttributeEvent srae) {

15 String str =MessageFormat.format(

16 "ServletRequest域對象中添加了屬性:{0},屬性值是:{1}"

17 ,srae.getName()

18 ,srae.getValue());

19 System.out.println(str);

20 }

21

22 @Override

23 public void attributeRemoved(ServletRequestAttributeEvent srae) {

24 String str =MessageFormat.format(

25 "ServletRequest域對象中刪除屬性:{0},屬性值是:{1}"

26 ,srae.getName()

27 ,srae.getValue());

28 System.out.println(str);

29 }

30

31 @Override

32 public void attributeReplaced(ServletRequestAttributeEvent srae) {

33 String str =MessageFormat.format(

34 "ServletRequest域對象中替換了屬性:{0}的值"

35 ,srae.getName());

36 System.out.println(str);

37 }

38

39 @Override

40 public void attributeAdded(HttpSessionBindingEvent se) {

41 String str =MessageFormat.format(

42 "HttpSession域對象中添加了屬性:{0},屬性值是:{1}"

43 ,se.getName()

44 ,se.getValue());

45 System.out.println(str);

46 }

47

48 @Override

49 public void attributeRemoved(HttpSessionBindingEvent se) {

50 String str =MessageFormat.format(

51 "HttpSession域對象中刪除屬性:{0},屬性值是:{1}"

52 ,se.getName()

53 ,se.getValue());

54 System.out.println(str);

55 }

56

57 @Override

58 public void attributeReplaced(HttpSessionBindingEvent se) {

59 String str =MessageFormat.format(

60 "HttpSession域對象中替換了屬性:{0}的值"

61 ,se.getName());

62 System.out.println(str);

63 }

64 }

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

1 <listener>2 <description>MyRequestAndSessionAttributeListener監聽器</description>3 <listener-class>me.gacl.web.listener.MyRequestAndSessionAttributeListener</listener-class>4 </listener>

  編寫RequestAndSessionAttributeListenerTest.jsp測試頁面

1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML> 3 <html> 4 <head> 5 <title>RequestAndSessionAttributeListener監聽器測試</title> 6 </head> 7

8 <body> 9 <%10 //往session域對象中添加屬性

11 session.setAttribute("aa", "bb");

12 //替換session域對象中aa屬性的值

13 session.setAttribute("aa", "xx");

14 //移除session域對象中aa屬性

15 session.removeAttribute("aa");

16

17 //往request域對象中添加屬性

18 request.setAttribute("aa", "bb");

19 //替換request域對象中aa屬性的值

20 request.setAttribute("aa", "xx");

21 //移除request域對象中aa屬性

22 request.removeAttribute("aa");

23 %>24 </body>25 </html>

  運行結果如下:

  

  從運行結果中可以看到,HttpSessionAttributeListener監聽器和ServletRequestAttributeListener成功監聽到了HttpSession域對象和HttpServletRequest域對象的屬性值變化情況。

二、感知Session綁定的事件監聽器

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

  Servlet 規范中定義了兩 個特殊的監聽器接口"HttpSessionBindingListener和HttpSessionActivationListener"來幫助 JavaBean 對象了解自己在Session域中的這些狀態: ,實現這兩個接口的類不需要 web.xml 文件中進行注冊。

2.1、HttpSessionBindingListener接口

  實現了HttpSessionBindingListener接口的JavaBean對象可以感知自己被綁定到Session中和 Session中刪除的事件

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

  當對象從HttpSession對象中解除綁定時,web服務器調用該對象的void valueUnbound(HttpSessionBindingEvent event)方法

范例:

1 package me.gacl.domain;

2

3 import javax.servlet.http.HttpSessionBindingEvent;

4 import javax.servlet.http.HttpSessionBindingListener;

5

6 /** 7 * @ClassName: JavaBeanDemo1

8 * @Description:

9 * 實現了HttpSessionBindingListener接口的 JavaBean對象可以感知自己被綁定到 Session中和從Session中刪除的事件

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

11 當對象從 HttpSession 對象中解除綁定時,web 服務器調用該對象的 void valueUnbound(HttpSessionBindingEvent event)方法

12

13 * @author: 孤傲蒼狼

14 * @date: 2014-9-11 下午11:14:54

15 *

16 */

17 public 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 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%@page import=" me.gacl.domain.JavaBeanDemo1"%> 3 <!DOCTYPE HTML> 4 <html> 5 <head> 6 <title></title> 7 </head> 8

9 <body>10 <%

11 //將javabean對象綁定到Session中

12 session.setAttribute("bean",new JavaBeanDemo1("孤傲蒼狼"));

13 //從Session中刪除javabean對象

14 session.removeAttribute("bean");

15 %>16 </body>17 </html>

  運行結果如下:

  

2.2、HttpSessionActivationListener接口

  實現了HttpSessionActivationListener接口的JavaBean對象可以感知自己被活化(反序列化)和鈍化(序列化)的事件

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

  當綁定到HttpSession對象中的javabean對象將要隨HttpSession對象被活化(反序列化)之后,web服務器調用該javabean對象的void sessionDidActive(HttpSessionEvent event)方法。這樣javabean對象就可以知道自己將要和 HttpSession對象一起被反序列化(活化)回到內存中

范例:

1 package me.gacl.domain;

2

3 import java.io.Serializable;

4

5 import javax.servlet.http.HttpSessionActivationListener;

6 import javax.servlet.http.HttpSessionEvent;

7

8 /** 9 * @ClassName: JavaBeanDemo2

10 * @Description:

11 實現了HttpSessionActivationListener接口的 JavaBean 對象可以感知自己被活化和鈍化的事件

12 活化:javabean對象和Session一起被反序列化(活化)到內存中。

13 鈍化:javabean對象存在Session中,當服務器把session序列化到硬盤上時,如果Session中的javabean對象實現了Serializable接口

14 那么服務器會把session中的javabean對象一起序列化到硬盤上,javabean對象和Session一起被序列化到硬盤中的這個操作稱之為鈍化

15 如果Session中的javabean對象沒有實現Serializable接口,那么服務器會先把Session中沒有實現Serializable接口的javabean對象移除

16 然后再把Session序列化(鈍化)到硬盤中

17 當綁定到 HttpSession對象中的javabean對象將要隨 HttpSession對象被鈍化之前,

18 web服務器調用該javabean對象對象的 void sessionWillPassivate(HttpSessionEvent event)方法

19 這樣javabean對象就可以知道自己將要和 HttpSession對象一起被序列化(鈍化)到硬盤中

20 當綁定到HttpSession對象中的javabean對象將要隨 HttpSession對象被活化之后,

21 web服務器調用該javabean對象的 void sessionDidActive(HttpSessionEvent event)方法

22 這樣javabean對象就可以知道自己將要和 HttpSession對象一起被反序列化(活化)回到內存中

23 * @author: 孤傲蒼狼

24 * @date: 2014-9-11 下午11:22:35

25 *

26 */

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 }

  為了觀察綁定到HttpSession對象中的javabean對象隨HttpSession對象一起被鈍化到硬盤上和從硬盤上重新活化回到內存中的的過程,我們需要借助tomcat服務器幫助我們完成HttpSession對象的鈍化和活化過程,具體做法如下:

  在WebRoot\META-INF文件夾下創建一個context.xml文件,如下所示:

  

  context.xml文件的內容如下:

1 <Context>2 <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">3 <Store className="org.apache.catalina.session.FileStore" directory="gacl"/>4 </Manager>5 </Context>

  在context.xml文件文件中配置了1分鐘之后就將HttpSession對象鈍化到本地硬盤的一個gacl文件夾中

  jsp測試代碼如下:

1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%@page import="me.gacl.domain.JavaBeanDemo2"%> 3 <!DOCTYPE HTML> 4 <html> 5 <head> 6 <title></title> 7 </head> 8

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

11 <hr/>12 <%

13 session.setAttribute("bean",new JavaBeanDemo2("孤傲蒼狼"));

14 %>15 </body>16 </html>

  訪問這個jsp頁面,服務器就會馬上創建一個HttpSession對象,然后將實現了HttpSessionActivationListener接口的JavaBean對象綁定到session對象中,這個jsp頁面在等待1分鐘之后沒有人再次訪問,那么服務器就會自動將這個HttpSession對象鈍化(序列化)到硬盤上,

  

  我們可以在tomcat服務器的work\Catalina\localhost\JavaWeb_Listener_20140908\gacl文件夾下找到序列化到本地存儲的session,如下圖所示:

  

  當再次訪問這個Jsp頁面時,服務器又會自動將已經鈍化(序列化)到硬盤上HttpSession對象重新活化(反序列化)回到內存中。運行結果如下:

  

?

  JavaWeb開發技術中的監聽器技術的內容就這么多了,在平時的工作中,監聽器技術在JavaWeb項目開發中用得是比較多,因此必須掌握這門技術。

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

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

相關文章

Excel_DATEDIF函數計算工齡、計算年假

基本語法 DATEDIF(開始日期&#xff0c;結束日期&#xff0c;unit) 基本用法&#xff1a; 實戰&#xff1a; 1、計算工齡&#xff1a; 2、計算年假 轉載于:https://www.cnblogs.com/wodexk/p/10799890.html

Cordova - 徹底搞定IOS編譯!

操作系統&#xff1a;OSX10.14 XCode&#xff1a;10.1 Cordova&#xff1a;8.1.2 假設已經配置好了Cordova開發環境&#xff0c;Apple ID你也有&#xff0c;XCode也可以正常工作了&#xff0c;那么就可以繼續看這篇文章了&#xff01; 如果你沒有看我這篇文章&#xff0c;那么你…

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

一、監聽器介紹 1.1、監聽器的概念 監聽器是一個專門用于對其他對象身上發生的事件或狀態改變進行監聽和相應處理的對象&#xff0c;當被監視的對象發生情況時&#xff0c;立即采取相應的行動。監聽器其 實就是一個實現特定接口的普通java程序&#xff0c;這個程序專門用于監聽…

第一期沖刺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…