- 浏览: 59023 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
liumingtong:
我想要你的联系方式.可以吗?要不你加我Q 3813774
success -
抛出异常的爱:
congdepeng 写道Liskov替换原则(LSP)
描 ...
设计原则 -
wumingshi:
楼主关于LSP的解释是错误的。LSP的精髓是,使用父类的代码可 ...
设计原则 -
liumingtong:
struts2的OGNL表达式
struts2的值栈
st ...
总结struts2 完成中······ -
Cindy_Lee:
Joy.zhang 写道
下面是具体的设计模式:
单例 ...
设计模式中11种
JSP作为后起之秀能够在服务器编程环境中占据一定地位,是和它良好支持一系列业界标准密切相关的。Session就是它提供的基础设施之一。作为一个程序员,你可以不介意具体在客户端是如何实现,就方便的实现简单的基于 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;
}
这两个函数位于一个HttpSessionManager类中.这个类引用了jsp里面的application全局对象。这个类的其他代码和本文无关且相当长,我就不贴出来了。
下面来看看jsp里面怎么用。
假设一个登录用的表单被提交到doLogin.jsp, 表单中包含UserName和password域。节选部分片段:
<%
HttpSessionManager hsm = new HttpSessionManager(application,request,response);
try
{
hsm.login();
}
catch ( UserNotFoundException e)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=User%20does%20not%20exist.");
return;
}
catch ( InvalidPasswordException e2)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=Invalid%20Password");
return;
}
catch ( Exception e3)
{
%> Error:<%=e3.toString() %><br>
Press <a href="login.jsp">Here</a> to relogin.
<% return;
}
response.sendRedirect("index.jsp");
%>
再来看看现在我们怎么得到一个当前在线的用户列表。
<body bgcolor="#FFFFFF">
<table cellspacing="0" cellpadding="0" width="100%">
<tr >
<td style="width:24px">SessionId
</td>
<td style="width:80px" >User
</td>
<td style="width:80px" >Login Time
</td>
<td style="width:80px" >Last access Time
</td>
</tr>
<%
Vector activeSessions = (Vector) application.getAttribute("activeSessions");
if (activeSessions == null)
{
activeSessions = new Vector();
application.setAttribute("activeSessions",activeSessions);
}
Iterator it = activeSessions.iterator();
while (it.hasNext())
{
HttpSession sess = (HttpSession)it.next();
JDBCUser sessionUser = (JDBCUser)sess.getAttribute("user");
String userId = (sessionUser!=null)?sessionUser.getUserID():"None";
%>
<tr>
<td nowrap=''><%= sess.getId() %></td>
<td nowrap=''><%= userId %></td>
<td nowrap=''>
<%= BeaconDate.getInstance( new java.util.Date(sess.getCreationTime())).getDateTimeString()%></td>
<td class="<%= stl %>3" nowrap=''>
<%= BeaconDate.getInstance( new java.util.Date(sess.getLastAccessedTime())).getDateTimeString()%></td>
</tr>
<%
}
%>
</table>
</body>
以上的代码从application中取出activeSessions,并且显示出具体的时间。其中BeaconDate类假设为格式化时间的类。
这样,我们得到了一个察看在线用户的列表的框架。至于在线用户列表分页等功能,与本文无关,不予讨论。
这是一个非刷新模型的例子,依赖于session的超时机制。我的同事sonymusic指出很多时候由于各个厂商思想的不同,这有可能是不可信赖的。考虑到这种需求,需要在每个叶面刷新的时候都判断当前用户距离上次使用的时间是否超过某一个预定时间值。这实质上就是自己实现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;
}
这两个函数位于一个HttpSessionManager类中.这个类引用了jsp里面的application全局对象。这个类的其他代码和本文无关且相当长,我就不贴出来了。
下面来看看jsp里面怎么用。
假设一个登录用的表单被提交到doLogin.jsp, 表单中包含UserName和password域。节选部分片段:
<%
HttpSessionManager hsm = new HttpSessionManager(application,request,response);
try
{
hsm.login();
}
catch ( UserNotFoundException e)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=User%20does%20not%20exist.");
return;
}
catch ( InvalidPasswordException e2)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=Invalid%20Password");
return;
}
catch ( Exception e3)
{
%> Error:<%=e3.toString() %><br>
Press <a href="login.jsp">Here</a> to relogin.
<% return;
}
response.sendRedirect("index.jsp");
%>
再来看看现在我们怎么得到一个当前在线的用户列表。
<body bgcolor="#FFFFFF">
<table cellspacing="0" cellpadding="0" width="100%">
<tr >
<td style="width:24px">SessionId
</td>
<td style="width:80px" >User
</td>
<td style="width:80px" >Login Time
</td>
<td style="width:80px" >Last access Time
</td>
</tr>
<%
Vector activeSessions = (Vector) application.getAttribute("activeSessions");
if (activeSessions == null)
{
activeSessions = new Vector();
application.setAttribute("activeSessions",activeSessions);
}
Iterator it = activeSessions.iterator();
while (it.hasNext())
{
HttpSession sess = (HttpSession)it.next();
JDBCUser sessionUser = (JDBCUser)sess.getAttribute("user");
String userId = (sessionUser!=null)?sessionUser.getUserID():"None";
%>
<tr>
<td nowrap=''><%= sess.getId() %></td>
<td nowrap=''><%= userId %></td>
<td nowrap=''>
<%= BeaconDate.getInstance( new java.util.Date(sess.getCreationTime())).getDateTimeString()%></td>
<td class="<%= stl %>3" nowrap=''>
<%= BeaconDate.getInstance( new java.util.Date(sess.getLastAccessedTime())).getDateTimeString()%></td>
</tr>
<%
}
%>
</table>
</body>
以上的代码从application中取出activeSessions,并且显示出具体的时间。其中BeaconDate类假设为格式化时间的类。
这样,我们得到了一个察看在线用户的列表的框架。至于在线用户列表分页等功能,与本文无关,不予讨论。
这是一个非刷新模型的例子,依赖于session的超时机制。我的同事sonymusic指出很多时候由于各个厂商思想的不同,这有可能是不可信赖的。考虑到这种需求,需要在每个叶面刷新的时候都判断当前用户距离上次使用的时间是否超过某一个预定时间值。这实质上就是自己实现session超时。如果需要实现刷新模型,就必须使用这种每个叶面进行刷新判断的方法。
发表评论
-
利用jsp读取远程文件保存到本地
2010-07-14 18:02 1841本文介绍利用jsp读取远程文件保存到本地的文章专题。 用js ... -
jsp+tomcat+mysql&sevlet&javabean配置
2010-07-14 18:01 682在配置jsp开发环境的过 ... -
JSP中用bean封装常用的功能
2010-07-14 18:00 713本文介绍JSP中用bean封装常用的功能的文章专题。 1、建 ... -
JSP中关于html的转换技巧
2010-07-14 17:59 609本文介绍JSP中关于html的转换技巧的文章专题。 publ ... -
在JSP中设置HTTP应答头
2010-07-14 17:58 770本文介绍在JSP中设置HTTP应答头的文章专题。 Prime ... -
在JSP中访问CORBA服务对象实例
2010-07-14 17:58 804结合J2EE和CORBA可以充分 ... -
学习jsp与javascript结合在页面间传递参数
2010-07-14 17:57 1285本文介绍学习jsp与javascript结合在页面间传递参数的 ... -
JSP Commons FileUpload 组件上传文件的总结
2010-07-14 17:57 912本文介绍JSP Commons FileUpload 组件上传 ... -
JSP开发前设置
2010-07-14 17:56 681由于朋友问起我开发JSP前都要做些什么,就写了这篇东东。 ? ... -
JSP应用语法详解集三
2010-07-14 17:56 733本文介绍JSP应用语法详 ... -
JSP应用语法详解集二
2010-07-14 17:55 681本文介绍JSP应用语法详解集二的文章专题。 8)标签: 转发 ... -
JSP应用语法详解集一
2010-07-14 17:55 605本文介绍JSP应用语法详解:HTML注释,隐藏注释,Page指 ... -
提升JSP应用程序的7大绝招
2010-07-14 17:54 734本文的目的是通过对servlet和JSP的一些调优技术来极大地 ... -
JSP技巧之:session在何时被创建
2010-07-14 17:54 643本文介绍JSP技巧之:session在何时被创建的文章专题。 ... -
谈谈JSP的九个隐含对象
2010-07-14 17:53 880本文介绍谈谈JSP的九个隐含对象的文章专题,例如:储存和取得属 ... -
解决JSP与MySQL交互的中文乱码问题
2010-07-14 17:51 670首先实现了一个StringConvert bean(GBtoI ... -
JSP几个常见问题
2010-07-14 17:51 703本文介绍JSP几个常见问题的文章专题,Hashtable和 H ... -
JSp的Taglib Directiv语法,属性概述
2010-07-14 17:50 750指示(directive)允许您使用自定义的标签,为标签库命名 ... -
JSP连接SQL Server 2000系统详细配置
2010-07-14 17:50 594到SUN官方站点(http://java.sun.com)下载 ... -
JSP中标签库的深入研究
2010-07-14 17:50 636标签处理器和标签附加信息需要定位在JSP容器类载入器可以找到的 ...
相关推荐
本文将基于给定的代码片段和描述,详细介绍如何利用JSP技术来实现在线人数和在线用户的统计。 #### 关键技术介绍 1. **JSP (JavaServer Pages)** - JSP是一种基于Java技术的服务器端脚本语言,它允许在HTML页面中...
当用户离开时,由于Session超时,计数器不会减1,但这种统计方法通常只能近似反映在线人数,因为用户关闭浏览器并不会立即从计数器中移除。 ```jsp Integer number = (Integer)application.getAttribute("Count"); ...
为了实现这个功能,我们需要在用户登录时增加一个在线用户计数器,并在用户登出或者会话超时时减少计数。这通常涉及到服务器端session的管理和维护。当用户登录成功,创建session并将在线人数加一;反之,如果检测到...
通过学习和实践这些知识点,开发者能够构建出一个完整的基于JSP的会员制网络广告系统,提供用户友好的界面,安全的数据管理,以及有效的广告投放和分析功能。同时,这样的系统也可以作为进一步学习Web开发、数据库...
5. **报表统计**:生成各种报表,如收入报表、车位使用率报表,便于管理者分析决策。 6. **异常处理**:处理如无牌车、未缴费车辆离场等特殊情况。 **四、关键技术** 1. **数据库技术**:如MySQL,用于存储用户...
【基于JSP在线书店系统】是一个完整的Web应用程序,它展示了JSP(JavaServer Pages)技术在企业级应用中的实际运用。这个系统的核心功能是提供一个线上平台,让用户能够浏览、搜索书籍,进行购买操作,同时也包含了...
在Java JSP(JavaServer Pages)环境中,统计在线人数是一项常见的需求,这通常涉及到服务器端的会话管理、数据持久化以及实时性处理。这里我们将深入探讨如何利用JSP技术来实现这一功能。 首先,我们需要理解JSP的...
2. **在线用户统计**:为了统计在线用户,我们需要记录当前活动的会话数量。这可以通过定期检查所有活动的会话并计算其数量来完成。在Servlet容器(如Tomcat)中,可以使用特定的API来获取这些信息。同时,为了防止...
【JSP流量统计系统】是一种基于Java服务器页面(JSP)技术构建的系统,用于收集、分析和展示网站访问量的相关数据。此类系统的核心目标是为网站管理员提供关于用户行为的详细信息,如访问次数、停留时间、热门页面等...
在JSP中,可以使用session或cookie来跟踪独立访客,每次用户访问时增加计数。这个项目可能使用了一个全局变量或者数据库记录来保存并更新访问次数。 3. **加入会员功能**:用户注册功能涉及用户输入验证、密码加密...
这个系统能够收集用户的选择,并对收集到的数据进行统计和分析,为用户提供直观的结果展示。 首先,JAVA作为后端的主要开发语言,它在Web开发中扮演着服务器端的角色,负责处理用户的请求、业务逻辑以及与数据库的...
这种系统的核心目标是提供一个用户友好的界面,让乘客可以方便地购买地铁票,同时后台管理系统能进行数据管理、统计分析等功能。以下是关于JSP地铁售票系统的详细知识点: 1. **JSP技术基础**:JSP是一种动态网页...
本项目是一个基于JSP技术与MySQL数据库构建的在线学习网站,旨在提供一个便捷、高效的网络学习平台。这个平台允许用户注册、登录,并能够浏览、搜索课程,参与在线学习,实现个人学习进度的跟踪。同时,它还包含一份...
- **统计分析模块**:对考试数据进行统计分析,如平均分、最高分、最低分等,为教学改进提供依据。 **3. 技术栈选型** 为了构建这样的系统,除了JSP外,我们还需要其他技术配合,如: - **Servlet**:JSP的后端...
在登录功能上,系统可能实现了会话管理,使用了JSP内置对象Session来跟踪用户状态,确保用户在登录后能访问受限资源。同时,登录页面可能还包含了防止SQL注入的安全措施,例如使用预编译语句或参数化查询。 注册...
3. **JSP内置对象**:JSP提供了9个内置对象,包括request、response、session、application、pageContext、out、config、exception和page,它们是Java Servlet API中的对象,简化了开发过程。 ### JSP运行环境配置 ...
此外,为了提升用户体验和数据处理能力,系统还集成了Excel导入导出功能,以及性别和地域的统计分析,通过饼状图展示结果。在安全方面,注册时采用了邮箱激活验证,登录则通过随机生成的验证码进行验证。 1. **JSP*...
- **SQL在考试系统中的应用**:创建和管理试题库,根据用户需求动态生成试卷,记录用户答题情况,统计分析结果。 5. **考试系统功能** - **用户管理**:注册、登录、个人信息管理,权限控制(如管理员、普通考生...
2. **Web应用架构**:基于jsp的在线考试系统通常采用三层架构:表现层(用户界面)、业务逻辑层(处理考试相关业务规则)和数据访问层(与数据库交互)。JSP在表现层用于生成动态内容,而Servlet或JavaBeans通常用于...