1、監聽域對象自身的創建和銷燬時間的監聽器,對應方法create和destroy
ServletContext(application:一個web應用只有一個)HttpSession ServletRequest
對應接口:在後面加上Listener
ServletContextListener主要用途:定時器、全局屬性對象、全局數據庫鏈接、加載緩存信息等。
Web-xml中只能配置一個
創建:啓動服務器
銷燬:關閉服務器
可以通過event獲取servletContext,通過它可以調用getInitParameter(name)獲得web.xml中context param(name、value)配置的參數;還可以調用set向application中設置屬性
HttpSessionListener主要用途:統計在線人數、記錄訪問日誌
Web-xml中可配置多個
創建:啓動服務器並訪問web應用的一個頁面
銷燬:1、關閉服務器 2、關閉瀏覽器直到session過期(時間不可量化)3、不關閉瀏覽器,session超時(可在web.xml中配置session-config下session-timeout單位爲分鐘 但該設置並不準確)
ServletRequestListener主要用途:讀取地址欄參數、記錄訪問歷史
也可在web.xml中配置多個
在接收請求時創建後自動銷燬 訪問後即銷燬
2、監聽域對象中的屬性的增加和刪除的事件監聽器,對應方法added、removed、replaced
ServletContextAttributeListener、request、session
Event.getName()
Request.getContextPath()獲得項目名稱
<button οnclick=”location.href=’<%=request.getContextPath()%>/init.jsp’;”>init<button>
3、監聽綁定到HttpSession域中的某個對象的狀態的事件監聽器
HttpSession中的對象狀態:綁定(setAttribute)——>解除綁定(remove) 鈍化(將session持久到存儲器上)——>活化(將存儲器上恢復session)
正常情況下session是存在於服務器內存中的,但當訪問人數過大時會佔用極大內存,這時有個機制就是將不經常使用的session暫時序列化到系統文件系統或是數據庫系統中,當被使用時反序列化到內存中,整個過程由服務器自動完成
Tomcat中兩種Session鈍化管理器
Session鈍化機制由SessionManager管理
Org。Apche。Catalina。Session。StandardManager
A、當Tomcat服務器被關閉或重啓時,tomcat服務器會將當前內存中的Session對象鈍化到服務器文件系統中;
B、另一種情況是web應用程序被重新加載(reload)時,內存中的Session對象也會被鈍化到服務器的文件系統中。
C、鈍化後的文件被保存到:Tomcat安裝路徑
/work/Catalina/hostname/applicationname/SESSION.ser
Org.apche.catalina.session.Persistentmanager
A、首先在鈍化的基礎上進行了擴張。第一種情況如上面1,第二種如上2,第三種情況,可以配置主流內存的Session對象數目,將不長使用的Session對象保存到文件系統或數據庫,當用時再重新加載
B、默認情況下,Tomcat提供兩個鈍化驅動類
Org.apche.Catalina.FileStore和org.apche.Catalina.JDBCStore
兩種接口:(不需要在web.xml中註冊)
創建的實現類是一個javabean
HttpSessionBindingListene
綁定:valueBound方法
解除綁定:valueUnbound方法 event.getName
HttpSessionActivationListener
鈍化:sessionWillPassivate方法
活化:sessionDidActivate event.getSource
在鈍化活化時還務必要實現Serializable
Servlet3.0下監聽器的使用
1、jre1.6 j2ee6.0 web.xml version=3.0
@WebListener(“This is my demo listener”)
該註解用於將類聲明爲監聽器,被其標註的類必須實現至少實現上文1、2中的六個接口之一,這樣就不用在web.xml中配置<listener>了
項目實戰 在線用戶(session數)和人數(IP數)統計
創建一個HttpSessionListener實現類,int變量保存session創建個數,每次創建(++)或銷燬(--)後都將該變量重新設置到servletContext中。因爲request方法可以獲取IP地址(getRemoteAddr()),實現統計IP地址數(一個IP地址可以通過不同瀏覽器訪問增加session數目)
代碼示例:
User : sessionId ip firstAccessTime
public class JudgeSessionId {
public static User getUserBySessionId(ArrayList<User> userList,String sessionId){
if(userList != null){
for(int i = 0 ; i < userList.size() ; i++){
User user = (User)userList.get(i);
if(user.getSessionId().equals(sessionId)){
return user;
}
}
}
return null;
}
}
public class RequestListenerDemoimplements ServletRequestListener {
ArrayList<User> userList = null;
@Override
public void requestDestroyed(ServletRequestEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void requestInitialized(ServletRequestEvent arg0) {
HttpServletRequest request = (HttpServletRequest)arg0.getServletRequest();
String sessionId = request.getSession().getId();
userList = (ArrayList<User>) request.getServletContext().getAttribute("userList");
if(userList ==null){
userList = new ArrayList<User>();
}
if(JudgeSessionId.getUserBySessionId(userList,sessionId) ==null){
User user = new User();
user.setFirstAccessTime(new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").format(new Date()));
user.setIp(request.getRemoteAddr());IP地址
user.setSessionId(sessionId);
userList.add(user);
}
request.getServletContext().setAttribute("userList",userList);
}
}
public class SessionListenerDemoimplements HttpSessionListener {
private int sessionNumber = 0;
@Override
public void sessionCreated(HttpSessionEvent arg0) {
this.sessionNumber++;
System.out.println(arg0.getSession().getId());
arg0.getSession().getServletContext().setAttribute("sessionNumber",this.sessionNumber);
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
this.sessionNumber--;
System.out.println("sessiondestroy");
arg0.getSession().getServletContext().setAttribute("sessionNumber",this.sessionNumber);
ArrayList<User> userList = (ArrayList<User>) arg0.getSession().getServletContext().getAttribute("userList");
String sessionId = arg0.getSession().getId();
User user = JudgeSessionId.getUserBySessionId(userList, sessionId);//集合爲空或集合中沒有該session就返回null
If(userList != null){
userList.remove(user);
}
}
}