如何用Session实现在线统计的功能,其实只要对Servlet规范详细了解一下,明白其基本原理,编写一个类似的功能并不是一件很复杂的事情。这个例子是基于2.3以上的规范编写的,最主要功能就是提供在线用户列表显示(既然用户列表都可以显示了,那人数统计自然也不在话下了)。
在给出代码之前,先简单说一下监听器的常识。
HttpSessionListener:这是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文件里了。
下面是具体的代码:
test.jsp
在给出代码之前,先简单说一下监听器的常识。
HttpSessionListener:这是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;
}
}
* 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))
{
%>
<%
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))
{
%>