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

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

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

 

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

 6Q5中国设计秀

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

 6Q5中国设计秀

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

 6Q5中国设计秀

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

 6Q5中国设计秀

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

 6Q5中国设计秀

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

 6Q5中国设计秀

public void valueBound(HttpSessionBindingEvent event)6Q5中国设计秀

 6Q5中国设计秀

public void valueUnbound(HttpSessionBindingEvent event)6Q5中国设计秀

 6Q5中国设计秀

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

 6Q5中国设计秀

 6Q5中国设计秀

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

 } 

} 

 } 

}

 6Q5中国设计秀

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

 6Q5中国设计秀

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

 6Q5中国设计秀

 6Q5中国设计秀

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

} 

 }
6Q5中国设计秀

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