用HttpSessionListener與HttpSessionBindingListener實現線上人數統計

來源:互聯網
上載者:User

標籤:ica   import   ring   xml配置   www   對象   min   tom   維護   

作者1:try出愛的異常

作者2:長安散人

      下午比較閑(其實今天都很閑),想了一下線上人數統計方面的實現,上網找了下這方面的知識,最初我的想法是,管理session,如果session銷毀了就減少,如果登陸使用者了就新增一個,但是如果是使用者非法退出,如:未登出,關閉瀏覽器等,這個使用者的session是管理不到的,最後決定用HttpSessionListener介面或HttpSessionBindingListener介面來實現,通過監聽session的建立和銷毀來控制,詳細如下。

先添加登陸的頁面index.jsp

<%@ page contentType="text/html;charset=utf-8"%><html><head><title>test</title>              </head><body><form action="login.jsp" method="post">    使用者名稱:<input type="text" name="username" />    <br />    <input type="submit" value="登入" /></form></body></html>

點擊登陸後跳轉的login.jsp(為了方便,用jsp做servlet,同學們用的時候記得改過來)

<%@ page contentType="text/html;charset=utf-8"%><%@ page import="java.util.*"%><%    request.setCharacterEncoding("UTF-8");    // 取得登入的使用者名稱    String username = request.getParameter("username");    // 把使用者名稱儲存進session    session.setAttribute("username", username);    // 把使用者名稱放入線上列表    List onlineUserList = (List) application.getAttribute("onlineUserList");    // 第一次使用前,需要初始化    if (onlineUserList == null) {        onlineUserList = new ArrayList();        application.setAttribute("onlineUserList", onlineUserList);    }    onlineUserList.add(username);    // 成功    response.sendRedirect("result.jsp");%>

登陸成功跳轉到顯示頁面result.jsp

<%@ page contentType="text/html;charset=utf-8"%><%@ page isELIgnored="false"%><%@page import="java.util.List"%><h3>您好:${username} [<a href="logout.jsp">登出</a>]</h3>當前線上使用者:<table><%    List onlineUserList = (List) application.getAttribute("onlineUserList");    for (int i = 0; i < onlineUserList.size(); i++) {    String onlineUsername = (String) onlineUserList.get(i);%>    <tr>        <td><%=onlineUsername%></td>    </tr><%}%></table>

點擊登出頁面logout.jsp頁面

<%@ page contentType="text/html;charset=utf-8"%><%@ page import="java.util.*"%><%    // 取得登入的使用者名稱    String username = (String) session.getAttribute("username");    // 銷毀session    session.invalidate();    // 從線上列表中刪除使用者名稱    List onlineUserList = (List) application.getAttribute("onlineUserList");    onlineUserList.remove(username);    // 成功    response.sendRedirect("index.jsp");%>

OK,登陸、查看、登出頁面都有了,下面開始建立監聽器

1、HttpSessionListener

添加類OnlineUserListener,繼承HttpSessionListener,HttpSessionListener中有兩個方法sessionCreated(HttpSessionEvent event)與sessionDestroyed(HttpSessionEvent event),前者是監聽session的建立,後者是監聽session的銷毀。

 OnlineUserListener代碼如下:

