本文在springboot 的項目,用HttpSessionListener 監聽器(監聽器的其中一種) 統計在線人數,實質是統計session 的數量。
思路很簡單,但是有個細節沒處理好,讓我調試了大半天,才把bug搞好。
先寫個HttpSessionListener 監聽器。count 是session的數量(人數),session 創建的時候,會觸發監聽器的sessionCreated 方法,session銷毀的時候,會觸發監聽器的sessionDestroyed 方法。 在監聽器中計算完人數count,把他放進servletContext(可以理解為一個倉庫,任意請求可以存儲和獲取里面的屬性)。
注意監聽器加上@WebListener,這樣就不用配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@WebListener public class OnLineCount implements HttpSessionListener { public int count= 0 ; //記錄session的數量 //監聽session的創建,synchronized 防并發bug public synchronized void sessionCreated(HttpSessionEvent arg0) { System.out.println( "【HttpSessionListener監聽器】count++ 增加" ); count++; arg0.getSession().getServletContext().setAttribute( "count" , count); } @Override public synchronized void sessionDestroyed(HttpSessionEvent arg0) { //監聽session的撤銷 System.out.println( "【HttpSessionListener監聽器】count-- 減少" ); count--; arg0.getSession().getServletContext().setAttribute( "count" , count); } } |
接著寫一個查詢session 數量的controller,我開始的時候是像下面這樣寫的,是錯誤的!
從servletContext 中取出count ,把count返回前端。
1
2
3
4
5
6
|
@RequestMapping ( "/count" ) @ResponseBody public String count(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){ Object count=httpServletRequest.getServletContext().getAttribute( "count" ); return "count : " +count; } |
這樣是錯誤的,測試你會發現,頁面看到count 是null ,因為沒有創建session,沒有觸發監聽器的統計方法。于是改一下:
1
2
3
4
5
6
7
8
9
10
|
@Controller public class IndexController { @RequestMapping ( "/count" ) @ResponseBody public String count(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){ HttpSession session = httpServletRequest.getSession(); Object count=session.getServletContext().getAttribute( "count" ); return "count : " +count; } } |
HttpSession session = httpServletRequest.getSession(); 作用:該用戶如果沒有sesision則創建session ,有則取得session不創建。
改成這樣測試,看起來是對的,但是有個問題。一個瀏覽器對應一個session,你打開2個瀏覽器,看到count是2 ,是對的。但是你關了一個瀏覽器,再打開,應該是2不變才對,但是變成3 了,原因是session銷毀的方法沒有執行,重新打開時,服務器找不到用戶原來的session ,重新創建了一個session,于是有3個session了,但是瀏覽器只有2個,也就是模擬應該是只有2個人在線上。
有2個方法可以解決這個問題,一個是在關閉網頁的時候,前端去調用一個方法把session銷毀。另一個更好的方法是,讓服務器記得原來那個session,即把原來的sessionId 記錄在瀏覽器,下次打開時,把這個sessionId發送過去,這樣服務器就不會重新創建。
代碼修改如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@Controller public class IndexController { @RequestMapping ( "/count" ) @ResponseBody public String number(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){ try { //把sessionId記錄在瀏覽器 Cookie c = new Cookie( "JSESSIONID" , URLEncoder.encode(httpServletRequest.getSession().getId(), "utf-8" )); c.setPath( "/" ); //先設置cookie有效期為2天,不用擔心,session不會保存2天 c.setMaxAge( 48 * 60 * 60 ); httpServletResponse.addCookie(c); } catch (Exception e){ e.printStackTrace(); } HttpSession session = httpServletRequest.getSession(); Object count=session.getServletContext().getAttribute( "count" ); return "count : " +count; } } |
總結
以上所述是小編給大家介紹的springboot 用監聽器統計在線人數案例分析,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!
原文鏈接:http://blog.csdn.net/neymar_jr/article/details/79181012