这是书上一个servlet监听在线人数的例子,原理是:有个UserInfoList类保存相关用户名在vector中,代码如下:
package cn.aust.userinfo;
import java.util.Vector;
public class UserInfoList {
private static UserInfoList user=new UserInfoList();
/*
* 利用private调用构造函数
* 防止被外界产生新的instance对象
* */
private Vector vector=null;
public UserInfoList(){
this.vector=new Vector();
}
public static UserInfoList getInstance(){
return user;
}
// 增加用户
public boolean addUserInfo(String user){
if(user!=null){
this.vector.add(user);
return true;
}else{
return false;
}
}
// 获取用户列表
public Vector getList(){
return vector;
}
// 移除用户
public void removeUserInfo(String user){
if(user!=null){
vector.removeElement(user);
}
}
}
////////////////////////////////
UserInfoTrace类监听在线人数
package cn.aust.userinfo;
import javax.servlet.http.HttpSessionBindingEvent;
public class UserInfoTrace implements javax.servlet.http.HttpSessionBindingListener {
private String user;
private UserInfoList container=UserInfoList.getInstance();
public UserInfoTrace(){
user="";
}
// 设置在线的监听人员
public void setUser(String user){
this.user=user;
}
public String getUser(){
return this.user;
}
public void valueBound(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
System.out.println("上线"+this.user);
}
public void valueUnbound(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
System.out.println("下线"+this.user);
if(user!=""){
container.removeUserInfo(user);
}
}
}
/////////
下面是两个Jsp页面登陆和在线人数显示
login.jsp
<body>
<form action="showUser.jsp" method="post" name="loginform">
<input type="text" name="username"/>
<input type="submit" value="登陆"/>
</form>
</body>
showUser.jsp
<%
String username=request.getParameter("username");
UserInfoList list=UserInfoList.getInstance();
UserInfoTrace ut=new UserInfoTrace();
ut.setUser(username);
session.setAttribute("+username+",ut);
list.addUserInfo(ut.getUser());
session.setMaxInactiveInterval(100);
%>
<textarea rows="8" cols="20">
<%
Vector vector=list.getList();
if(vector!=null&&vector.size()>0){
for(int i=0;i<vector.size();i++){
out.println(vector.elementAt(i));
}
}
%>
</textarea>
????????????
问题是我登陆上一个,container.removeUserInfo 删除一个????
一、session放的时候,如果这个key没有值,则触发valueBound。如果之前已经有值了,看看后放的这两个是不是一样的,一样的就什么也不触发,如果不一样,则先bound后来的那个,再unbound旧的那个。你这个不管用户之前有没有登录过,都new一个UserInfoTrace放进去,显然必于后者。
二、session.setAttribute("+username+",ut);这是你的代码,其中 "+username+" 简直不能再迷惑,你也不用代码高亮。 "+username+" 这个是常量String,所以key是恒定的。
-----下面是我猜的
解释一下控制台打印:
111登录 UserInfoTrace1111->valueBound
222登录 UserInfoTrace2222->valueBound
UserInfoTrace1111->valueUbound
//这个地方,很有可能你过了100秒了,session超时了
UserInfoTrace2222->valueUbound
重复222
把session.setAttribute(username,ut);解决了,谢谢