学院首页 软件应用 编程开发 创意设计 认证培训 软件论坛
ASP ASP.NET PHP JSP SQL MYSQL Java VB

您的位置:学院 >> 编程开发 >> JSP >> JSP中基于Session的在线用户统计分析


JSP中基于Session的在线用户统计分析


  JSP作为后起之秀能够在服务器编程环境中占据一定地位,是和它良好支持一系列业界标准密切相关的。Session就是它提供的基础设施之一。作为一个程序员,你可以不介意具体在客户端是如何实现,就方便的实现简单的基于session的用户管理。现在对于处理在线用户,有几种不同的处理方法。

  一种是页面刷新由用户控制,服务器端控制一个超时时间比如30分钟,到了时间之后用户没有动作就被踢出。这种方法的优点是,如果用户忘了退出,可以防止别人恶意操作。缺点是,如果你在做一件很耗时间的事情,超过了这个时间限制,submit的时候可能要再次面临登陆。如果原来的叶面又是强制失效的话,就有可能丢失你做的工作。在实现的角度来看,这是最简单的,Server端默认实现的就是这样的模式。

  另一种方式是,站点采用框架结构,有一个Frame或者隐藏的iframe在不断刷新,这样你永远不会被踢出,但是服务器端为了判断你是否在线,需要定一个发呆时间,如果超过这个发呆时间你除了这个自动刷新的页面外没有刷新其他页面的话,就认为你已经不在线了。采取这种方式的典型是xici.net。 他的优点是可以可以利用不断的刷新实现一些类似server-push的功能,比如网友之间发送消息。

  不管哪一种模式,为了实现浏览当前所有的在线用户,还需要做一些额外的工作。servlet API中没有得到Session列表的API。

  可以利用的是Listener. Servlet 2.2和2.3规范在这里略微有一些不一样。2.2中HttpSessionBindingListener可以实现当一个HTTPSession中的Attribute变化的时候通知你的类。而2.3中还引入了HttpSessionAttributeListener.鉴于我使用的环境是Visual age for java 4和JRun server 3.1,他们还不直接支持Servlet 2.3的编程,这里我用的是HttpSessionBindingListener.

  需要做的事情包括做一个新的类来实现HttpSessionBindingListener接口。这个接口有两个方法:

public void valueBound(HttpSessionBindingEvent event)
public void valueUnbound(HttpSessionBindingEvent event)

  当你执行Session.addAttribute(String,Object)的时候,如果你已经把一个实现了HttpSessionBindingListener接口的类加入为Attribute,Session会通知你的类,调用你的valueBound方法。相反,Session.removeAttribute方法对应的是valueUndound方法。

public class HttpSessionBinding implements javax.servlet.http.HttpSessionBindingListener
{
 ServletContext application = null;

 public HttpSessionBinding(ServletContext application)
 {
  super();
  if (application ==null)
   throw new IllegalArgumentException("Null application is not accept.");
  this.application = application;
 }

 public void valueBound(javax.servlet.http.HttpSessionBindingEvent e)
 {
  Vector activeSessions = (Vector) application.getAttribute("activeSessions");
  if (activeSessions == null)
  {
   activeSessions = new Vector();
  }

  JDBCUser sessionUser = (JDBCUser)e.getSession().getAttribute("user");
  if (sessionUser != null)
  {
   activeSessions.add(e.getSession());
  }
  application.setAttribute("activeSessions",activeSessions);
 }

 public void valueUnbound(javax.servlet.http.HttpSessionBindingEvent e)
 {
  JDBCUser sessionUser = (JDBCUser)e.getSession().getAttribute("user");
  if (sessionUser == null)
  {
   Vector activeSessions = (Vector) application.getAttribute("activeSessions");
   if (activeSessions != null)
   {
    activeSessions.remove(e.getSession().getId());
    application.setAttribute("activeSessions",activeSessions);
   }
  }
 }
}

  假设其中的JDBCUser类是一个任意User类。在执行用户登录时,把User类和HttpSessionBinding类都加入到Session中去。

  这样,每次用户登录后,在application中的attribute "activeSessions"这个vector中都会增加一条记录。每当session超时,valueUnbound被触发,在这个vector中删去将要被超时的session.

