Javaweb統計在線人數的小栗子


最近在學習Javaweb相關的內容(不黑不吹之前對web開發零基礎),下面通過一個統計在線人數的小栗子講講Servlet監聽器吧

開發環境 eclipse  tomcat 7

先說說這個小栗子的構思:

        首先要考慮的就是通過什么方式能夠統計在線人數?很容易想到可以通過session來統計在線人數為什么不是request呢?因為request在請求結束時即服務器返回資源時就被銷毀了,也就是說request的作用域不足以用以統計在線人數。服務器在第一次接受一個用戶請求時會給該用戶分配一個sessionid在有效期結束后或是用戶主動關閉瀏覽器一段時間后session會被銷毀,所以用session來統計在線人數是合情合理的。

        接下來問題來了,知道了統計在線人數和session相關那么應該如何操作呢?下面說說Servlet監聽器。

        Servlet監聽器只要就是用來對Web應用進行監聽和控制的,功能接近Java的GUI程序的監聽器,可以監聽由於Web應用程序狀態改變而引起的Servlet容器產生的相應事件,然后作出處理。

       Servlet監聽器分為Servlet上下文監聽器,Http會話監聽器,Servlet請求監聽器。

       既然用到了Session那我們先來看看Session相關的監聽器吧。查看Apache文檔

       HttpSessionListener接口有兩個方法對應的是session被創建和被銷毀時調用的。定義一個監聽器類實現HttpSessionListener接口代碼如下所示

 1 package com.xiaoysec;
 2 
 3 import java.util.ArrayList;
 4 
 5 import javax.servlet.annotation.WebListener;
 6 import javax.servlet.http.HttpSessionEvent;
 7 import javax.servlet.http.HttpSessionListener;
 8 
 9 /**
10  * Application Lifecycle Listener implementation class MyHttpSessionListener
11  *
12  */
13 
14 public class MyHttpSessionListener implements HttpSessionListener {
15     private int numberCount = 0;
16 
17     /**
18      * Default constructor.
19      */
20     public MyHttpSessionListener() {
21         // TODO Auto-generated constructor stub
22     }
23 
24     /**
25      * @see HttpSessionListener#sessionCreated(HttpSessionEvent)
26      */
27     public void sessionCreated(HttpSessionEvent arg0) {
28         // TODO Auto-generated method stub
29         numberCount++;
30         arg0.getSession().getServletContext()
31                 .setAttribute("numberCount", numberCount);
32     }
33 
34     /**
35      * @see HttpSessionListener#sessionDestroyed(HttpSessionEvent)
36      */
37     public void sessionDestroyed(HttpSessionEvent arg0) {
38         // TODO Auto-generated method stub
39         numberCount--;
40         arg0.getSession().getServletContext()
41                 .setAttribute("numberCount", numberCount);
42         ArrayList<Userinfo> userlist = (ArrayList<Userinfo>) arg0.getSession()
43                 .getServletContext().getAttribute("userlist");
44         if (SessionUtil.getUsersessionid(userlist, arg0.getSession().getId()) != null) {
45             userlist.remove(SessionUtil.getUsersessionid(userlist, arg0
46                     .getSession().getId()));
47         }
48     }
49 
50 }

