JSP环境基于Session的在线用户统计深入分析

2008-02-23 09:16:05来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

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;

}


			   
			   

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:10秒为任意数据库增加执行日志功能

下一篇:JSP初学者看的好文章[推荐]