public void login()
throws ACLException,SQLException,IOException
{
 /* get JDBC User Class */
 if (user != null)
 {
  logout();
 }
 {
  // if session time out, or user didn't login, save the target url temporary.

  JDBCUserFactory uf = new JDBCUserFactory();

  if ( (this.request.getParameter("userID")==null) || (this.request.getParameter("password")==null) )
  {
   throw new ACLException("Please input a valid userName and password.");
  }

  JDBCUser user = (JDBCUser) uf.UserLogin(
   this.request.getParameter("userID"),
   this.request.getParameter("password") );
   user.touchLoginTime();
   this.session.setAttribute("user",user);
   this.session.setAttribute("BindingNotify",new HttpSessionBinding(application));
  }
 }

  Login的时候,把User和这个BindingNotofy目的的类都加入到session中去。logout的时候,就要主动在activeSessions这个vector中删去这个session.

public void logout()
throws SQLException,ACLException
{
 if (this.user == null && this.session.getAttribute("user")==null)
 {
  return;
 }

 Vector activeSessions = (Vector) this.application.getAttribute("activeSessions");
 if (activeSessions != null)
 {
  activeSessions.remove(this.session);
  application.setAttribute("activeSessions",activeSessions);
 }

 java.util.Enumeration e = this.session.getAttributeNames();

 while (e.hasMoreElements())
 {
  String s = (String)e.nextElement();
  this.session.removeAttribute(s);
 }
 this.user.touchLogoutTime();
 this.user = null;
}

   这两个函数位于一个HttpSessionManager类中.这个类引用了jsp里面的application全局对象。这个类的其他代码和本文无关且相当长,我就不贴出来了。

  下面来看看jsp里面怎么用。

  假设一个登录用的表单被提交到doLogin.jsp, 表单中包含UserName和password域。节选部分片段:

<%
HttpSessionManager hsm = new HttpSessionManager(application,request,response);
try
{
 hsm.login();
}
catch ( UserNotFoundException e)
{
 response.sendRedirect("InsufficientPrivilege.jsp?detail=User%20does%20not%20exist.");
 return;
}
catch ( InvalidPasswordException e2)
{
 response.sendRedirect("InsufficientPrivilege.jsp?detail=Invalid%20Password");
 return;
}
catch ( Exception e3)
{
 %> Error:<%=e3.toString() %><br>
 Press <a href="login.jsp">Here</a> to relogin.
 <% return;
}
response.sendRedirect("index.jsp");
%>

  再来看看现在我们怎么得到一个当前在线的用户列表。

<body bgcolor="#FFFFFF">
<table cellspacing="0" cellpadding="0" width="100%">

<tr >
<td style="width:24px">SessionId
</td>
<td style="width:80px" >User
</td>
<td style="width:80px" >Login Time
</td>
<td style="width:80px" >Last access Time
</td>
</tr>
<%
Vector activeSessions = (Vector) application.getAttribute("activeSessions");
if (activeSessions == null)
{
 activeSessions = new Vector();
 application.setAttribute("activeSessions",activeSessions);
}

