我的理解,人数统计好说,因为,可已设置监听器,让其在服务器启动的时候进行监听,然后统计登录人数,但是统计在线人数,就麻烦点了,因为大多数人都不愿意点击注销按钮,直接关闭浏览器,这样session的关闭就麻烦了点,我先给出统计人数的代码,我想统计在线人数可以定时调用程序来统计,但是不是实时的,所以最大的障碍就是怎么在关闭浏览器的时候,就关闭session 

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);。