JSPCN主页
|
JSP空间
|
网站制作
|
JSP下载
|
JSP论坛
|
JSP教程
|
关于JSPCN
|
联系我们
做最专业的JSP中文网站
当前位置
:
首页
--
JSP技术
--
JSP其他
文章搜索:
关键字
标题
JSP中文网内容管理系统(JCMS)
JSP虚拟主机
网络笔记本
网摘,图片,笔记收藏
虚拟服务器
JSPCN文章目录分类
JSP配置
[
219
]
JSP基础
[
136
]
中文问题
[
69
]
上传问题
[
27
]
JAVABEAN
[
46
]
数据库
[
212
]
文件操作
[
126
]
图片声音
[
17
]
JSP其他
[
57
]
时间相关
[
16
]
JAVAMAIL
[
72
]
STRUTS
[
144
]
开发工具
[
28
]
教程系列
[
157
]
JSP实例
[
89
]
JAVA基础
[
421
]
APPLET
[
78
]
JAVA网络
[
179
]
Applica
[
115
]
Servlet
[
98
]
XML
[
163
]
J2ME
[
257
]
J2EE
[
374
]
考试相关
[
63
]
JAVA线程
[
90
]
EJB
[
261
]
Swing
[
26
]
Java API
[
141
]
声音图片
[
28
]
异常处理
[
33
]
JAVA实例
[
290
]
JAVA类
[
139
]
SUN
[
89
]
Hibernate
[
6
]
JMX
[
8
]
Spring
[
34
]
本版推荐文章
用缓冲技术提高JSP应用的性能和稳定性
编写线程安全的JSP程序
JSP漏洞大观
JSP安全性初探
获取jsp各种参数
用JavaMail写简易电子邮件发送系统
如何防止IE缓存jsp文件
调试程序里的 NullPointerException
jsp设计模式
用JSP实现类似资源管理器式的文件与目录的折叠(代码示例)
JSP显示内容缓存技巧
利用iText在JSP中生成PDF报表
Tomcat5.x中的虚拟主机配置方法
jsp实现购物程序
用JSP/ASP创建WAP应用
使用JSP读取客户端信息
apache+resin+pureftp的虚拟主机和负载均衡
JSP动作(标签)
开发JSP自定义行为
Jsp中的Application使用
本版热点文章
apache+resin+pureftp的虚拟主机和负载均衡
用JavaMail写简易电子邮件发送系统
Tomcat5.x中的虚拟主机配置方法
jsp实现购物程序
开发JSP自定义行为
JSP漏洞大观
使用JSP读取客户端信息
用缓冲技术提高JSP应用的性能和稳定性
调试程序里的 NullPointerException
jsp设计模式
获取jsp各种参数
JSP安全性初探
用JSP实现类似资源管理器式的文件与目录的折叠(代码示例)
编写线程安全的JSP程序
JSP动作(标签)
JSP的模板
用JSP/ASP创建WAP应用
利用iText在JSP中生成PDF报表
使用JSP技术设计电子商务应用系统--从入门到精通(一)
如何防止IE缓存jsp文件
相关文章链接
再论Session事件的捕获
作者: 文章来源:
访问次数:20次 加入时间:2007年04月21日
最近又有网友问到,如何用Session实现在线统计的功能,其实只要对Servlet规范详细了解一下,明白其基本原理,编写一个类似的功能并不是一件很复杂的事情。我以前的一篇文章,最初也是发表在JavaResearch上的(
http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=2164
),不过可能源码没有全部给出,只给出了最重点的源码,所以还是有很多网友给我发信索取全部源码。因为那个项目是以前做的,所以我手头上也没有原来的代码了,所以可能有的网友的要求就满足不了了,在这里一并致歉。
第一篇文章是基于Servlet2.2规范编写的,那时候没有HttpSessionListener,鉴于目前绝大多数的应用服务器都支持2.3的规范,所以为了回应网友的提问,特地又基于2.3以上的规范编写了一个简单的测试例子。
这个例子的最主要功能就是提供在线用户列表显示(既然用户列表都可以显示了,那人数统计自然也不在话下了)。
在给出代码之前,先简单说一下监听器的常识。
HttpSessionListener:网友rdfei 在他的文章(
http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=18541
)中也已经进行了比较详细的描述,这是2.3以上规范所提供的一个新功能,也就是可以定义监听器监听HttpSession对象的创建和销毁。每当有新的用户访问网站,应用服务器会创建一个HttpSession对象,每当Session超时,应用服务器则会销毁这个对象。
HttpSessionBindingListener:每当往Session中存入一个对象(setAttribute)或从Session中删除一个对象的时候,如果这个对象实现了此监听器接口,应用服务器将会自动调用接口相应的方法。
需要注意的一点就是,在sessionDestroyed方法和valueUnbound方法中,你可以得到HttpSession对象的实例,但是其getAttribute方法不再可用,也就是在这两个方法中,你不能再次得到存入session中的对象。
基于以上这些粗浅的认识,再简单介绍一下我提供的测试例子的情况:
测试例子总共包含如下文件:
OnlineUserListener.java:它实现了HttpSessionListener接口
OnlineUsers.java:它包含了所有正在访问网站的用户信息,为了方便起见,它也实现了HttpSessionBindingListener接口(实际中你最好把他们分开吧)
User.java:这是用户的信息
test.jsp:为了方便,我把登录,退出,显示在线用户列表等功能都做在同一个jsp文件里了。
下面是具体的代码:
/**
* OnlineUserListener.java
* Created on 2004-11-19
*/
package
com.ccctc.view.web;
import
javax.servlet.http.
HttpSessionEvent
;
import
javax.servlet.http.
HttpSessionListener
;
/**
* @author litf
*
*/
public
class
OnlineUserListener
implements
HttpSessionListener
{
/**
* 浏览器第一次访问的时候,调用本方法
* @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent)
*/
public
void
sessionCreated(
HttpSessionEvent
event) {
User u =
new
User();
u.setName(
"guest"
);
u.setId(event.getSession().getId());
event.getSession().setAttribute(
"currentUser"
,u);
OnlineUsers.getInstance().addUser(u);
}
/**
* Session超时的时候,调用本方法
* @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent)
*/
public
void
sessionDestroyed(
HttpSessionEvent
event) {
OnlineUsers.getInstance().removeUser(event.getSession().getId());
}
}
/**
* OnlineUsers.java
* Created on 2004-11-19
*/
package
com.ccctc.view.web;
import
java.util.
Collection
;
import
java.util.
HashMap
;
import
java.util.
Map
;
import
javax.servlet.http.
HttpSession
;
import
javax.servlet.http.
HttpSessionBindingEvent
;
import
javax.servlet.http.
HttpSessionBindingListener
;
/**
* @author litf
* 在线用户统计
*/
public
class
OnlineUsers
implements
HttpSessionBindingListener
{
private
Map
users =
new
HashMap
();
private
static
OnlineUsers onlineUsers =
new
OnlineUsers();
public
static
OnlineUsers getInstance(){
return
onlineUsers;
}
/**
* @return
*/
public
Collection
getUsers() {
return
users.values();
}
public
void
addUser(User user) {
users.put(user.getId(),user);
}
public
void
removeUser(
String
userId){
users.remove(userId);
}
/**
* 对象实例(即OnlineUserListener的实例)作为一个属性被设置到session的
* 时候,会调用本方法,这种情况一般发生在点击登录按钮以后的处理过程中
* 设置
* @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent)
*/
public
void
valueBound(
HttpSessionBindingEvent
event) {
//现在暂时不需要额外处理,你可以在这里记录日志等
}
/**
* 当Session超时,或本实例被从session中移除的时候被调用,这种情况一般
* 发生在注销方法的处理过程中
* @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent)
*/
public
void
valueUnbound(
HttpSessionBindingEvent
event) {
try
{
HttpSession
session = event.getSession();
User u = (User)session.getAttribute(
"currentUser"
);
u.setName(
"guest"
);
}
catch
(
RuntimeException
e) {
//e.printStackTrace();
}
}
}
/**
* User.java
* Created on 2004-11-19
*/
package
com.ccctc.view.web;
/**
* @author litf
*
*/
public
class
User{
private
String
address;
private
String
id;
private
String
name;
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public
boolean
equals(
Object
obj) {
if
(obj ==
null
|| !(obj
instanceof
User)) {
return
false
;
}
if
(
this
.id !=
null
&&
this
.id.equals(((User)obj).getId())){
return
true
;
}
return
false
;
}
/**
* @return
*/
public
String
getAddress() {
return
address;
}
/**
* @return
*/
public
String
getId() {
return
id;
}
/**
* @return
*/
public
String
getName() {
return
name;
}
/**
* @param string
*/
public
void
setAddress(
String
string) {
address = string;
}
/**
* @param string
*/
public
void
setId(
String
string) {
id = string;
}
/**
* @param string
*/
public
void
setName(
String
string) {
name = string;
}
/**
* @see java.lang.Object#toString()
*/
public
String
toString() {
return
"name:"
+name +
",id:"
+ id +
",address:"
+address;
}
}
test.jsp
<%@ page
import
=
"com.ccctc.view.web.*"
%>
<%
User u = (User)session.getAttribute(
"currentUser"
);
String
name = request.getParameter(
"user"
);
if
(u !=
null
){
String
remote = request.getRemoteAddr();
u.setAddress(remote);
}
//User Login
if
(name !=
null
){
if
(u !=
null
){
session.setAttribute(
"_listener"
,OnlineUsers.getInstance());
u.setName(name);
}
}
//User Logout
String
logout = request.getParameter(
"logout"
);
if
(logout !=
null
){
session.removeAttribute(
"_listener"
);
}
%>
current users:<p>
<%
java.util.
Collection
l = OnlineUsers.getInstance().getUsers();
for
(java.util.
Iterator
it = l.iterator(); it.hasNext();)
{
User tu = (User)it.next();
if
(u.equals(tu))
{
%>
<font color=red><%=tu.getName()%>:<%=tu.getAddress()%> </font>
<%
}
else
{
%>
<%=tu.getName()%>:<%=tu.getAddress()%>
<%
}
}
%>
<form action=
"/cctc/login.jsp"
>
User : <input name=
"user"
type=
"text"
> <br>
<input type=
"submit"
name=
"Submit"
>
</form>
<p>
<a href=
"/cctc/login.jsp?logout=true"
>Logout</a> <p>
<a href=
"/cctc/login.jsp"
>refresh</a>
web.xml文件中增加:
<listener>
<listener-
class
>com.ccctc.view.web.OnlineUserListener</listener-
class
>
</listener>
附件:SessionTest.rar(95K)
Copyright © 2002-2005
JSP
CN.net. All rights reserved.
JSP中文网 备案序号:蜀ICP备05001583号
成都恒海科技发展有限公司 成都市一环路南二段6号新瑞楼三楼8号