在Session被創建時numberCount++,在被銷毀時numberCount--。這樣,一個簡單的在線人數統計功能就實現了,接下來完善一下,如果想看到客戶端的ip信息又該怎么辦呢?首先還是思考如何獲取用戶信息,很容易想到可以通過request獲取客戶端的信息。

    定義一個封裝用戶信息的Javabean,代碼如下:

    

 1 package com.xiaoysec;
 2 
 3 public class Userinfo {
 4     private String sessionid;
 5     private String ip;
 6     private String recenttime;
 7 
 8     public String getSessionid() {
 9         return sessionid;
10     }
11 
12     public void setSessionid(String sessionid) {
13         this.sessionid = sessionid;
14     }
15 
16     public String getIp() {
17         return ip;
18     }
19 
20     public void setIp(String ip) {
21         this.ip = ip;
22     }
23 
24     public String getRecenttime() {
25         return recenttime;
26     }
27 
28     public void setRecenttime(String recenttime) {
29         this.recenttime = recenttime;
30     }
31 
32 }

 定義一個類MyServletRquestListener實現ServletRequestListener接口,在該接口中定義了一個requestInitialized方法,在服務器端接收到客戶端的請求時被調用,

 代碼如下:

 

 1 package com.xiaoysec;
 2 
 3 import java.text.SimpleDateFormat;
 4 import java.util.ArrayList;
 5 import java.util.Date;
 6 
 7 import javax.servlet.ServletRequestEvent;
 8 import javax.servlet.ServletRequestListener;
 9 import javax.servlet.annotation.WebListener;
10 import javax.servlet.http.HttpServletRequest;
11 
12 public class MyServletRquestListener implements ServletRequestListener {
13     private ArrayList<Userinfo> userlist; // 在綫用戶的list
14 
15     @Override
16     public void requestDestroyed(ServletRequestEvent arg0) {
17         // TODO Auto-generated method stub
18 
19     }
20 
21     /**
22      * 在初始化request的初始化中判斷是否存在user的信息(sessionid)如果不存在的話就保存在userlist中
23      */
24     @Override
25     public void requestInitialized(ServletRequestEvent arg0) {
26         userlist = (ArrayList<Userinfo>) arg0.getServletContext().getAttribute("userlist");
27         if(userlist==null)
28             userlist = new ArrayList<Userinfo>(); 
29         HttpServletRequest req = (HttpServletRequest) arg0.getServletRequest();
30         String sessionid = req.getSession().getId();
31         if (SessionUtil.getUsersessionid(userlist, sessionid) == null) {
32             Userinfo user = new Userinfo();
33             user.setIp(req.getRemoteAddr());
34             user.setSessionid(sessionid);
35             user.setRecenttime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
36                     .format(new Date()));
37             userlist.add(user);
38         }
39         arg0.getServletContext().setAttribute("userlist", userlist);
40     }
41 
42 } 

 接着寫一個SessionUtil類實現了getUsersessionid方法,代碼如下:

 1 package com.xiaoysec;
 2 
 3 import java.util.ArrayList;
 4 
 5 public class SessionUtil {
 6     public static Object getUsersessionid(ArrayList<Userinfo> userlist,String sessionid) {
 7          for(int i=0;i<userlist.size();i++){
 8               Userinfo info = userlist.get(i);
 9               if(userlist.get(i).getSessionid().equals(sessionid)) //表示當前的sessionid用戶存在於用戶list中不需要
10                   return info;
11          }
12         return null;
13     }
14 
15 }

在getUsersessionid中參數為userlist和sessionid,通過一個循環判斷sessionid所指的用戶是否在userlist中如果在的話就返回用戶信息info,如果不在的話就返回null並在MyServletRquestListener的31行處添加進userlist。

最后是界面jsp展示

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@  page import="java.util.*"%>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>Insert title here</title>
 9 </head>
10 <body>
11     當前用戶在線人數<%= application.getAttribute("numberCount") %><br/>
12     <%
13         ArrayList<com.xiaoysec.Userinfo> userlist = (ArrayList<com.xiaoysec.Userinfo>)request
14                 .getServletContext().getAttribute("userlist");
15     if(userlist!=null){
16         for (int i=0;i<userlist.size();i++) {
17             com.xiaoysec.Userinfo info = userlist.get(i);
18     %>
19     ip:<%=info.getIp()%><br /> 
20     recentTime:<%=info.getRecenttime()%><br/>
21     sessionid:<%=info.getSessionid()%><br/>
22     <%
23         }}
24     %>
25 </body>
26 </html>

總結:通過這個小栗子只是對Servlet監聽器有一個小小的了解,還是需要多看源碼,理解過程,多代碼,多思考,多總結。

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM