監聽器
web監聽器
客戶端請求
服務端操作
ServletContext(application)
HttpSession(session)
ServletRequest(request)
servlet規範中定義的一種特殊類
用於監聽servletcontext,httpsession,servletRequest等域對象的創建與銷燬事件
用於監聽域對象的屬性發生修改的事件
在事件發生前後做一些處理
用途
- 統計在線人數和在線用戶
- 統計啓動時加載初始化信息
- 統計網站訪問量
- 跟spring結合
第一個監聽器
步驟
- 創建一個實現監聽器藉口的類(ServletContextListener)
- 配置web.xml進行註冊(Design-outline-listener)
啓動順序
優先級
監聽器>過濾器>Servlet
監聽器
按照監聽對象劃分
- 用於監聽應用程序環境對象 ServletContext
- 用於監聽用戶會話 HttpSession
- 用於監聽請求消息 ServletRequest
監聽事件劃分
- 監聽域對象自身的創建和銷燬
- 監聽域對象中的屬性的增加和刪除
- 監聽綁定到HttpSession域中的某個對象的狀態
ServletContext
用途
- 定時器
- 全局屬性對象
ServletContextEvent對象可以調用一系列的方法
調用獲取初始化參數
String myuser = servletContextEvent.getServletContext().getInitParameter("user");
//web.xml設置
<context-param>
<param-name>user</param-name>
<param-value>juedaiyuer</param-value>
</context-param>
HttpSession事件監聽
用途
- 統計在線人數
- 記錄訪問日誌
實現了HttpSessionListener接口
session服務參數配置
//配置session存活時間
<session-config>
<session-timeout>0</session-timeout>
</session-config>
ServletRequest事件監聽
用途
- 讀取參數
記錄訪問歷史
//後臺日誌顯示的啓動情況(打印刷存在感)
requestInitialized
sessionCreated
requestDestroyed
同理可以根據ServletRequestEvent這個事件對象來獲取request的參數(get一系列的方法)
String myname = servletRequestEvent.getServletRequest().getParameter("name");
url:http://localhost:8080/FirstListener/?name=juedaiyuer
後臺就會獲取到name參數
監聽域對象中屬性的變更的監聽器
域對象中屬性的變更的事件監聽器就是用來監聽 ServletContext, HttpSession, HttpServletRequest 這三個對象中的屬性變更信息事件的監聽器
ServletContext
ServletContext,是一個全局的儲存信息的空間,服務器開始,其就存在,服務器關閉,其才釋放。request,一個用戶可有多個;session,一個用戶一個;而servletContext,所有用戶共用一個
例子
購物網站來說,從數據庫提取物品信息,如果採用session存儲這些物品信息,每一個用戶都需要訪問一次數據庫;採用上下文的話,每一個用戶只需要訪問上下文讀入物品信息即可.
接口
- ServletContextAttributeListener
- HttpSessionAttributeListener
- ServletRequestAttributeListener
接口中定義的方法
屬性的添加,替換,刪除
- attributeAdded
- attributeRemoved
- attributeReplaced
在一個jsp頁面傳遞參數值
request.setAttribute();
getAttribute和getParameter的區別
getParameter必須是url帶參數形式
getAttribute獲取參數的方式只有setAttribute設置參數的時候,才能夠有效
ServletContextAttributeListener
package Listener;
import java.text.MessageFormat;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
public class MyServletContextAttributeListener implements
ServletContextAttributeListener {
public void attributeAdded(ServletContextAttributeEvent arg0) {
// TODO Auto-generated method stub
String str = MessageFormat.format("ServletContext域對象中添加了屬性:{0} 屬性值:{1}",arg0.getName(),arg0.getValue());
System.out.println(str);
}
public void attributeRemoved(ServletContextAttributeEvent arg0) {
// TODO Auto-generated method stub
String str = MessageFormat.format("ServletContext域對象中刪除了屬性:{0} 屬性值:{1}",arg0.getName(),arg0.getValue());
System.out.println(str);
}
public void attributeReplaced(ServletContextAttributeEvent arg0) {
// TODO Auto-generated method stub
String str = MessageFormat.format("ServletContext域對象中替換了屬性:{0} ",arg0.getName());
System.out.println(str);
}
}
web.xml配置
Test.jsp添加測試片段
<%
application.setAttribute("name", "juedaiyuer");
application.setAttribute("name", "zhanhunyiran");
application.removeAttribute("name");
%>
HttpSessionAttributeListener
<%
session.setAttribute("user", "user01");
session.setAttribute("user", "user02");
session.removeAttribute("user");
%>
ServletRequestAttributeListener
<%
request.setAttribute("user", "user01");
request.setAttribute("user", "user02");
request.removeAttribute("user");
%>
綁定HttpSession監聽器
Session鈍化機制
session一般情況存儲於內存,當用戶達到一定數量級,會影響到服務器性能,採用的鈍化機制.
本質在於把服務器中不經常使用的session對象暫時序列化到文件系統中或者是數據庫系統中,當被使用時反序列化到內存中,整個過程由服務器自動完成.
tomcat鈍化管理器
session鈍化機制由SessionManager管理
實際開發用到的並不是很多
org.apache.catalina.session.StandardManager
- 當Tomcat服務器被關閉或重啓時,tomcat服務器會將當前內存中的session對象鈍化到服務器文件系統中
- 另一種情況是web應用程序被重新加載時,內存中的session對象也會被鈍化到文件系統中
- 鈍化後的文件被保存: tomcat安裝路徑:/work/Catalina/hostname/applicationname/SESSION.ser
org.apache.catalina.session.Persistentmanager管理
- 同上
- 配置主流內存的Session對象數目,將不常使用的session對象保存在文件系統或數據庫中,當用到的時候重新加載
- 默認情況下,tomcat提供兩個鈍化驅動類
- org.apache.Catalina.FileStore和org.apache.Catalina.JDBCStore
接口
HttpSessionBindingListener
提供方法:
綁定:valueBound方法
解除綁定:valueUnbound方法
HttpSessionActivationListener
提供方法:
1. 鈍化 sessionWillPassivate
2. 活化 sessionDidActivate
不需要在web.xml文件中註冊
創建一個javabean
HttpSessionBindingListener的示例
用myEclipse創建一個類實現HttpSessionBindingListener接口
package entity;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class User implements HttpSessionBindingListener {
private String username;
private String password;
public void valueBound(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
System.out.println("valueBound---name:"+arg0.getName());
}
public void valueUnbound(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
System.out.println("valueUnbound---name:"+arg0.getName());
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
<%@page import="entity.User"%>
session.setAttribute("currentUser", new User());
session.removeAttribute("currentUser");
HttpSessionActivationListener的示例
javabean
package entity;
import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
public class User2 implements HttpSessionActivationListener,Serializable {
private String name;
private static final long serialUID = 1;
public void sessionDidActivate(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("活化到硬盤,session的id:"+se.getSession().getId());
}
public void sessionWillPassivate(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("鈍化到硬盤,session的id:"+se.getSession().getId());
}
public User2(String name)
{
this.name = name;
}
}
servlet3.0監聽器使用
@WebListener
該註解用於將類聲明爲監聽器,被@WebListener標註的類必須實現以下至少一個接口
*Listener
無法定義監聽器的順序
統計在線用戶及人數
統計在線人數
package manager;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class MySessionManger implements HttpSessionListener {
private int userNumber;
@Override
public void sessionCreated(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
userNumber++;
arg0.getSession().getServletContext().setAttribute("userNum", userNumber);
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
userNumber--;
arg0.getSession().getServletContext().setAttribute("userNum", userNumber);
}
}
將在線用戶數保存在上下文
使用了EL表達式
當前用戶在線人數${userNum}
統計在線用戶
統計訪問者的來源(ip),使用request對象