監聽器概述
監聽器(Listener)是一種特殊的Servlet技術,它可以監聽Web應用的上下文信息、Servlet請求信息和Servlet會話信息,即ServletContext、ServletRequest、HttpSession。並根據不同的情況,在后台調用相應的處理程序。利用監聽器對Web應用進行監聽和控制,來增強Web應用的事件處理能力。
監聽器要用到javax.servlet.jar中的一組監聽接口和事件類,根據監聽對象的不同,監聽器可被划分為3種:
1)ServletContext事件監聽器:用於監聽應用程序環境對象。
2)HttpSession事件監聽器:用於監聽用戶會話對象。
3)ServletRequest事件監聽器:用於監聽請求消息對象。
這3種監聽器共包含了8個監聽接口、6個監聽事件類。
監聽對象 | 監聽接口 | 監聽事件類 |
ServletRequest | ServletRequestListener | ServletRequestEvent |
ServletRequestAttributeListener | ServletRequestAttributeEvent | |
HttpSession | HttpSessionListener | HttpSessionEvent |
HttpSessionActivationListener | ||
HttpSessionAttributeListener | HttpSessionBindingEvent | |
HttpSessionBindingListener | ||
ServletContext | ServletContextListener | ServletContextEvent |
ServletContextAttributeListener | ServletContextAttributeEvent |
監聽器的啟動順序
1)當有多個監聽器時,按各監聽器在web.xml中配置的順序進行先后順序啟動。
2)相較於過濾器、Servlet的啟動順序是:
監聽器>過濾器>Servlet
Listener分類
1)監聽ServletContext對象(對應jsp內置對象——application對象)
對ServletCOntext對象實現監聽,可以監聽到ServletContext對象中屬性的變化(增刪改操作),也可以就監聽到ServletContext對象本身的變化(創建和銷毀)。常見監聽方法:
接口名稱 | 接口方法 | 激發條件 |
ServletContextAttributeListener | public void attributeAdded(ServletContextAttributeEvent scab); | 增加屬性 |
public void attributeRemoved(ServletContextAttributeEvent scab); | 刪除屬性 | |
public void attributeRepalced(ServletContextAttributeEvent scab); | 修改屬性 | |
ServletContextListener | public void contextInitialized(ServletContextEvent sce); | 創建對象 |
public void contextDestroyed(ServletContextEvent sce); | 銷毀對象 |
2)監聽會話(HttpSession對象)(對應jsp內置對象——session對象):
對HttpSession對象實現監聽,可以監聽到HttpSession對象中屬性的變化(增刪改操作),也可以就監聽到HttpSession對象本身的變化(創建和銷毀),以及該對象的狀態,還可以監聽HttpSession對象是否綁定到該監視器對象上。常見監聽方法:
接口名稱 | 接口方法 | 激發條件 |
HttpSessionAttributeListener | public void attributeAdded(HttpSessionBindingEvent se); | 增加屬性 |
public void attributeRemoved(HttpSessionBindingEvent se); | 刪除屬性 | |
public void attributeReplaced(HttpSessionBindingEvent se); | 修改屬性 | |
HttpSessionListener | public void sessionCreated(HttpSessionEvent se); | 創建對象 |
public void sessionDestroyed(HttpSessionEvent se); | 銷毀對象 | |
HttpSessionActivationListener | public void sessionDidActivate(HttpSessionEvent se); | 會話剛被激活 |
public void sessionWillPssivate(HttpSessionEvent se); | 會話將要鈍化 | |
HttpSessionBindingListener | public void valueBound(HttpSessionBindingEvent se); | 調用setAttribute() |
public void valueUnbound(HttpSessionBindingEvent se); | 調用removeAttribute() |
注意1:
活化(Activate)和鈍化(Passivate)是Web容器為了更好地利用系統資源或者進行服務器負載平衡等原因而對特定對象采取的措施。
會話對象的鈍化是指暫時將會話對象通過序列化的方法存儲到硬盤上;
活化與鈍化相反,是把硬盤上存儲的會話對象重新加載到Web容器中。
Tomcat中的兩種鈍化管理器:org.apache.catalina.session.StandardManger和org.apache.catalina.session.Persistentmanger
注意2:
session的銷毀有兩種情況:
(1)session超時,web.xml配置:
<session-config> <session-timeout>120</session-timeout><!--session120分鍾后超時銷毀--> </session-config>
(2)手工使session失效
public void invalidate();//使session失效方法。session.invalidate();
3)監聽請求(ServletRequest對象)(對應jsp內置對象——request對象)
對ServletRequest對象實現監聽,可以監聽到ServletRequest對象中屬性的變化(增刪改操作),也可以就監聽到ServletRequest對象本身的變化(創建和銷毀)。常見監聽方法:
接口名稱 | 接口方法 | 激發條件 |
ServletRequestAttributeListener | public void attributeAdded(ServletRequestAttributeEvent srae); | 增加屬性 |
public void attributeRemoved(ServletRequestAttributeEvent srae); | 刪除屬性 | |
public void attributeReplaced(ServletRequestAttributeEvent srae); | 修改屬性 | |
ServletRequestListener | public void requestInitialized(ServletRequestEvent sre); | 創建對象 |
public void requestDestroyed(ServletRequestEvent sre); | 銷毀對象 |
監聽器設計步驟(實例)
實例:實現在線人數統計。
當一個瀏覽器第一次訪問網站時,服務器會新建一個HttpSession對象,並觸發HttpSession創建事件,如果注冊了HttpSessionListener事件監聽器,則會調用HttpSessionListener事件監聽器的sessionCreated方法。相反,當這個瀏覽器用戶注銷或訪問超時的時候,服務器會銷毀相應的HttpSession對象,觸發HttpSession銷毀事件,同時調用所注冊的HttpSessionListener事件監聽器的sessionDestroyed方法。這樣,只需在HttpSessionListener實現類的sessionCreated方法中讓計數器加1,在sessionDestroyed方法中讓計數器減1,就可以實現網站在線人數的統計功能。(在參考博客中還有其他方法統計網站在線人數,在此不再贅述)
創建實現對應接口的監聽器類:
package com.listener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class OnlineListener implements HttpSessionListener { //定義靜態變量存儲在線人數 private static int onlineCount=0; @Override public void sessionCreated(HttpSessionEvent arg0) { onlineCount++; } @Override public void sessionDestroyed(HttpSessionEvent arg0) { if(onlineCount>0) onlineCount--; } //自定義一個返回在線人數的方法 public static int getOnlineCount(){ return onlineCount; } }
配置web.xml文件(配置相對簡單,只需配置監聽器所在的類,無需配置映射地址)
在servlet 3.0版本及更高版本中,可以使用注解的方式將實現了某個監聽器接口的類聲明為監聽器,即在類名上標注@WebListener。
<!-- 配置監聽器 --> <listener> <listener-class>com.listener.OnlineListener</listener-class> </listener>
創建顯示在線人數的jsp頁面(注意要導入監聽器類所在的包)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="com.listener.*" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>在線人數顯示頁面</title> </head> <body> <h2>當前的在線人數:<%=OnlineListener.getOnlineCount() %></h2> </body> </html>
然后可用不同瀏覽器訪問這一網址,查看運行結果。
參考博客:http://www.cnblogs.com/coderland/p/5902874.html
參考書籍:《Java EE框架開發技術與案例教程 》