做过JAVA编程的都知道,在JAVA中有一种垃圾收集器的机制,当它运行时(通常在系统内存低到一定限度时自动运行),会回收不再使用的对象所占用的内存,所以,在JAVA程序中,我们通常只考虑创建对象,而从不关心对象的清除。Finalize()是JAVA为类提供的一种特殊方法。垃圾收集器的工作过程大致是这样的:一旦垃圾收集器准备好释放无用对象占用的存储空间,它首先调用那些对象的finalize()方法,然后才真正回收对象的内存。通过使用finalize(),就可以在垃圾收集器运行期间进行一些特殊的工作。下面一例就说明了finalize()的一种巧妙用法。
现在的商业应用系统越来越多的采用WEB形式。在WEB形式应用中,每一次页面访问是独立的,前后不相关联,哪怕多个用户在同一时刻访问应用的同一个页面,用户相互之间也是不知道的。如果想要检查当前有哪些用户正在使用系统(如准备恢复数据备份或进行系统升级时,系统管理员都很希望知道这些信息),该怎么办呢? 基于Servlet、Jsp技术的WEB服务器提供了隐含的Session、Application对象,利用它可以帮开发者实现一些信息的持续保存和共享。当用户访问一个WEB应用时,WEB服务器会自动创建一个Session对象,该对象可以供用户在会话期内在应用的所有页面中共享数据; Application是WEB应用的一个全局对象。
现在的商业应用系统越来越多的采用WEB形式。在WEB形式应用中,每一次页面访问是独立的,前后不相关联,哪怕多个用户在同一时刻访问应用的同一个页面,用户相互之间也是不知道的。如果想要检查当前有哪些用户正在使用系统(如准备恢复数据备份或进行系统升级时,系统管理员都很希望知道这些信息),该怎么办呢? 基于Servlet、Jsp技术的WEB服务器提供了隐含的Session、Application对象,利用它可以帮开发者实现一些信息的持续保存和共享。当用户访问一个WEB应用时,WEB服务器会自动创建一个Session对象,该对象可以供用户在会话期内在应用的所有页面中共享数据; Application是WEB应用的一个全局对象。
利用Session、Application对象,可以达到跟踪所有用户信息的目的。
当用户打开浏览器开始请求WEB应用的登录页面时,WEB服务即为该客户创建一个session,此后,在session的timeout时间内,该客户都使用这个session(timeout时间可设置,如Tomcat服务器是在各应用的l文件中设置)。如果使用IE浏览器,Session与客户IP地址、客户程序进程ID所共同标识的连接有对应关系,相同IP地址、相同进程的窗口(如通过IE-文件-新建-窗口 打开的新窗口)具有同一个session,所以session可用于标识各个独立的客户应用连接。
下面是一个样例
为了方便处理,先建一个简单类(user)用来表达用户信息及存放sessionId:
当用户打开浏览器开始请求WEB应用的登录页面时,WEB服务即为该客户创建一个session,此后,在session的timeout时间内,该客户都使用这个session(timeout时间可设置,如Tomcat服务器是在各应用的l文件中设置)。如果使用IE浏览器,Session与客户IP地址、客户程序进程ID所共同标识的连接有对应关系,相同IP地址、相同进程的窗口(如通过IE-文件-新建-窗口 打开的新窗口)具有同一个session,所以session可用于标识各个独立的客户应用连接。
下面是一个样例
为了方便处理,先建一个简单类(user)用来表达用户信息及存放sessionId:
package com; public class user { public String name=""; public String sessionId=""; } |
另一个类(testSession)用于处理用户的login、logout等动作信息,使系统可以跟踪当前连接的用户信息。
package com; import java.util.Vector; import com.user; public class testSession { public user User; private Vector vsid; public testSession() { User=new user(); } public boolean verify(String username,String password) throws Exception //验证用户/密码 { return true; } public void setSessionVar(String sesid,Vector sid) { this.User.sessionId=sesid; this.vsid=sid; } private static synchronized void addappses(user puser, Vector pvsid) { //记录一个新连接的用户 int pos=-1; user l_user; if (puser==null || pvsid==null) return; for(int i=0;i<pvsid.size();i++){ l_user=((i); if(l_user.sessionId.equals(puser.sessionId)){ pos=i; break; } } if(pos==-1){ pvsid.add(puser); } else{ pvsid.set(pos,puser); } } private static synchronized void removeappses(user puser, Vector pvsid) { //移除一个退出的用户 int pos=-1; user l_user; if (puser==null || pvsid==null) return; for(int i=0;i<pvsid.size();i++){ l_user=((i); if(l_user.sessionId.equals(puser.sessionId)){ pos=i; break; } } if(pos!=-1){ ve(pos); } } protected void finalize() { veappses(this.User,this.vsid); } public boolean login(String username) throws Exception { //处理登录 this.User.name=username; this.addappses(this.User,this.vsid); return true; } public boolean logout() throws Exception { //处理注销 this. finalize(); this.User=null; this.vsid=null; return true; } } |
每一个用户均建立一个testSession对象,来保存该用户的信息。为了对类testSession进行说明,必须同时引人另一个文件logintest.jsp。这个用于示例的JSP文件提供一个简单的界面进行登录、注销处理。文件内容如下:
<%@ page import=" stSession, java.util.Vector"%> <%@page contentType="text/html;charset=GBK" %> <% request.setCharacterEncoding(response. getCharacterEncoding());%> <% String Parameter("actiontype"); String actionResult=""; if(actionType!=null) { if(actionType.equals("login")){ // -1- String Parameter("username"); if(userName==null || userName.equals("")){ ; } else{ String Parameter("password"); if(password==null) password=""; testSession ts= (Attribute("testSession"); if(ts!=null) { //-1.1- veAttribute("testSession"); if( !ts.User.name.equals("")) ts.logout(); } ts=new testSession(); if(!ts.verify(userName,password)) { //验证用户与密码,看是否合法用户 actionResult="login fail"; //非法用户,显示错误信息 } else{ //验证成功 session.setAttribute("testSession",ts); Vector app_vts= (Attribute("app_vts"); if(app_vts==null) { app_vts=new Vector(); application.setAttribute("app_vts",app_vts); } ts.Id(),app_vts); ts.login(userName); actionResult=userName+" login success"; } } } if(actionType.equals("logout")){ testSession ts= (Attribute("testSession"); if(ts!=null) { veAttribute("testSession"); if( !ts.User.name.equals("")){ //-2- actionResult=ts.User.name; ts.logout(); } session.invalidate(); } actionResult=actionResult+" logout success"; } } else actionResult="null"; %> <head> <script LANGUAGE="Javascript"></script> <script> function doAction(actionType) { st.actiontype.value=actionType; st.submit(); } </script> </head> <body> <table width="80%" border="1" align="center" > <form method="POST" action="logintest.jsp" name="test"> <tr> <td height="33" align="right">用户:</td> <td width="70%"> <input name="username" type="text" value="" size="20"> </td> </tr> <tr> <td width="27%" height="22" align="right">密码:</td> <td width="73%"> <input name="password" type="password" size="20"> </td> </tr> <tr> <td height="32" colspan="2" align="right"> <div align="center"> <input name="B1" type="button" value="登录" onclick="doAction('login')"> <input name="B2" type="reset" value="重写"> <input name="B3" type="button" value="注销" onclick="doAction('logout')"> </div></td> </tr> <tr> <td width="27%" height="22" align="right"> <input name="actiontype" type="hidden" value=""></td> <td width="73%"> <input name="info" type="text" size="20" value="<%=actionResult%>"> </td> </tr> </form> </table> </body> |
[-1-]:程序的if(actionType.equals("login")){…}部分处理login。[-1.1-]前后部分先通过Attribute("testSession");取得session中保存的会话变量ts(一个testSession对象实例)。如果tssession和application的区别为空,表示当前用户还没有login,否则用户已经login了,则先logout再重新login,并将新testSession对象保存到session里。Attribute("app_vts");所取得的变量app_vts中保存了所有当前登录用户的user信息。每个用户login成功时,即往app_vts中添加一个user对象,这是通过testSession的addappses方法完成的。而当用户注销时,先从Attribute("testSession")中取到当前用户的testSession对象,该对象已含有Attribute("app_vts")对象的引用,通过testSession的logout方法进行注销处理(见[-2-]标记前后)。TestSession.logout最终是通过调用removeappses方法从全局对象app_vts中移除用户信息的。总结来说,程序利用应用全局对象application来保存跟踪用户连接信息的对象(例中为app_vts),该对象记录着应用中所有用户的连接、退出信息。
JSP页面运行的界面如图:
JSP页面运行的界面如图:
当我们输入用户testuser_1并按<登录>按钮,按钮下面的文本框显示"testuser_1 login success"。我们利用viewSessiones.jsp来观察结果,显示如下:
testuser_1 sessionId=A16DCE950C2C664D0AA93E05B27D8E00 |
viewSessiones.jsp文件的内容如下:
<%@ page import="stSession, com.user, java.util.Vector"%> <%@ page contentType="text/html; charset=GBK"%> <% request.setCharacterEncoding(response. getCharacterEncoding()); %> <% Vector l_vts=(Attribute("app_vts"); user l_us; if(l_vts!=null){ for(int i=0;i<l_vts.size();i++){ l_us=(user)(i); out.println(l_us.name+" sessionId="+l_us.sessionId); out.println("<br>"); } } %> |
viewSessiones.jsp文件的作用是将app_vts中的用户信息显示出来。
当我们从桌面再启动一个IE程序,输入用户testuser_2并按<登录>按钮,按钮下面的文本框显示"testuser_2 login success"。我们利用viewSessiones.jsp来观察结果,显示如下:
testuser_1 sessionId=A16DCE950C2C664D0AA93E05B27D8E00
testuser_2 sessionId=34B0AF3F1F2573F1C1DD12D62DF06F91
而当我们在第一个IE中按下按钮<注销>,logintest.jsp的显示为:
当我们从桌面再启动一个IE程序,输入用户testuser_2并按<登录>按钮,按钮下面的文本框显示"testuser_2 login success"。我们利用viewSessiones.jsp来观察结果,显示如下:
testuser_1 sessionId=A16DCE950C2C664D0AA93E05B27D8E00
testuser_2 sessionId=34B0AF3F1F2573F1C1DD12D62DF06F91
而当我们在第一个IE中按下按钮<注销>,logintest.jsp的显示为:
刷新viewSessiones.jsp来观察结果,显示如下:
testuser_2 sessionId=BC487C6A9FD663EA27E797A420B41051
我们在第二个IE中按下按钮<注销>,按钮下面的文本框显示"testuser_2 login success", 刷新viewSessiones.jsp来观察结果,显示出已经没有连接的用户信息。
testuser_2 sessionId=BC487C6A9FD663EA27E797A420B41051
我们在第二个IE中按下按钮<注销>,按钮下面的文本框显示"testuser_2 login success", 刷新viewSessiones.jsp来观察结果,显示出已经没有连接的用户信息。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论