import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ApplicationListener implements ServletContextListener{
public void contextDestroyed(ServletContextEvent arg0) {
ServletContext sc = arg0.getServletContext();
Integer count = (Integer) sc.getAttribute("AccessCount");
try {
PrintWriter out = new PrintWriter(new FileWriter("c:/Users/god/count.txt"));// 將人數保存到文本文件
System.out.println("count:"+count);
out.print(count);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void contextInitialized(ServletContextEvent arg0) {
Integer count = 0;
ServletContext sc = arg0.getServletContext();
try {
Scanner in = new Scanner(new FileReader("c:/Users/god/count.txt"));// 讀取已經產生的人數信息,然後進行累加
count = in.nextInt();
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
sc.setAttribute("AccessCount", count);
}
}
在web.xml文件裏面進行設置
<listener>
<listener-class>
文件的位置也就是包名.ApplicationListener
</listener-class>
</listener>
統計的時候是設置攔截器,需要在struts.xml中設置
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
@SuppressWarnings("serial")
public class AccessInterceptor implements Interceptor{
private String id;
public void destroy() {
}
public void init() {
}
@SuppressWarnings("unchecked")
public String intercept(ActionInvocation ai) throws Exception {
ServletContext sc = ServletActionContext.getServletContext();
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession();
if(!session.getId().equals(id)){
Integer count = (Integer) sc.getAttribute("AccessCount");// 判斷如果登錄成功,統計數字自增
sc.setAttribute("AccessCount", count+1);
id = session.getId();
}
String result = ai.invoke();
return result;
}
}
你可以直接掛一個google或者51的統計腳本;
你也可以使用日誌的方式來記錄訪問量,一般不要往數據庫來;通過分析log即可;
回答者: ustbduanhang - 九級 2009-8-31 09:33
可以提供一些思路給你:
【網站級訪問量】
一、 ServletContext 中存放一個計數器(Integer 也可)
ServletRequestListener.requestInitialized(ServletRequestEvent sre)
計數器++
二、 Filter 中使用 靜態變量 進行統計。
【頁面級訪問量】
一、 Servlet 或 Action 中使用 靜態變量 進行統計。
二、 Filter 中使用 靜態變量 進行統計。
【網站在線人數】
ServletContext 中存放一個計數器(Integer 也可)或 其他類中使用一個 靜態變量
登錄時:session.setAttribute("wangyf", "***") 計數器++
HttpSessionListener
sessionDestroyed(HttpSessionEvent se) {
session.getAttribute("wangyf") != null 計數器--
}
利用Servlet監聽器實現簡單網站訪問量和在線人數統計
Servlet監聽器主要有三種,在ServletContext(上下文對象)、Session(會話)和request(請求)這三對象上進行監聽,可以監聽對象的創建、銷燬、添加屬性、刪除屬性、屬性值的改變等。ServletContext對象的作用域在整個WEB應用程序,類似於Static屬性;Session的作用域在一個會話,一個會話可以理解爲一個從一個瀏覽器發出請求到服務器開始,一直到瀏覽器關閉(但通常我們可以設置會話的生命期,防止那些獲得連接後卻長時間沒有再向服務器發出請求的情況),相當於類的成員變量;request的作用域僅在一次請求,即瀏覽器發送一次請求到服務器處理該請求併發迴響應就結束了,相當於局部變量。
要實現統計網站的歷史訪問量就要利用ServletContext的全局屬性的特點了,爲了在服務器停止後,之前的訪問量不會消失,我們就應該在服務器關閉前將當前的訪問量存放到文件裏面,以便下一次重啓服務器後,可以繼續使用。在ServletContext上面創建監聽器,監聽上下文對象的銷燬和創建,並同時在創建上下文的時候從文件讀取歷史數據,在上下文銷燬的時候將當前訪問量寫入到文件保存起來。以後每當創建一個會話(Session)的時候,就將當前的計數值加一。在線人數的統計是利用在創建會話的時候,將在線人數之加一,在會話對象銷燬的時候,將在線人數值減一。因爲兩種人數統計都是被所有用戶共享的信息,所以使用ServletContext的setAttribute()和getAttribut()方法來對總人數和在線人數進行管理。
創建對上下文對象的監聽器:
public class ContextListener implements ServletContextListener{
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
Properties pro = new Properties();
try {
pro.setProperty("counter", arg0.getServletContext().getAttribute("counter").toString());
String filePath = arg0.getServletContext().getRealPath("/WEB-INF/classes/db/count.txt");
//上下文對象銷燬時,將當前訪問量寫入文件
OutputStream os = new FileOutputStream(filePath);
pro.store(os, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
arg0.getServletContext().setAttribute("online", 0);
Properties pro = new Properties();
InputStream in = ContextListener.class.getResourceAsStream("/db/count.txt");
String n = null;
try {
pro.load(in);
n = pro.getProperty("counter");//從計數文件中讀取該站的歷史訪問量
arg0.getServletContext().setAttribute("counter", Integer.parseInt(pro.getProperty("counter")));
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("讀取計數文件失敗");
}
System.out.println("創建上下文對象" + n);
}
}
創建對會話對象的監聽:
public class SessionListener implements HttpSessionListener{
public void sessionCreated(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
HttpSession session = arg0.getSession();
int i = (Integer)session.getServletContext().getAttribute("online");//獲得當前在線人數,並將其加一
session.getServletContext().setAttribute("online", i+1);
int n = (Integer)session.getServletContext().getAttribute("counter");//創建一個會話就將訪問量加一
session.getServletContext().setAttribute("counter", n+1);
Properties pro = new Properties();
try {//訪問人數加一後就將結果寫入文件(防止不正常關閉服務器)
pro.setProperty("counter", session.getServletContext().getAttribute("counter").toString());
String filePath = session.getServletContext().getRealPath("/WEB-INF/classes/db/count.txt");
OutputStream os = new FileOutputStream(filePath);
pro.store(os, null);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("寫入計數文件失敗");
}
System.out.println("創建一個會話");
}
public void sessionDestroyed(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
//銷燬會話的時候,需要將在線人數減一
ServletContext context = arg0.getSession().getServletContext();
Integer i = (Integer)context.getAttribute("online");
context.setAttribute("online", i-1);
arg0.getSession().invalidate();
System.out.println("銷燬一個會話");
}
}
在web.xml文件中將監聽器註冊,在創建和銷燬對象時就會觸發該事件了。 因爲我們通常做測試的時候,服務器的關閉是沒有通過正常的方式來進行的,所以程序中在創建一個會的時候將網站歷史訪問數據值加一後就將該值在文件中進行更新,否則可能該值不會改變。創建一個會話是通過request.getSession()來觸發的,所以在做測試的Servlet中需要加上HttpSession
session = request.getSession();
//設置會話的最大不活動時間爲60秒
session.setMaxInactiveInterval(60);。