Iterator it = activeSessions.iterator();
while (it.hasNext())
{
 HttpSession sess = (HttpSession)it.next();
 JDBCUser sessionUser = (JDBCUser)sess.getAttribute("user");
 String userId = (sessionUser!=null)?sessionUser.getUserID():"None";
%>
<tr>
<td nowrap=''><%= sess.getId() %></td>
<td nowrap=''><%= userId %></td>
<td nowrap=''>
<%= BeaconDate.getInstance( new java.util.Date(sess.getCreationTime())).getDateTimeString()%></td>
<td class="<%= stl %>3" nowrap=''>
<%= BeaconDate.getInstance( new java.util.Date(sess.getLastAccessedTime())).getDateTimeString()%></td>
</tr>
<%
}
%>
</table>
</body>

  以上的代码从application中取出activeSessions,并且显示出具体的时间。其中BeaconDate类假设为格式化时间的类。

  这样,我们得到了一个察看在线用户的列表的框架。至于在线用户列表分页等功能,与本文无关,不予讨论。

  这是一个非刷新模型的例子,依赖于session的超时机制。我的同事sonymusic指出很多时候由于各个厂商思想的不同,这有可能是不可信赖的。考虑到这种需求,需要在每个叶面刷新的时候都判断当前用户距离上次使用的时间是否超过某一个预定时间值。这实质上就是自己实现session超时。如果需要实现刷新模型,就必须使用这种每个叶面进行刷新判断的方法。
技术文章快速查找

栏目导航
软件应用
·操作系统 ·杀毒防黑 ·应用软件
·聊天软件 ·网络软件  
Web开发
·ASP ·JavaScript ·CGI
·JSP ·VbScript ·Web服务器
·PHP ·XML  
开发语言
·VB ·VC ·ASP.NET
·Java ·C/C++ ·Delphi
数据库开发
·MySQL ·SQL/Access ·PowerBuilder
·Oracle ·DB2  
网站设计
·Flash ·Dreamweaver ·HTML/CSS
·Fireworks ·FrontPage  
平面设计
·Photoshop ·CorelDraw ·AutoCAD
·FreeHand ·Illustrator ·3DsMAX
媒体动画
·Director ·Authorware ·Maya
·视频处理    


相关软件 产品库推荐
·笔记本 ·台式机 ·服务器
·数码相机 ·手机 ·GPS
·DV摄像机 ·MP3 ·MP4
·CPU ·硬盘 ·内存
·主板 ·显卡 ·显示器
·打印机 ·投影机 ·路由器

还没人留言,抢个先,哈哈!
对"JSP中基于Session的在线用户统计分析"的评论 - 快速回贴
内容:
  [完成后可按Ctrl+Enter发布]

百度中 JSP中基于Session的在线用户统计分析 相关内容
Google搜索中 JSP中基于Session的在线用户统计分析 相关内容
雅虎中 JSP中基于Session的在线用户统计分析 相关内容
Sogou搜索中 JSP中基于Session的在线用户统计分析 相关内容

相关软件 最新回复帖子:

·AutoCAD打造精致三维鸟笼实例详解
·Photoshop自定义水晶字特效样式
·AutoCAD三维基础实例教程
·PS为黑背景长发美女照片抠图换背
·用Photoshop自制个性摩托车贴花小经验
·轻松几步将美女照片处理为手工素描
·巧用Photoshop画笔轻松绘制创意特效
·用Photoshop通道将模糊肖像照片清晰化
·照片处理:Photoshop修复残破照片
·PS CS2新增形状模糊滤镜绘制花布图案


  相关软件 JSP中基于Session的在线用户统计分析相关文章
解决JSP开发Web程序中的中文问题 JSP 2.0下的动态内容缓存分析讲解
入侵基于JSP+Tomcat的Web网站实录 JSP报表打印的一种简单解决方案
JSP/Servlet的重定向技术综述 让JSP与ASP.Net共享Session值
用缓冲技术提高JSP程序的性能和稳定性 JBuilder2005实战JSP之程序功能介绍
JBuilder2005实战JSP之创建数据库表 JBuilder2005实战JSP之登录页面
JBuilder2005实战JSP之切换控制 JBuilder2005实战JSP之错误处理
JBuilder2005实战JSP之特殊页面 JBuilder2005实战JSP之日志和部署
利用JSP 2.0开发Web应用程序 JSP安全编程实例浅析
Taglib原理和实现之循环的Tag JSP和Struts解决用户退出问题
Taglib 原理和实现之嵌套和属性读取 JSP入门初级教程之Session的使用