一. 簡介
定義:
1. servlet規範中定義的一種特殊類
2. 用于監聽ServletContext , HttpSession , 和ServletRequest等域對象的建立與銷毀事件
3. 用于監聽域對象的屬性發生修改的事件
4. 在事件發生之前、發生後做一些必要的處理。
應用:
統計線上人數;系統初始化時加載初始化資訊;統計網站通路量
二. 分類
按監聽的事件可分為以下三種:
1.監聽域對象自身的建立和銷毀的事件監聽器
1)ServletContent–實作ServletContextListener接口
可以用于做定時器,可以通過擷取web.xml中的
<content param>
初始化參數來加載全局屬性對象
2)HttpSession–實作HttpSessionListener接口
可以用于統計線上人數和記錄通路日志
3)ServletRequest–實作ServletRequestListener接口
可以用于讀取request裡的參數,記錄通路曆史
2.監聽域對象中的屬性的增加和删除的事件監聽器
1)ServletContent–實作ServletContextAttributeListner接口
2)HttpSession–實作HttpSessionAttributeListner接口
3)ServletRequest–實作ServletRequestAttributeListner接口
其内部有attributeAdded(),attributeRemoved()和attributeReplaced()方法,可通過傳進來的參數對增添,删除或修改的屬性進行操作
3.監聽綁定到HttpSession域中的某個對象的狀态的事件監聽器
HttpSession 中對象的狀态包括 綁定-解除綁定,鈍化-活化
1..綁定-解除綁定
實際上就是通過setAttribute()和removeAttribute()方法将屬性在session中存儲或移除
對該狀态監聽要實作的是HttpSessionBindingListener接口,分别對應valueBound()方法和valueUnbound()方法
2..鈍化-活化
正常情況下,session是存在于伺服器的記憶體中的,但是如果出現很多使用者同時線上的情況,伺服器記憶體的開銷将是巨大的,會直接影響伺服器的性能,session的鈍化機制可以有效的解決這個問題:web伺服器将不經常使用的session對象序列化到儲存設備中,當使用到的時候再将其進行恢複,反序列化到記憶體當中,整個過程由伺服器自動完成
對該狀态監聽要實作的是HttpSessionActavationListener和Serializable接口,兩種狀态分别對應sessionWillPassivate()方法和sessionDidActivate()方法
注意:
- 使用以上兩種監聽器應該是在javabean的類中實作相應的接口,而不是直接建立監聽器
- 以上兩種監聽器不需要在web.xml中注冊
三. 統計線上使用者和人數
需求:統計線上使用者人數,及線上使用者的ip
分析:統計線上人數可以通過session對象的建立進行統計,擷取使用者ip可以通過request對象擷取
1..MyHttpSessionListener.java –監聽Session對象的建立及銷毀
package lisener;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import entity.User;
public class MyHttpSessionListener implements HttpSessionListener {
private int usernumber = ;
public void sessionCreated(HttpSessionEvent se) {
usernumber++;
se.getSession().getServletContext().setAttribute("usernumber", usernumber);
}
public void sessionDestroyed(HttpSessionEvent se) {
usernumber--;
se.getSession().getServletContext().setAttribute("usernumber", usernumber);
//該會話結束,需将該使用者從使用者清單中删除
ArrayList<User> userlist = (ArrayList<User>)se.getSession().getServletContext().getAttribute("userlist");
String sessionId = null;
if((sessionId = se.getSession().getId())!=null)
{
for (User user : userlist) {
if(user.getSessionId().equals(sessionId)){ //該使用者存在于使用者清單中
userlist.remove(user);
}
}
}
}
}
2..MyServletRequestListener.java – 擷取request對象中存儲的資訊
package lisener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.SimpleFormatter;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import entity.User;
public class MyServletRequestListener implements ServletRequestListener{
private ArrayList<User> userlist; //建立線上使用者清單
public void requestDestroyed(ServletRequestEvent sre) {
}
public void requestInitialized(ServletRequestEvent sre) {
userlist = (ArrayList<User>)sre.getServletContext().getAttribute("userlist");
if(userlist==null)
userlist = new ArrayList<User>();
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
String sessionId = request.getSession().getId();
for (User user : userlist) {
if(user.getSessionId().equals(sessionId)){ //該使用者存在于使用者清單中
return;
}
}
//建立使用者,初始化資訊,存到使用者清單中
User user = new User();
user.setSessionId(sessionId);
user.setIp(request.getRemoteAddr());
user.setLoadtime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
userlist.add(user);
sre.getServletContext().setAttribute("userlist", userlist);
}
}
3..User.java –使用者實體類
package entity;
public class User {
private String sessionId;
private String ip;
private String loadtime;
setter,getter方法。。。。
}
4..index.jsp–表示層
(需導入User類)
<body>
目前線上使用者人數:<%=request.getSession().getServletContext().getAttribute("usernumber") %><br/>
<%
ArrayList<User> userlist = (ArrayList<User>)request.getSession().getServletContext().getAttribute("userlist");
if(userlist!=null){
for (User user : userlist) {
%>
ip:<%=user.getIp() %><br>
loadtime:<%=user.getLoadtime() %><br>
<%
}
}
%>
</body>