Java Web(五) 監聽器Listener
監聽器概述
在上一篇裏介紹了過濾器Filter,而Listener是Servlet的另一個高級特性。Listener用於監聽Java Web程序中的事件,例如創建,修改,刪除Session,request,context等,並觸發相應的事件。Listener主要用於對Session,request,context等進行監控,目前共有8種Listener,分別完成對不同事件的監聽。
使用Listener不需要關註事件是怎樣觸發的或者怎麽調用相應的Listener,只要記住該類事件觸發時一定會調用相應的Listener。你只需要在Lisener裏編寫相關的代碼就可以。
Servlet3.0以前需要在web.xml中配置,之後直接用@WebListener()註解即可。
<listener>
<listener-class>listener.TestListener</listener-class>
</listener>
監聽對象的創建與銷毀
HttpSessionListener,ServletContextListener,ServletRequestListener分別用來監控Session,context,request的創建於銷毀。觸發時機為:
- HttpSessionListener:創建Session時執行sessionCreatedf方法,超時或者執行session.invalidate()時執行sessionDestroy方法。該Listener可用於收集在線者信息。
- ServletContextListener:服務器啟動或者熱部署war包時執行contextInitialized方法。服務器關閉時執行contextDestroyed方法。該Listener可用於啟動時獲取web.xml裏配置的初始化參數。
- ServletRequest:用戶每次請求時都會執行requestInitialized方法。request處理完畢自動銷毀前執行requestDestroyed方法。
實例:因為java可以繼承多個接口,所以用一個類繼承這三個接口即可。
package listener; /** * Created by kindleheart happily. */ import javax.servlet.*; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; @WebListener public class TestListener implements ServletContextListener, HttpSessionListener, ServletRequestListener { public TestListener() { } //加載context上下文時被調用 public void contextInitialized(ServletContextEvent sce) { ServletContext servletContext = sce.getServletContext(); System.out.println("即將啟動" + servletContext.getContextPath()); } //銷毀context上下文時被調用 public void contextDestroyed(ServletContextEvent sce) { ServletContext servletContext = sce.getServletContext(); System.out.println("即將關閉" + servletContext.getContextPath()); } //創建Session時被調用 public void sessionCreated(HttpSessionEvent se) { HttpSession session = se.getSession(); System.out.println("新創建一個Session,ID為:" + session.getId()); } //銷毀Session時被調用 public void sessionDestroyed(HttpSessionEvent se) { HttpSession session = se.getSession(); System.out.println("銷毀一個Session,ID為:" + session.getId()); } //創建request時被調用 public void requestInitialized(ServletRequestEvent sre) { //存儲創建request時的時間 HttpServletRequest request = (HttpServletRequest) sre.getServletRequest(); request.setAttribute("dateCrated", System.currentTimeMillis()); } //銷毀request時被調用 public void requestDestroyed(ServletRequestEvent sre) { //計算該請求所需時間 HttpServletRequest request = (HttpServletRequest) sre.getServletRequest(); long time = System.currentTimeMillis() - (Long)request.getAttribute("dateCrated"); System.out.println("請求處理結束,用時" + time + "毫秒"); } }
監聽對象屬性的變化
HttpSessionAttributeListener,ServletContextAttributeListener,ServletRequestAttributeListener分別用來監控Session,context,request的屬性變化。在向監聽對象添加,更新,移除屬性時,會分別執行xxxAdded(),xxxReplaced(),xxxRemoved()方法,xxx分別代表Session,context,request。
/**
* Created by kindleheart happily.
*/
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
@WebListener
public class SessionAttributeListenerTest implements HttpSessionAttributeListener {
public SessionAttributeListenerTest() { }
public void attributeAdded(HttpSessionBindingEvent sbe) {
HttpSession session = sbe.getSession();
String name= sbe.getName(); //新添加的屬性名
System.out.println("新建Session屬性:" + name + ",值為:" + sbe.getValue());
}
public void attributeRemoved(HttpSessionBindingEvent sbe) {
HttpSession session = sbe.getSession();
String name= sbe.getName(); //即將刪除的屬性名
System.out.println("刪除Session屬性:" + name + ",值為:" + sbe.getValue());
}
public void attributeReplaced(HttpSessionBindingEvent sbe) {
HttpSession session = sbe.getSession();
String name= sbe.getName(); //發生修改的屬性名
Object oldValue = sbe.getValue(); //原來的屬性值
System.out.println("修改Session屬性:" + name + ",舊值為:" + oldValue +"新值為:" + session.getAttribute(name));
}
}
監聽Session內的對象
除了上面6種Listener,另外還有兩種Listener用於監控Session內的對象,分別是HttpSessionBindingListener與HttpSessionActivationListener。他們觸發的時機為:
- HttpSessionBindingListener:當監聽對象與Session綁定時執行valueBound方法,解綁時執行valueUnbound方法。
- HttpSessionActivationListener:服務器關閉時,會將Session裏的內容保存到硬盤上,這個過程稱為鈍化,執行sessionWillPassivate方法。服務器重新啟動時,會將Session內容從硬盤上重新加載,會執行sessonDidActivate方法。
案例:把User對象與Session綁定時,就會執行相應的方法。
package model;
/**
* Created by kindleheart happily.
*/
import javax.servlet.http.*;
public class User implements HttpSessionBindingListener, HttpSessionActivationListener {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
HttpSession session = se.getSession();
System.out.println(this + "已經成功從硬盤加載。SessionId:" + session.getId());
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
HttpSession session = se.getSession();
System.out.println(this + "即將保存到硬盤。SessionId:" + session.getId());
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
HttpSession session = event.getSession();
String name = event.getName();
System.out.println(this + "被綁定到Session" + session.getId() + "的" + name + "屬性上");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
HttpSession session = event.getSession();
String name = event.getName();
System.out.println(this + "被從Session" + session.getId() + "的" + name + "屬性上移除");
}
}
應用:統計在線人數
用戶第一次訪問服務器時,服務器會創建一個Session,用戶結束訪問時會銷毀這個Session,那麽可以使用HttpSessionListener來統計在線人數。
package util;
/**
* Created by kindleheart happily.
*/
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;
@WebListener()
public class OnlineNumListener implements HttpSessionListener {
private static int userNum = 0;
public OnlineNumListener() {
}
public static int getUserNum() {
return userNum;
}
public void sessionCreated(HttpSessionEvent se) {
userNum++;
}
public void sessionDestroyed(HttpSessionEvent se) {
userNum--;
}
}
在主頁顯示在線人數:
<%@ page import="util.OnlineNumListener" %>
<%@page pageEncoding="utf-8" contentType="text/html; utf-8" language="java" isELIgnored="false" %>
<html>
<body>
<h2>我是主頁</h2>
<%
int num = OnlineNumListener.getUserNum();
%>
<h3>在線人數為:</h3>><%=num%>
</body>
</html>
Java Web(五) 監聽器Listener