使用HttpSessionListener介面監聽Session的建立和失效(可以用於統計線上人數)
轉自:http://uule.iteye.com/blog/824115
HttpSessionListener :
Session建立事件發生在每次一個新的session建立的時候,類似地Session失效事件發生在每次一個Session失效的時候。
這個介面也只包含兩個方法,分別對應於Session的建立和失效:
# public void sessionCreated(HttpSessionEvent se);
# public void sessionDestroyed(HttpSessionEvent se);
我的web應用上想知道到底有多少使用者在使用?
在網站中經常需要進行線上人數的統計。過去的一般做法是結合登入和退出功能,即當用戶輸入使用者名稱密碼進行登入的時候計數器加1,然後當用戶點選退出按鈕退出系統的時候計數器減1。這種處理方式存在一些缺點,例如:使用者正常登入後,可能會忘記點選退出按鈕,而直接關閉瀏覽器,導致計數器減1的操作沒有及時執行;網站上還經常有一些內容是不需要登入就可以訪問的,在這種情況下也無法使用上面的方法進行線上人數統計。
我們可以利用Servlet規範中定義的事件監聽器(Listener)來解決這個問題,實現更準確的線上人數統計功能。對每一個正在訪問的使用者,J2EE應用伺服器會為其建立一個對應的HttpSession物件。當一個瀏覽器第一次訪問網站的時候,J2EE應用伺服器會新建一個HttpSession物件
- import javax.servlet.http.HttpSessionListener;
-
import javax.servlet.http.HttpSessionEvent;
- public class SessionCounter implements HttpSessionListener {
- private static int activeSessions =0;
- /* Session建立事件 */
- public void sessionCreated(HttpSessionEvent se) {
- ServletContext ctx = event.getSession( ).getServletContext( );
-
Integer numSessions = (Integer) ctx.getAttribute("numSessions"
- if (numSessions == null) {
- numSessions = new Integer(1);
- }
- else {
- int count = numSessions.intValue( );
- numSessions = new Integer(count + 1);
- }
- ctx.setAttribute("numSessions", numSessions);
- }
- /* Session失效事件 */
- public void sessionDestroyed(HttpSessionEvent se) {
- ServletContext ctx=se.getSession().getServletContext();
- Integer numSessions = (Integer)ctx.getAttribute("numSessions");
- <span class="oblog_text"> if(numSessions == null)
- numSessions = new Integer(0);
- }
- else {
- int count = numSessions.intValue( );
- numSessions = new Integer(count - 1);
- }
- ctx.setAttribute("numSessions", numSessions);</span>
- }
- }
在這個解決方案中,任何一個Session被建立或者銷燬時,都會通知SessionCounter 這個類,當然通知的原因是必須在web.xml檔案中做相關的配置工作。如下面的配置程式碼:
Java程式碼- <listener>
- <listener-class>demo.listener.SessionCounter</listener-class>
- </listener>
以下兩種情況下就會發生sessionDestoryed(會話銷燬)事件:
1.執行session.invalidate()方法時 。
既然LogoutServlet.java中執行session.invalidate()時,會觸發sessionDestory()從線上使用者 列表中清除當前使用者,我們就不必在LogoutServlet.java中對線上列表進行操作了,所以LogoutServlet.java的內容現在是 這樣。
- public void doGet(HttpServletRequest request,HttpServletResponse response)
- throws ServletException, IOException {
- // 銷燬session
- request.getSession().invalidate();
- // 成功
- response.sendRedirect("index.jsp");
- }
2.
如果使用者長時間沒有訪問伺服器,超過了會話最大超時時間 ,伺服器就會自動銷燬超時的session。
會話超時時間可以在web.xml中進行設定,為了容易看到超時效果,我們將超時時間設定為最小值。
- <session-config>
- <session-timeout>1</session-timeout>
- </session-config>
時間單位是一分鐘,並且只能是整數,如果是零或負數,那麼會話就永遠不會超時。
2.HttpSessionEvent
這是類代表一個web應用程式內更改會話事件通知。
Java程式碼- public class ShopSessionListener implements HttpSessionListener {
- public void sessionCreated(HttpSessionEvent se) {
- }
- public void sessionDestroyed(HttpSessionEvent se) {
- String sessionid = se.getSession().getId();
- EopSite site =(EopSite)ThreadContextHolder.getSessionContext().getAttribute("site_key");
- if(site!=null){
- ICartManager cartManager = SpringContextHolder.getBean("cartManager");
- cartManager.clean(sessionid,site.getUserid(),site.getId());
- }
- }
- }
se.getSession().getId();
HttpSession 介面中的getId():
Returns a string containing the unique identifier assigned to this session.
返回一個字串,其中包含唯一識別符號分配給本次會話。