天天看點

監聽器一. 簡介二. 分類三. 統計線上使用者和人數

一. 簡介

定義:

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>
           

繼續閱讀