JAVA网页设计JSP中基于Session的在线用户统计剖析
对于一个大型项目,如果用java来作,可能需要9个月,并且可能需要翻阅10本以上的书,但如果用ruby来作,3个月,3本书就足够了,而.net也不过3,4本书足以,这就是区别。JSP作为后起之秀可以在服务器编程情况中占有必定位置,是和它优秀撑持一系列业界尺度亲切相干的。Session就是它供应的基本举措措施之一。作为一个程序员,你能够不介怀详细在客户端是怎样完成,就便利的完成复杂的基于session的用户办理。如今关于处置在线用户,有几种分歧的处置办法。一种是页面革新由用户把持,服务器端把持一个超不时间好比30分钟,到了工夫以后用户没有举措就被踢出。这类办法的长处是,假如用户忘了加入,能够避免他人歹意操纵。弱点是,假如你在做一件很耗工夫的事变,凌驾了这个工夫限定,submit的时分大概要再次面对上岸。假如本来的叶面又是强迫生效的话,就有大概丧失你做的事情。在完成的角度来看,这是最复杂的,Server端默许完成的就是如许的形式。
另外一种体例是,站点接纳框架布局,有一个Frame大概埋没的iframe在不休革新,如许你永久不会被踢出,可是服务器端为了判别你是不是在线,必要定一个发愣工夫,假如凌驾这个发愣工夫你除这个主动革新的页面外没有革新其他页面的话,就以为你已不在线了。接纳这类体例的典范是xici.net。他的长处是能够能够使用不休的革新完成一些相似server-push的功效,好比网友之间发送动静。
不论哪种形式,为了完成扫瞄以后一切的在线用户,还必要做一些分外的事情。servletAPI中没有失掉Session列表的API。
能够使用的是Listener.Servlet2.2和2.3标准在这里稍微有一些纷歧样。2.2中HttpSessionBindingListener能够完成当一个HTTPSession中的Attribute变更的时分关照你的类。而2.3中还引进了HttpSessionAttributeListener.鉴于我利用的情况是Visualageforjava4和JRunserver3.1,他们还不间接撑持Servlet2.3的编程,这里我用的是HttpSessionBindingListener.
必要做的事变包含做一个新的类来完成HttpSessionBindingListener接口。这个接口有两个办法:
publicvoidvalueBound(HttpSessionBindingEventevent)
publicvoidvalueUnbound(HttpSessionBindingEventevent)
当你实行Session.addAttribute(String,Object)的时分,假如你已把一个完成了HttpSessionBindingListener接口的类到场为Attribute,Session会关照你的类,挪用你的valueBound办法。相反,Session.removeAttribute办法对应的是valueUndound办法。
publicclassHttpSessionBindingimplementsjavax.servlet.http.HttpSessionBindingListener
{
ServletContextapplication=null;
publicHttpSessionBinding(ServletContextapplication)
{
super();
if(application==null)
thrownewIllegalArgumentException("Nullapplicationisnotaccept.");
this.application=application;
}
publicvoidvalueBound(javax.servlet.http.HttpSessionBindingEvente)
{
VectoractiveSessions=(Vector)application.getAttribute("activeSessions");
if(activeSessions==null)
{
activeSessions=newVector();
}
JDBCUsersessionUser=(JDBCUser)e.getSession().getAttribute("user");
if(sessionUser!=null)
{
activeSessions.add(e.getSession());
}
application.setAttribute("activeSessions",activeSessions);
}
publicvoidvalueUnbound(javax.servlet.http.HttpSessionBindingEvente)
{
JDBCUsersessionUser=(JDBCUser)e.getSession().getAttribute("user");
if(sessionUser==null)
{
VectoractiveSessions=(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.
publicvoidlogin()
throwsACLException,SQLException,IOException
{
/*getJDBCUserClass*/
if(user!=null)
{
logout();
}
{
//ifsessiontimeout,oruserdidntlogin,savethetargeturltemporary.
JDBCUserFactoryuf=newJDBCUserFactory();
if((this.request.getParameter("userID")==null)||(this.request.getParameter("password")==null))
{
thrownewACLException("PleaseinputavaliduserNameandpassword.");
}
JDBCUseruser=(JDBCUser)uf.UserLogin(
this.request.getParameter("userID"),
this.request.getParameter("password"));
user.touchLoginTime();
this.session.setAttribute("user",user);
this.session.setAttribute("BindingNotify",newHttpSessionBinding(application));
}
}
Login的时分,把User和这个BindingNotofy目标的类都到场到session中往。logout的时分,就要自动在activeSessions这个vector中删往这个session.
publicvoidlogout()
throwsSQLException,ACLException
{
if(this.user==null&&this.session.getAttribute("user")==null)
{
return;
}
VectoractiveSessions=(Vector)this.application.getAttribute("activeSessions");
if(activeSessions!=null)
{
activeSessions.remove(this.session);
application.setAttribute("activeSessions",activeSessions);
}
java.util.Enumeratione=this.session.getAttributeNames();
while(e.hasMoreElements())
{
Strings=(String)e.nextElement();
this.session.removeAttribute(s);
}
this.user.touchLogoutTime();
this.user=null;
}
这两个函数位于一个HttpSessionManager类中.这个类援用了jsp内里的application全局对象。这个类的其他代码和本文有关且相称长,我就不贴出来了。
上面来看看jsp内里怎样用。
假定一个登任命的表单被提交到doLogin.jsp,表单中包括UserName和password域。节选部分片断:
<%
HttpSessionManagerhsm=newHttpSessionManager(application,request,response);
try
{
hsm.login();
}
catch(UserNotFoundExceptione)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=User%20does%20not%20exist.");
return;
}
catch(InvalidPasswordExceptione2)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=Invalid%20Password");
return;
}
catch(Exceptione3)
{
%>Error:<%=e3.toString()%><br>
Press<ahref="login.jsp">Here</a>torelogin.
<%return;
}
response.sendRedirect("index.jsp");
%>
再来看看如今我们怎样失掉一个以后在线的用户列表。
<bodybgcolor="#FFFFFF">
<tablecellspacing="0"cellpadding="0"width="100%">
<tr>
<tdstyle="width:24px">SessionId
</td>
<tdstyle="width:80px">User
</td>
<tdstyle="width:80px">LoginTime
</td>
<tdstyle="width:80px">LastaccessTime
</td>
</tr>
<%
VectoractiveSessions=(Vector)application.getAttribute("activeSessions");
if(activeSessions==null)
{
activeSessions=newVector();
application.setAttribute("activeSessions",activeSessions);
}
Iteratorit=activeSessions.iterator();
while(it.hasNext())
{
HttpSessionsess=(HttpSession)it.next();
JDBCUsersessionUser=(JDBCUser)sess.getAttribute("user");
StringuserId=(sessionUser!=null)?sessionUser.getUserID():"None";
%>
<tr>
<tdnowrap=><%=sess.getId()%></td>
<tdnowrap=><%=userId%></td>
<tdnowrap=>
<%=BeaconDate.getInstance(newjava.util.Date(sess.getCreationTime())).getDateTimeString()%></td>
<tdclass="<%=stl%>3"nowrap=>
<%=BeaconDate.getInstance(newjava.util.Date(sess.getLastAccessedTime())).getDateTimeString()%></td>
</tr>
<%
}
%>
</table>
</body>
以上的代码从application中掏出activeSessions,而且显现出详细的工夫。个中BeaconDate类假定为格局化工夫的类。
如许,我们失掉了一个观察在线用户的列表的框架。至于在线用户列表分页等功效,与本文有关,不予会商。
这是一个非革新模子的例子,依附于session的超机会制。我的同事sonymusic指出良多时分因为各个厂商头脑的分歧,这有多是不成信任的。思索到这类需求,必要在每一个叶面革新的时分都判别以后用户间隔前次利用的工夫是不是凌驾某一个预准时间值。这本色上就是本人完成session超时。假如必要完成革新模子,就必需利用这类每一个叶面举行革新判别的办法。
微软什么都提供了。你可以试想一下,如果你是新手,你是希望你点一下按钮程序就能运行那,还是想自己一点一点的组织结构,然后打包发部,调错再打包...... Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。 Java是一种计算机编程语言,拥有跨平台、面向对java 不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。 那么我书也看了,程序也做了,别人问我的问题我都能解决了,是不是就成为高手了呢?当然没那么简单,这只是万里长征走完了第一步。不信?那你出去接一个项目,你知道怎么下手吗,你知道怎么设计吗,你知道怎么组织人员进行开发吗?你现在脑子里除了一些散乱的代码之外,可能再没有别的东西了吧! 一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。 所以现在应用最广泛又最好学的就是J2EE了。 J2EE又包括许多组件,如Jsp,Servlet,JavaBean,EJB,JDBC,JavaMail等。要学习起来可不是一两天的事。那么又该如何学习J2EE呢?当然Java语法得先看一看的,I/O包,Util包,Lang包你都熟悉了吗?然后再从JSP学起。 有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想) Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。 还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。 那么我书也看了,程序也做了,别人问我的问题我都能解决了,是不是就成为高手了呢?当然没那么简单,这只是万里长征走完了第一步。不信?那你出去接一个项目,你知道怎么下手吗,你知道怎么设计吗,你知道怎么组织人员进行开发吗?你现在脑子里除了一些散乱的代码之外,可能再没有别的东西了吧! 我大二,Java也只学了一年,觉得还是看thinking in java好,有能力的话看英文原版(中文版翻的不怎么好),还能提高英文文档阅读能力。 http://www.jdon.com/去下载,或到同济技术论坛的服务器ftp://nro.shtdu.edu.cn去下,安装上有什么问题,可以到论坛上去提问。 那么我书也看了,程序也做了,别人问我的问题我都能解决了,是不是就成为高手了呢?当然没那么简单,这只是万里长征走完了第一步。不信?那你出去接一个项目,你知道怎么下手吗,你知道怎么设计吗,你知道怎么组织人员进行开发吗?你现在脑子里除了一些散乱的代码之外,可能再没有别的东西了吧!
页:
[1]