在线登录用户统计只统计登录后的在线用户,忽略未登录的用户,并且同一帐号不允许多次登录,即当用户登录时,如果该用户帐号已经在其他地方登录,则自动踢出之前登录的用户。登录标识为Session中logonUserView属性是否为null。实现原理:借助HttpSessionAttributeListener和HttpSessionListener来实现。用户登录时,如果密码验证通过,则判断改用户是否已经登录,如果已经登录则将之前登录的用户强制注销,然后将记录这用户信息的LogonUserView对象放入当前session,这时候HttpSessionAttributeListener的attributeAdded事件被触发,该用户被记录到在线用户列表。用户注销时或Session自动失效时,会触发HttpSessionListener的sessionDestroyed事件,从在线用户列表中移除注销用户。具体实现代码如下:
该统计方法在集群环境下无法使用,集群环境可以将在线用户信息存入数据库,各服务器连接统一数据库
1. LogonUserView类,记录登录后用户信息
public class LogonUserView implements java.io.Serializable {
private String userid;
private String userName;
// 省略其他属性和get、set方法
}
2. OnlineUserView类,记录在线用户信息
public class OnlineUserView {
private String userId;
private String userName;
private String loginIP;
// 在线用户对应Session,踢用户时使用
private HttpSession userSession;
// 省略其他属性和get、set方法
}
3. 登录方法(片段)
// 检测是否是在不同浏览器下已有相同用户Id的用户登陆
List onlineUsers = OnlineUserListener.getOnlineUsers();
for(int i = 0; i < onlineUsers.size(); i++){
// 在线用户视图
OnlineUserView onlineUserView = (OnlineUserView)onlineUsers.get(i);
// 在线用户Session
HttpSession onlineUserSession = onlineUserView.getUserSession();
// 同一用户
if(authorizedUserId.equals(onlineUserView.getUserId())){
// 在不同机器上登陆,提示,否则不提示
if(!request.getRemoteAddr().equals(onlineUserView.getLoginIP())){
// 提示信息
}
try{
if(!onlineUserSession.getId().equals(request.getSession().getId())){
// 强制注销之前登陆用户,并将该用户从在线用户列表删除
onlineUserSession.invalidate();
}
}catch(IllegalStateException ise){}
break;
}
}
// 绑定登陆用户信息到Session,监听器自动将该用户添加到在线用户列表
request.getSession().setAttribute("logonUserView", logonUserView);
4. 注销方法(片段)
// 使session失效,触发sessionDestroyed事件,从在线用户列表中移除注销用户
session.invalidate();
5. 在线用户监听器
public class OnlineUserListener implements HttpSessionAttributeListener, HttpSessionListener {
/**
* 在线用户列表
*/
private static List onlineUsers = new ArrayList();
/**
* 获取在线用户列表
* @return
*/
public static List getOnlineUsers(){
return onlineUsers;
}
/*
* session 属性添加时(即首次执行setAttribute时)触发
*/
public void attributeAdded(HttpSessionBindingEvent event) {
if(event.getSession()==null){
return;
}
// 当执行setAttribute("logonUserView",logonUserView)时
// 将当前用户添加到在线用户列表中
if(event.getName().equalsIgnoreCase("logonUserView")){
// 获取当前登陆用户信息及session
LogonUserView user = (LogonUserView)event.getValue();
HttpSession session = event.getSession();
// 创建在线用户信息对象
OnlineUserView onlineUserView = new OnlineUserView();
onlineUserView.setLoginIP(user.getLoginIP());
onlineUserView.setUserId(user.getUserfullid());
onlineUserView.setUserName(user.getUsername());
onlineUserView.setUserSession(session);
// 添加到在线用户列表
onlineUsers.add(onlineUserView);
}
}
/*
* session 属性移除时(即执行removeAttribute时)触发
*/
public void attributeRemoved(HttpSessionBindingEvent event) {
}
/*
* session 属性更新时(即再次执行setAttribute时)触发
*/
public void attributeReplaced(HttpSessionBindingEvent event) {
if(event.getSession()==null){
return;
}
// 当执行再次执行setAttribute("logonUserView")时,发生用户替换
if(event.getName().equalsIgnoreCase("logonUserView")){
// 获取被替换用户信息及session
LogonUserView user = (LogonUserView)event.getValue();
// 更新在线用户信息
HttpSession session = event.getSession();
// 获取当前登陆用户信息
LogonUserView newUser = (LogonUserView)session.getAttribute("logonUserView");
// 循环查找被替换用户在线信息
for(int i=0;i<onlineUsers.size();i++){
OnlineUserView onlineUserView = (OnlineUserView)onlineUsers.get(i);
if(onlineUserView.getUserId().equals(user.getUserfullid())){
// 更新在线用户信息
onlineUserView.setLoginIP(newUser.getLoginIP());
onlineUserView.setUserId(newUser.getUserfullid());
onlineUserView.setUserName(newUser.getUsername());
break;
}
}
}
}
/*
* session 创建时触发
*/
public void sessionCreated(HttpSessionEvent event) {
}
/*
* session 销毁时(即用户注销、session超时时)触发
*/
public void sessionDestroyed(HttpSessionEvent event) {
if(event.getSession()==null){
System.out.println("OnlineUserListener.sessionDestroyed() session==null");
return;
}
// 获取当前登陆用户信息及session
HttpSession session = event.getSession();
for(int i=0; i<onlineUsers.size();i++){
OnlineUserView onlineUserView = (OnlineUserView)onlineUsers.get(i);
if(onlineUserView!=null && onlineUserView.getUserSession()!=null && session!=null
&& onlineUserView.getUserSession().getId().equals(session.getId())){
// 从在线用户列表移除用户
onlineUsers.remove(onlineUserView);
break;
}
}
}
}
说明:
该统计方法在集群环境下无法使用,集群环境可以将在线用户信息存入数据库,各服务器连接统一数据库