最新更新 sitemap 网站制作设计本站搜索
网页设计
国外网站 韩国网站 个人主页 手提袋设计 CSS 网页特效 平面设计 网站设计 Flash CMS技巧 服装网站 php教程 photoshop 画册 服务器选用 数据库 Office
虚拟主机 域名注册 云主机 网页设计 客服QQ:8208442
当前位置:首页 > 编程开发 > jsp教程

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

日期:12-17    来源:中国设计秀    作者:cnwebshow.com

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

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

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

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

  可以利用的是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.93k中国设计秀

  需要做的事情包括做一个新的类来实现HttpSessionBindingListener接口。这个接口有两个方法:93k中国设计秀

public void valueBound(HttpSessionBindingEvent event)93k中国设计秀
public void valueUnbound(HttpSessionBindingEvent event)93k中国设计秀

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

public class HttpSessionBinding implements javax.servlet.http.HttpSessionBindingListener 93k中国设计秀
{93k中国设计秀
 ServletContext application = null;93k中国设计秀

 public HttpSessionBinding(ServletContext application)93k中国设计秀
 {93k中国设计秀
  super();93k中国设计秀
  if (application ==null)93k中国设计秀
   throw new IllegalArgumentException("Null application is not accept.");93k中国设计秀
  this.application = application;93k中国设计秀
 }93k中国设计秀

 public void valueBound(javax.servlet.http.HttpSessionBindingEvent e) 93k中国设计秀
 { 93k中国设计秀
  Vector activeSessions = (Vector) application.getAttribute("activeSessions");93k中国设计秀
  if (activeSessions == null)93k中国设计秀
  {93k中国设计秀
   activeSessions = new Vector();93k中国设计秀
  }93k中国设计秀

  JDBCUser sessionUser = (JDBCUser)e.getSession().getAttribute("user");93k中国设计秀
  if (sessionUser != null)93k中国设计秀
  {93k中国设计秀
   activeSessions.add(e.getSession());93k中国设计秀
  }93k中国设计秀
  application.setAttribute("activeSessions",activeSessions);93k中国设计秀
 }93k中国设计秀

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

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

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

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

  JDBCUserFactory uf = new JDBCUserFactory();93k中国设计秀

  if ( (this.request.getParameter("userID")==null) || (this.request.getParameter("password")==null) )93k中国设计秀
  {93k中国设计秀
   throw new ACLException("Please input a valid userName and password.");93k中国设计秀
  }93k中国设计秀

  JDBCUser user = (JDBCUser) uf.UserLogin(93k中国设计秀
   this.request.getParameter("userID"),93k中国设计秀
   this.request.getParameter("password") );93k中国设计秀
   user.touchLoginTime();93k中国设计秀
   this.session.setAttribute("user",user);93k中国设计秀
   this.session.setAttribute("BindingNotify",new HttpSessionBinding(application));93k中国设计秀
  }93k中国设计秀
 }93k中国设计秀

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

public void logout()93k中国设计秀
throws SQLException,ACLException93k中国设计秀
{93k中国设计秀
 if (this.user == null && this.session.getAttribute("user")==null)93k中国设计秀
 {93k中国设计秀
  return;93k中国设计秀
 }93k中国设计秀

 Vector activeSessions = (Vector) this.application.getAttribute("activeSessions");93k中国设计秀
 if (activeSessions != null)93k中国设计秀
 {93k中国设计秀
  activeSessions.remove(this.session);93k中国设计秀
  application.setAttribute("activeSessions",activeSessions);93k中国设计秀
 }93k中国设计秀

 java.util.Enumeration e = this.session.getAttributeNames();93k中国设计秀

 while (e.hasMoreElements())93k中国设计秀
 {93k中国设计秀
  String s = (String)e.nextElement();93k中国设计秀
  this.session.removeAttribute(s);93k中国设计秀
 }93k中国设计秀
 this.user.touchLogoutTime();93k中国设计秀
 this.user = null;93k中国设计秀
}93k中国设计秀

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

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

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

  再来看看现在我们怎么得到一个当前在线的用户列表。93k中国设计秀

<body bgcolor="#FFFFFF">93k中国设计秀
<table cellspacing="0" cellpadding="0" width="100%">93k中国设计秀

<tr >93k中国设计秀
<td style="width:24px">SessionId93k中国设计秀
</td>93k中国设计秀
<td style="width:80px" >User93k中国设计秀
</td>93k中国设计秀
<td style="width:80px" >Login Time93k中国设计秀
</td>93k中国设计秀
<td style="width:80px" >Last access Time93k中国设计秀
</td>93k中国设计秀
</tr>93k中国设计秀
<%93k中国设计秀
Vector activeSessions = (Vector) application.getAttribute("activeSessions");93k中国设计秀
if (activeSessions == null)93k中国设计秀
{93k中国设计秀
 activeSessions = new Vector();93k中国设计秀
 application.setAttribute("activeSessions",activeSessions);93k中国设计秀
}93k中国设计秀

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

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

  这样,我们得到了一个察看在线用户的列表的框架。至于在线用户列表分页等功能,

本文引用地址:/bc/article_46692.html
网站地图 | 关于我们 | 联系我们 | 网站建设 | 广告服务 | 版权声明 | 免责声明