這幾天在做一個(gè)在線人數(shù)統(tǒng)計(jì)的程序,我費(fèi)了好大勁在網(wǎng)上查了一些資料,經(jīng)過(guò)調(diào)試學(xué)到了一些東西,在這寫(xiě)兩個(gè)簡(jiǎn)單的程序介紹一下:
1.新建一個(gè)工程O(píng)nlineCount,包結(jié)構(gòu)如下圖所示:
demo1:新建一個(gè)OnlineCounter.java
代碼如下:
package com.dr.demo2.servlet;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.apache.log4j.Logger;

public class OnlineCounter extends HttpServlet implements HttpSessionListener

{
private static Logger log = Logger.getLogger(OnlineCounter.class);
private static final long serialVersionUID = 1L;
private static int sessionCounter = 0;

public OnlineCounter()
{
log.info("OnlineCounter initialized.");
}

public void sessionCreated(HttpSessionEvent se)
{
sessionCounter++;
log.info("session created:" + sessionCounter);
}

public void sessionDestroyed(HttpSessionEvent se)
{
sessionCounter--;
log.info("session destroied");
}

public static int getOnlineSession()
{
return sessionCounter;
}

}


在web.xml中寫(xiě)入以下語(yǔ)句:
<listener>
<listener-class>
com.dr.demo2.servlet.OnlineCounter
</listener-class>
</listener>

<session-config>
<session-timeout>1</session-timeout><!-- 默認(rèn)時(shí)間為分鐘 -->
</session-config>


新建一個(gè)online.jsp,在body中寫(xiě)入以下語(yǔ)句:
<%@ page import= "com.dr.demo2.servlet.OnlineCounter" %>
在線: <%= OnlineCounter.getOnlineSession() %>人
這樣就可以啟動(dòng)服務(wù)器運(yùn)行。
1.初始啟動(dòng)服務(wù)器運(yùn)行時(shí):控制臺(tái)上會(huì)下面的日志信息:
2011-01-18 11:11:47,968 [main] [com.dr.demo2.servlet.OnlineCounter] [INFO] - OnlineCounter initialized.
2.在瀏覽器地址欄中中訪問(wèn)online.jsp:控制臺(tái)上打出,
2011-01-18 11:37:16,031 [http-8080-1] [com.dr.demo2.servlet.OnlineCounter] [INFO] - session created:1
3.大約一分鐘過(guò)后,控制臺(tái)上會(huì)打出:
2011-01-18 11:39:10,265 [ContainerBackgroundProcessor[StandardEngine[Catalina]]] [com.dr.demo2.servlet.OnlineCounter] [INFO] - session destroied
這跟在web.xml中的時(shí)間有關(guān)系
在調(diào)試時(shí)你會(huì)發(fā)現(xiàn),當(dāng)一個(gè)電腦上裝有不同的瀏覽器時(shí),用另一個(gè)瀏覽器再次訪問(wèn)時(shí),會(huì)打出:
2011-01-18 11:38:16,031 [http-8080-1] [com.dr.demo2.servlet.OnlineCounter] [INFO] - session created:2
為了避免上述失誤產(chǎn)生,在程序中加入IP過(guò)濾:
demo2:新建一個(gè)SessionCounter.java
代碼如下:
package com.dr.demo2.servlet;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.apache.log4j.Logger;


public class SessionCounter implements HttpSessionListener,ServletRequestListener
{
private static Logger log = Logger.getLogger(SessionCounter.class);
private static final String CONTENT_TYPE = "text/html; charset=GBK";
private static int activeSessions = 0;//當(dāng)前活動(dòng)的人數(shù)
private HttpServletRequest request;
private static ArrayList list = new ArrayList();//用來(lái)存放不同ip的地址


public void init() throws ServletException
{
log.info("SessionCounter init!");

}


public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
log.info("SessionCounter doGet!");
response.setContentType(CONTENT_TYPE);
HttpSession session = request.getSession();
}


public void destroy()
{
log.info("SessionCounter destroy!");
}


public void requestDestroyed(ServletRequestEvent event)
{
//To change body of implemented methods use File | Settings | File Templates.
log.info("SessionCounter requestDestroyed!");
}


public void requestInitialized(ServletRequestEvent sre)
{
request=(HttpServletRequest)sre.getServletRequest();
log.info("SessionCounter requestInitialized!");
}


public void sessionCreated(HttpSessionEvent httpSessionEvent)
{
log.info("SessionCounter sessionCreater!");
String sessionId = httpSessionEvent.getSession().getId();
Timestamp createTime = new Timestamp(System.currentTimeMillis());
String loginIp = request.getRemoteAddr();
boolean rs = true;

if(list.size() > 0)
{

for(int i = 0;i < list.size(); i ++)
{

if(loginIp.equals(list.get(i)))
{
rs = false;
}
}
}

if(rs)
{ //如果隊(duì)列中存在相同的IP 則SESSION不增加
list.add(loginIp);
log.info("ipList隊(duì)列新增ip: "+loginIp);
activeSessions++;
log.info("新增SESSION,sessionId = " + sessionId +"; createTime = " + createTime
+ "; loginIp = " + loginIp +"; 當(dāng)前總SESSION值為 "+activeSessions);
}
}


public void sessionDestroyed(HttpSessionEvent httpSessionEvent)
{
log.info("SessionCounter sessionDestroyed!");
String sessionId = httpSessionEvent.getSession().getId();
Timestamp overTime = new Timestamp(System.currentTimeMillis());
String loginIp = request.getRemoteAddr();

if(activeSessions>0)
{

if(list.size() > 0)
{

for(int i = 0;i < list.size(); i ++)
{

if(loginIp.equals(list.get(i)))
{
list.remove(i);
log.info("ipList隊(duì)列移除ip: "+loginIp);
}
}
}
activeSessions--; //在用戶銷(xiāo)毀的時(shí)候,從隊(duì)列中踢出這個(gè)IP
log.info("銷(xiāo)毀SESSION,sessionId = " + sessionId +"; overTime = " + overTime
+ "; loginIp = " + loginIp +"; 當(dāng)前總SESSION值為 "+activeSessions);
}
}


public static int getActiveSessions()
{
log.info("SessionCounter getActiveSessions!");
return activeSessions;
}


public void setActiveSessions(int i)
{
log.info("SessionCounter setActiveSessions!");
activeSessions = i;
}

}


將xml中的代碼改為如下代碼:
<listener>
<listener-class>com.dr.demo2.servlet.SessionCounter</listener-class>
</listener>
<session-config>
<session-timeout>1</session-timeout><!-- 默認(rèn)時(shí)間為分鐘 -->
</session-config>

online.jsp代碼改為如下代碼:
<%@ page import= "com.dr.demo2.servlet.SessionCounter" %>
在線: <%= SessionCounter.getActiveSessions() %>人
程序運(yùn)行結(jié)果:
1.訪問(wèn)online.jsp時(shí),控制臺(tái)輸出如下:
2.用不同的瀏覽器訪問(wèn)時(shí),控制臺(tái)輸出如下:

3.用不同的電腦訪問(wèn)時(shí),控制臺(tái)輸出如下:
4.大概一分鐘過(guò)后,控制臺(tái)上輸出如下:

希望各位大蝦批評(píng)指正!