- 浏览: 29274 次
- 性别:
- 来自: 杭州
最新评论
-
so_depress:
学习了,总之谢谢分享
在线统计人数和访问量设计 -
fancyleeo:
操,转帖转的这么不专业!
在线统计人数和访问量设计
Servlet监听器主要有三种,在ServletContext(上下文对象)、Session(会话)和request(请求)这三对象上进行监听,可以监听对象的创建、销毁、添加属性、删除属性、属性值的改变等。ServletContext对象的作用域在整个WEB应用程序,类似于Static属性;Session的作用域在一个会话,一个会话可以理解为一个从一个浏览器发出请求到服务器开始,一直到浏览器关闭(但通常我们可以设置会话的生命期,防止那些获得连接后却长时间没有再向服务器发出请求的情况),相当于类的成员变量;request的作用域仅在一次请求,即浏览器发送一次请求到服务器处理该请求并发回响应就结束了,相当于局部变量。
要实现统计网站的历史访问量就要利用ServletContext的全局属性的特点了,为了在服务器停止后,之前的访问量不会消失,我们就应该在服务器关闭前将当前的访问量存放到文件里面,以便下一次重启服务器后,可以继续使用。在ServletContext上面创建监听器,监听上下文对象的销毁和创建,并同时在创建上下文的时候从文件读取历史数据,在上下文销毁的时候将当前访问量写入到文件保存起来。以后每当创建一个会话(Session)的时候,就将当前的计数值加一。在线人数的统计是利用在创建会话的时候,将在线人数之加一,在会话对象销毁的时候,将在线人数值减一。因为两种人数统计都是被所有用户共享的信息,所以使用ServletContext的setAttribute()和getAttribut()方法来对总人数和在线人数进行管理。
创建对上下文对象的监听器:
创建对会话对象的监听:
在web.xml文件中将监听器注册,在创建和销毁对象时就会触发该事件了。 因为我们通常做测试的时候,服务器的关闭是没有通过正常的方式来进行的,所以程序中在创建一个会的时候将网站历史访问数据值加一后就将该值在文件中进行更新,否则可能该值不会改变。创建一个会话是通过request.getSession()来触发的,所以在做测试的Servlet中需要加上HttpSession session = request.getSession();
//设置会话的最大不活动时间为60秒
session.setMaxInactiveInterval(60);。
要实现统计网站的历史访问量就要利用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);。
package org.leeyohn.listener; import java.util.HashMap; import javax.servlet.http.HttpSessionListener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSession; import javax.servlet.ServletContext; import org.leeyohn.User; import org.leeyohn.OnLineUser; public class OnLineUserListener implements HttpSessionListener { //在线注册用户的累加器 private int userCount = 0; //在线游客的累加器 private int visitorCount = 0; @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("sessionCreated"); //获取一个session HttpSession session = se.getSession(); //获取application ServletContext application = session.getServletContext(); System.out.println("创建了一个游客Session"); //包装成一个在线游客信息 OnLineUser onLineUser = new OnLineUser(session.getId(), null, null, null); //获取在线游客的HashMap HashMap<String, OnLineUser> visitorMap = (HashMap<String, OnLineUser>)application.getAttribute("visitormap"); //将访问网站的游客放入Map中 visitorMap.put(session.getId(), onLineUser); //当前在线游客总数 visitorCount = visitorMap.size(); System.out.println(visitorCount); //设置全局的在线游客人数 application.setAttribute("visitorCount", visitorCount); //总人数 application.setAttribute("onLineUserCount", (visitorCount + userCount)); } @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("sessionDestoryed"); HttpSession session = se.getSession(); ServletContext application = session.getServletContext(); //注册用户 if (session.getAttribute("user") != null) { System.out.println("注销了一个注册用户Session"); User user = (User)session.getAttribute("user"); HashMap<String, OnLineUser> userMap = (HashMap<String, OnLineUser>)application.getAttribute("usermap"); userMap.remove(session.getId()); userCount = userMap.size(); System.out.println(userCount); application.setAttribute("userCount", userCount); } //游客 else { System.out.println("注销了一个游客Session"); HashMap<String, OnLineUser> visitorMap = (HashMap<String, OnLineUser>)application.getAttribute("visitormap"); visitorMap.remove(session.getId()); visitorCount = visitorMap.size(); System.out.println(visitorCount); application.setAttribute("visitorCount", visitorCount); } //总人数 application.setAttribute("onLineUserCount", (visitorCount + userCount)); } } LoginServlet.java文件 import java.util.HashMap; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.http.Cookie; import javax.servlet.RequestDispatcher; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.JspFactory; import javax.servlet.ServletContext; import java.sql.ResultSet; import org.leeyohn.User; import org.leeyohn.DbDao; import org.leeyohn.OnLineUser; import org.leeyohn.dao.DataSourcePool; public class LoginServlet extends HttpServlet { @Override public void service(HttpServletRequest request , HttpServletResponse response) { //获取session对象 HttpSession session = request.getSession(true); //创建一个application对象 ServletContext application = getServletContext(); String errMsg = ""; try { //获取应用程序名称 String webName = request.getContextPath().substring(1); //用户名 String username = new String(request.getParameter("username").getBytes("iso-8859-1"), "gbk"); //密码 String password = new String(request.getParameter("password").getBytes("iso-8859-1"), "gbk"); //Cookie生存周期 int maxAge = Integer.parseInt(request.getParameter("cookietime")); System.out.println("Cookie生存周期=" + maxAge); System.out.println("应用程序名称=" + webName); DataSourcePool dsp = (DataSourcePool)application.getAttribute("dsp"); ResultSet rs = dsp.query("select user_id, user_name, user_password from user_table where user_name='" + username + "'"); if (rs.next()) { if (rs.getString("user_password").equals(password)) { //调用Model,将用户名密码和ID封装成User对象 User user = new User(rs.getInt(1), username, password); Cookie cookieName = new Cookie(webName + ".loginname", username); Cookie cookiePass = new Cookie(webName + ".loginpass", password); cookieName.setPath("/"); cookiePass.setPath("/"); //设置Cookie对象的保存期限 cookieName.setMaxAge(maxAge); cookiePass.setMaxAge(maxAge); //写入Cookie对象 response.addCookie(cookieName); response.addCookie(cookiePass); //设置session属性,跟踪用户状态 session.setAttribute("user", user); //--------统计在线人数并分别统计在线会员人数和在线游客------- OnLineUser onLineUser = new OnLineUser(session.getId(), user , request.getRemoteAddr(), request.getServletPath()); //获取在线注册用户的HashMap HashMap<String, OnLineUser> userMap = (HashMap<String, OnLineUser>) application.getAttribute("usermap"); //将新登录的注册用户放入Map中 userMap.put(session.getId(), onLineUser); //Map的容量 int userCount = userMap.size(); System.out.println(userCount); //设置全局的在线注册用户人数 application.setAttribute("userCount", userCount); //一次游客访问为session,但登录也是session,要减去游客数量,增加登录用户数量 HashMap<String, OnLineUser> visitorMap = (HashMap<String, OnLineUser>) application.getAttribute("visitormap"); //从游客的Map中移除当前游客 visitorMap.remove(session.getId()); //移除当前游客后的游客数量 int visitorCount = visitorMap.size(); application.setAttribute("visitorCount", visitorCount); //总人数 application.setAttribute("onLineUserCount", (visitorCount + userCount)); request.getRequestDispatcher("/autoturn.jsp").forward(request, response); } else { //用户名密码不匹配 errMsg += "您的用户名密码不符合,请重新输入"; } } else { //用户名不存在 errMsg += "您的用户名不存在,请先注册"; } } catch (Exception e) { e.printStackTrace(); } if (errMsg != null && !errMsg.equals("")) { request.setAttribute("err", errMsg); try { request.getRequestDispatcher("/error.jsp").forward(request, response); } catch (Exception e) { e.</p> <div align="center" class="pager"><span id="pagesSpan"> <span id="1">1</span> <a href="183186_2.html">2</a></span></div> <div class="ad7"><script language="javascript" src="/ad/2010/article/ad7.js"></script></div> <div class="ad8"><script language="javascript" src="/ad/2010/article/ad8.js"></script></div> <div class="index_main_err">如果图片或页面不能正常显示请<a href="javascript:void(0)" onClick="ReportError()" class= "redlink"><font color="#990000"><strong>点击这里</strong></font></a></div> </div> <div class="index_main_left_foot"> <div class="index_main_left_foot1"> <p><a href="javascript:window.external.addFavorite(self.location,document.title);">【收藏此页】</a><a href="http://bbs.firnow.com" target="_blank">【飞诺社区】</a><a href="#comment">【发表评论】</a><a href="javascript:window.close()">【关闭】</a></p> <a href="#comment"><img src="/images/2010/article/ping.gif" width="149" height="34" border="0" /></a> </div> <div class="index_main_left_foot2"> <p>上一篇:<a href="/course/3_program/java/javajs/20091122/183185.html">java中涉及构造器的相关问题</a></p> <p>下一篇:<a href="/course/3_program/java/javajs/20091122/183187.html">监听用户离线,自定义离线时间</a></p> </div> </div> </div> <div class="ad9"><script language="javascript" src="/ad/2010/article/ad9.js"></script></div> <div class="index_main_left_3">Java技术文章推荐文章</div> <div class="index_main_left_4"> <ul> <li><a href="/course/3_program/java/javajs/2008710/132607.html" target="_blank">Eclipse 编译错误问题解决</a></li> <li><a href="/course/3_program/java/javajs/200824/98544.html" target="_blank">Hibernate3.x调用存储过程 </a></li> <li><a href="/course/3_program/java/javajs/2008313/104430.html" target="_blank">面向 Java 开发人员的 db4o 指南: 超越简单对象,使用 db4o 创建、更新与删除结构化对象</a></li> <li><a href="/course/3_program/java/javajs/2007128/91108.html" target="_blank">Solaris shell脚本</a></li> <li><a href="/course/3_program/java/javajs/2008325/107299.html" target="_blank">Java 5.0 Generics</a></li> <li><a href="/course/3_program/java/javajs/20091112/182214.html" target="_blank">基于Java的数据库连接池技术研究</a></li> <li><a href="/course/3_program/java/javajs/20100107/187388.html" target="_blank">Struts 2杂谈(2):如何向标签文件中的Struts 2标签传递参数值</a></li> <li><a href="/course/3_program/java/javajs/20100106/186819.html" target="_blank">Java线程:新特征-阻塞队列</a></li> </ul> <ul> <li><a href="/course/3_program/java/javajs/200896/139343.html" target="_blank"> JAVA代码:通过Socket执行HTTP的GET方法</a></li> <li><a href="/course/3_program/java/javajs/20091120/183028.html" target="_blank">java.IO搜索指定文件</a></li> <li><a href="/course/3_program/java/javajs/200818/96005.html" target="_blank">连接池与使用Tomcat的连接池</a></li> <li><a href="/course/3_program/java/javajs/20081012/150137.html" target="_blank"> 基于Eclipse RCP的油田开发决策支持系统(一)</a></li> <li><a href="/course/3_program/java/javajs/200899/141527.html" target="_blank">Hibernate 使用DB2 for Z/OS 序列 的一个BUG</a></li> <li><a href="/course/3_program/java/javajs/20090302/156398.html" target="_blank">详细讲解Java中log4j的使用方法</a></li> <li><a href="/course/3_program/java/javajs/20091006/178011.html" target="_blank">NHibernate的各种保存方式的区别 (save,persist,update,saveOrUp</a></li> <li><a href="/course/3_program/java/javajs/20090407/164588.html" target="_blank">Integer</a></li> </ul> </div> <div class="index_main_left_5"> <div class="index_main_left_5_top"><p><a name="comment"></a>文章评论</p></div> <div id="divComment" class="index_main_left_5_main"></div> </div> <div class="index_main_left_6"> <div class="index_main_left_6_left"> <div class="index_main_left_6_left_top">请您留言</div> <div class="index_main_left_6_left_ceneter"> <form> <table width="84%" height="216" border="0" cellpadding="10"> <tr> <td width="19%" height="29">昵称:</td> <td width="81%"><label> <input type="text" class="index_main_left_6_left_ceneter_text" style="width:150px;" name="tbName" id="tbName" onclick="this.focus();this.select()" maxlength="20" /> </label></td> </tr> <tr> <td>验证码:</td> <td> <span style="float:left;"><input name="tbCode" id="tbCode" class="index_main_left_6_left_ceneter_text" type="text" size="6" /></span><span id="spanCode" style="float:left; clear:right;"><img id="Img2" onclick="this.src=this.src" style="display:none;"/></span> </tr> <tr> <td height="26" colspan="2"><a href="http://bbs.firnow.com/register.aspx" style="color:#FF0000">注册会员</a> <a href="http://bbs.firnow.com/login.aspx">会员登录</a></td> </tr> <tr> <td height="100" colspan="2"><label> <a name="comment"></a><textarea name="tbContent" id="tbContent" class="index_main_left_6_left_ceneter_textarea" rows="5">
相关推荐
### 一、网站访问量统计的意义与作用 网站访问量统计是衡量一个网站流量的重要指标之一,它可以帮助网站管理者了解用户的行为模式,包括用户从何处来、在网站上的停留时间、访问频率等。通过对这些数据的分析,可以...
访问量,也被称为页面浏览量或Page Views,是指用户打开或刷新一个网页的次数。在统计时,每个独立的页面加载被视为一次访问。然而,如果用户在同一页面上频繁刷新,这种行为可能会导致访问量被过度计算,从而影响...
数据库设计通常包括日期、日访问量和总访问量字段。 实现统计功能时,还需要注意以下几点: - **会话管理**:为了避免重复计数,可以使用会话ID来判断是否为新访客。如果会话ID不存在或与之前的不同,就视为新访问...
为了统计访问量,我们需要一个存储历史数据的数据结构,如`HashMap`,其中键为日期或星期,值为对应的访问量。 以下是一个简单的日访问量统计示例: ```java import java.time.LocalDate; import java.util....
在线人数统计是网站运营中的重要指标,用于了解网站的活跃度和用户参与度。下面将详细解释这个领域的几个关键知识点: 1. **Web应用程序结构**: - `Global.asax` 文件:这是一个ASP.NET应用程序的全局应用事件...
这个"在线人数统计程序.rar"是一个特别设计的解决方案,它无需依赖Global.asa文件,这对于那些不支持或限制使用此文件的免费Web托管服务尤其有用。Global.asa文件在ASP(Active Server Pages)中是一个重要的组件,...
在线人数统计是网络服务运营中的重要指标,它可以帮助管理者了解网站、应用或游戏等平台的实时活跃用户数量,为优化用户体验、制定营销策略提供数据支持。准确的在线人数统计不仅涉及技术实现,还涵盖多种技术和策略...
在本文中,我们将深入探讨如何使用JavaServer Pages (JSP) 实现在线人数统计功能,以便展示当前在线的用户数量。我们将分析提供的代码段,并解释关键概念和技术。 首先,我们有一个名为`onLineUser`的类,它实现了`...
"星光统计系统"是一款专为网站流量分析设计的软件,其主要功能包括统计站点的总访问量、在线人数以及用户使用的操作系统类型,并且能够精确获取访问者的IP地址。这款统计系统的一大亮点在于它采用了防刷新技术,从而...
标题 "统计一天的访问人数以及总访问数" 暗示了我们正在讨论网站或应用程序的用户活动跟踪和分析。这种统计通常涉及到日志记录、数据处理和数据分析。以下是相关知识点的详细介绍: 1. **日志记录**: - 网站或...
这个表的设计可以满足基本的访问量统计,但如果你需要更长时间的数据记录,例如按月统计,那么可能需要扩展表结构以存储更多的日期信息。 接下来,我们利用`Global.asax`文件来处理用户访问事件。`Global.asax`是...
在"内置对象 统计上网人数"这个主题中,我们将探讨如何利用ASP.NET的内置对象来实现站内统计功能,特别是统计网站的在线用户数量。 首先,我们需要了解几个关键的内置对象: 1. **HttpApplication**: 这个对象代表...
在Java Web开发中,统计在线人数是一项常见的需求,它能够帮助我们了解网站或应用的实时活跃用户数量。这里我们将深入探讨如何实现这一功能。 首先,我们需要理解“在线人数”的定义。通常,它指的是在一定时间窗口...
- 如果网站访问量巨大,可能需要分布式会话管理,确保在多台服务器之间正确同步在线人数。 6. **安全考虑**: - 防止会话劫持和跨站请求伪造(CSRF)攻击,确保每个会话ID的安全性。 - 定期清理无用的会话,防止...
在ASP.NET开发中,统计网站在线人数和历史访问量是一个常见的需求,这有助于了解网站的活跃度和用户流量。在给定的标题和描述中,我们看到使用Visual Studio 2008(VS2008)进行这项任务,通过`Application`和`...
该系统需要在服务器上保存访问量数据,浏览者访问包含有计数器的页面时,将触发计数程序,程序打开文本文件或查询数据库获得访问之前的计数数据,将计数值加 1,在页面上显示并写回文本文件或数据库中。 二、设计...
综上所述,通过图表分析网站访问量涉及的技术和概念包括:在线人数统计、数据可视化库的使用、时间序列数据分析、日志处理、数据处理与计算、性能优化以及交互式设计。这些知识对于理解用户行为、优化网站性能和制定...
同时,统计表还包括“累计”列,用于跟踪每周的总访问量,帮助管理层了解整体趋势。 2. **电话查询**:表格中提到的“查询电话”可能是用来记录访客通过电话进行咨询的次数,这有助于评估客户服务的质量和效率,...
6. **结果可视化**:统计结果通常以文本文件形式输出在HDFS上,我们可以使用工具如Apache Pig或Hive进行进一步处理,或将数据导入到数据可视化工具(如Tableau、Grafana)中,生成图表展示每日访问趋势。 7. **扩展...
根据给定文件的信息,我们可以总结出以下关于使用 JSP 实现在线用户人数统计的知识点: ### 1. **实现原理** 在线人数统计主要是通过利用 `HttpSession` 的生命周期事件来实现。每当一个新用户访问网站时,服务器会...