package com.test;import java.util.List;import javax.servlet.ServletContext;import javax.servlet.http.HttpSession;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;/** * @author 版本 */public class OnlineUserListener implements HttpSessionListener {public void sessionCreated(HttpSessionEvent event) {System.out.println("建立session:"+event.getSession().getId());}public void sessionDestroyed(HttpSessionEvent event) {HttpSession session = event.getSession();        ServletContext application = session.getServletContext();        // 取得登入的使用者名稱        String username = (String) session.getAttribute("username");        // 從線上列表中刪除使用者名稱        List onlineUserList = (List) application.getAttribute("onlineUserList");        onlineUserList.remove(username);        System.out.println(username+"已經退出!");}}

web.xml配置:

<listener>  <listener-class>com.test.OnlineUserListener</listener-class></listener>

一旦監聽器發現調用了sessionDestoryed方法就會把其使用者從線上人數中delete,在下面兩種情況下會發生sessionDestoryed事件

a.執行session.invalidate()方法時

logout.jsp中調用了 session.invalidate()方法

b.session會話逾時

session的預設逾時事件是30分鐘,30分鐘後自動銷毀session

2、HttpSessionBindingListener

HttpSessionBindingListener雖然叫做監聽器,但使用方法與HttpSessionListener完全不同。我們實際看一下它是如何使用的。

建立類OnlineUserBindingListener,實現HttpSessionBindingListener介面,構造方法傳入username參數,HttpSessionBindingListener內有兩個方法valueBound(HttpSessionBindingEvent event)和valueUnbound(HttpSessionBindingEvent event),前者為資料繫結,後者為取消綁定

所謂對session進行資料繫結,就是調用session.setAttribute()把HttpSessionBindingListener儲存進session中。

在login.jsp中做這一步:

<%@page import="com.test.OnlineUserBindingListener"%><%@ page contentType="text/html;charset=utf-8"%><%@ page import="java.util.*"%><%    request.setCharacterEncoding("UTF-8");    // 取得登入的使用者名稱    String username = request.getParameter("username");       // 把使用者名稱放入線上列表    session.setAttribute("onlineUserBindingListener", new OnlineUserBindingListener(username));    // 成功    response.sendRedirect("result.jsp");%>

這就是HttpSessionBindingListener和HttpSessionListener之間的最大區別:HttpSessionListener只需要設定到web.xml中就可以監聽整個應用中的所有session。HttpSessionBindingListener必須執行個體化後放入某一個session中,才可以進行監聽。

從監聽範圍上比較,HttpSessionListener設定一次就可以監聽所有session,HttpSessionBindingListener通常都是一對一的。

正是這種區別成就了HttpSessionBindingListener的優勢,我們可以讓每個listener對應一個username,這樣就不需要每次再去session中讀取username,進一步可以將所有操作線上列表的代碼都移入listener,更容易維護。

HttpSessionBindingListener代碼如下:

package com.test;import java.util.ArrayList;import java.util.List;import javax.servlet.ServletContext;import javax.servlet.http.HttpSession;import javax.servlet.http.HttpSessionBindingEvent;import javax.servlet.http.HttpSessionBindingListener;public class OnlineUserBindingListener implements HttpSessionBindingListener {String username;public OnlineUserBindingListener(String username){this.username=username;}public void valueBound(HttpSessionBindingEvent event) {HttpSession session = event.getSession();    ServletContext application = session.getServletContext();    // 把使用者名稱放入線上列表    List onlineUserList = (List) application.getAttribute("onlineUserList");    // 第一次使用前,需要初始化    if (onlineUserList == null) {        onlineUserList = new ArrayList();        application.setAttribute("onlineUserList", onlineUserList);    }    onlineUserList.add(this.username);}public void valueUnbound(HttpSessionBindingEvent event) {HttpSession session = event.getSession();    ServletContext application = session.getServletContext();    // 從線上列表中刪除使用者名稱    List onlineUserList = (List) application.getAttribute("onlineUserList");    onlineUserList.remove(this.username);    System.out.println(this.username + "退出。");}}

這裡可以直接使用listener的username操作線上列表,不必再去擔心session中是否存在username。

valueUnbound的觸發條件是以下三種情況:

a.執行session.invalidate()時。

b.session逾時,自動銷毀時。

c.執行session.setAttribute("onlineUserListener", "其他對象");或session.removeAttribute("onlineUserListener");將listener從session中刪除時。

因此,只要不將listener從session中刪除,就可以監聽到session的銷毀。

附註: Java設定session逾時(失效)的三種方式

1.      在web容器中設定(此處以tomcat為例)

在tomcat-5.0.28\conf\web.xml中設定,以下是tomcat 5.0中的預設配置:

  1. <!-- ==================== Default Session Configuration ================= -->  
  2.   <!-- You can set the default session timeout (in minutes) for all newly   -->  
  3.   <!-- created sessions by modifying the value below.    -->  
  4.     <session-config>  
  5.         <session-timeout>30</session-timeout>  
  6. </session-config>  

Tomcat預設session逾時時間為30分鐘,可以根據需要修改,負數或0為不限制session失效時間。 

2.      在工程的web.xml中設定

  1. <!-- 時間單位為分鐘   -->  

<session-config>

      <session-timeout>15</session-timeout>

</session-config>

3.      通過Java代碼設定

session.setMaxInactiveInterval(30*60);//以秒為單位

三種方式優先順序:1 < 2 <3

用HttpSessionListener與HttpSessionBindingListener實現線上人數統計

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.