session 之session混乱解决方法

  session 之session混乱解决方法 收藏
知道了session混乱产生的原因之后,也就知道了问题的根源。同时也引出了很多的问题:

1、如何记录住在线人员(这里只有帐号的系统用户,不包括访客);

2、如何限制同一个帐号在同一时间段内只能够登陆一次系统?

3、如何限制不同的用户在同一台机器上登陆系统?

4、管理员如何踢人?

我们首先来分析上面的问题:

首先在服务器端当用户通过身份验证成功登陆系统之后,我们将此用户的信息记录住(OnLineUserManager.java),包括帐号、登陆日期、机器的IP地址、session的ID,session对象。(记住session的ID极其重要,因为服务器识别session是根据id,只要id相同,服务器就认为是同一个用户);

(上面解决了问题1)

这样当用户登陆系统的时候我们首先根据帐号判断用户是否登陆了,如果已经登陆,提示用户;(这样就解决了问题2)

如果未登陆,判断用户的session的id是否已经在用户的信息OnLineUserManager里面了,如果是提示用户

关闭当前窗口,重新点击IE打开一个新的浏览器窗口。(这样session就不会混乱了)。

如果要限制不同的用户在同一台机器上登陆系统?这个就要根据IP地址来判断了。如果OnLineUserManager中

有通过这个机器登陆系统的用户,那么就提示用户同一台机器只能够一个帐号登陆;

(问题3也就解决了,注意:如果用户使用了代理服务器,那么此方法失效。这个方法适用于管理规范的用户,客户在局域网内使用,每个客户有固定的ip。)

问题4如何踢人?你想想OnLineUserManager中记录了用户session对象,只要根据用户的帐号找到对应的

session对象,然后session.invalidate();这样就可以彻底的将捣乱的人提出系统了。

===============需要注意的是OnLineUserManager必须是线程安全的=我的实现如下==============

view plaincopy to clipboardprint?
package com.work.qxgl.login;  
 
 
 
import java.util.Vector;  
 
 
 
import org.apache.commons.logging.Log;  
 
import org.apache.commons.logging.LogFactory;  
 
 
 
import com.work.util.DateUtil;  
 
 
 
/** 
 
 * 统计在线用户数。前提是登录的时候限制一个用户只能够在系统中登录一次。 有了这个功能,管理员就可以管理在线用户,如果谁不服从管理,就可以从系统中踢出去。 
 
 * TODO 将jsp放到WEB-INF后面,然后所有的URL必须通过struts的action调用。 使用拦截器Interceptor来实现权限的控制! 
 
 * 或者通过web中的Filter来实现权限控制! 实现权限管理系统日志的记录! 
 
 *  
 
 * @author wangmingjie 
 
 *  
 
 */ 
 
public class OnLineUserManager {  
 
    private static Log log = LogFactory.getLog(OnLineUserManager.class);  
 
    private Vector<OnLineUser> users = null;  
 
 
 
 
 
    private OnLineUserManager() {  
 
        users = new Vector<OnLineUser>();//在构造函数中初始化  
 
    }  
 
      
 
    static class SingletonHolder {  
 
        static OnLineUserManager instance = new OnLineUserManager();  
 
    }  
 
 
 
    /** 
 
     * 单例模式。这样简单而且能够保证线程安全。 
 
     *  
 
     * @return 
 
     */ 
 
    public static OnLineUserManager getInstance() {  
 
        return SingletonHolder.instance;  
 
    }  
 
 
 
    /** 
 
     * 获取到登录用户的数量。 
 
     *  
 
     * @return 
 
     */ 
 
    public synchronized int getCount() {  
 
        users.trimToSize();  
 
        return users.capacity();  
 
    }  
 
 
 
    /** 
 
     * 通过用户帐号判断该用户是否存在! 必须保证是线程安全的。 
 
     *  
 
     * @param userAccount 
 
     * @return 
 
     */ 
 
    public synchronized boolean existUser(String userAccount) {  
 
        users.trimToSize();  
 
        boolean existUser = false;  
 
        for (int i = 0; i < users.capacity(); i++) {  
 
            if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {  
 
                existUser = true;  
 
                break;  
 
            }  
 
        }  
 
        return existUser;  
 
    }  
 
      
 
    /** 
 
     * @param sessionid 
 
     * @return 
 
     */ 
 
    public synchronized boolean existSession(String sessionid) {  
 
        users.trimToSize();  
 
        boolean existUser = false;  
 
        for (int i = 0; i < users.capacity(); i++) {  
 
            if (sessionid.equals(((OnLineUser) users.get(i)).getSessionId())) {  
 
                existUser = true;  
 
                break;  
 
            }  
 
        }  
 
        return existUser;  
 
    }  
 
      
 
 
 
    /** 
 
     * 删除用户 
 
     *  
 
     * @param userAccount 
 
     * @return 
 
     */ 
 
    public synchronized boolean deleteUser(String userAccount) {  
 
        users.trimToSize();  
 
        if (existUser(userAccount)) {  
 
            int currUserIndex = -1;  
 
            for (int i = 0; i < users.capacity(); i++) {  
 
                if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {  
 
                    currUserIndex = i;  
 
                    break;  
 
                }  
 
            }  
 
            if (currUserIndex != -1) {  
 
                users.remove(currUserIndex);  
 
                users.trimToSize();  
 
                log.debug("用户" + userAccount + "退出系统" 
 
                        + DateUtil.getCurrentDateTime());  
 
                log.debug("在线用户数为:" + getCount());  
 
                return true;  
 
            }  
 
        }  
 
        return false;  
 
    }  
 
      
 
    /** 
 
     * 根据用户帐号,获取在线用户信息 
 
     * @param userAccount 
 
     * @return 
 
     */ 
 
    public synchronized OnLineUser getUser(String userAccount) {  
 
        users.trimToSize();  
 
        if (existUser(userAccount)) {  
 
            int currUserIndex = -1;  
 
            for (int i = 0; i < users.capacity(); i++) {  
 
                if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {  
 
                    currUserIndex = i;  
 
                    break;  
 
                }  
 
            }  
 
            if (currUserIndex != -1) {  
 
                return  users.get(currUserIndex);  
 
            }  
 
        }  
 
        return null;  
 
    }  
 
 
 
    /** 
 
     * 获取到在线用户的信息。 
 
     *  
 
     * @return 
 
     */ 
 
    public synchronized Vector<OnLineUser> getOnLineUser() {  
 
        return users;  
 
    }  
 
 
 
    public synchronized void addUser(OnLineUser onLineUser) {  
 
        users.trimToSize();  
 
        if (!existUser(onLineUser.getUserAccount())) {  
 
            users.add(onLineUser);  
 
            log.debug(onLineUser.getUserAccount() + "/t登录到系统/t" + DateUtil.getCurrentDateTime());  
 
            // 通过request才能够获取到用户的ip等信息  
 
        } else {  
 
            log.debug(onLineUser.getUserAccount() + "已经存在");  
 
        }  
 
        log.debug("在线用户数为:" + getCount());  
 
    }  
 
 
 

package com.work.qxgl.login;

 

import java.util.Vector;

 

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

 

import com.work.util.DateUtil;

 

/**

 * 统计在线用户数。前提是登录的时候限制一个用户只能够在系统中登录一次。 有了这个功能,管理员就可以管理在线用户,如果谁不服从管理,就可以从系统中踢出去。

 * TODO 将jsp放到WEB-INF后面,然后所有的URL必须通过struts的action调用。 使用拦截器Interceptor来实现权限的控制!

 * 或者通过web中的Filter来实现权限控制! 实现权限管理系统日志的记录!

 *

 * @author wangmingjie

 *

 */

public class OnLineUserManager {

 private static Log log = LogFactory.getLog(OnLineUserManager.class);

 private Vector<OnLineUser> users = null;

 

 

 private OnLineUserManager() {

  users = new Vector<OnLineUser>();//在构造函数中初始化

 }

 

 static class SingletonHolder {

  static OnLineUserManager instance = new OnLineUserManager();

 }

 

 /**

  * 单例模式。这样简单而且能够保证线程安全。

  *

  * @return

  */

 public static OnLineUserManager getInstance() {

  return SingletonHolder.instance;

 }

 

 /**

  * 获取到登录用户的数量。

  *

  * @return

  */

 public synchronized int getCount() {

  users.trimToSize();

  return users.capacity();

 }

 

 /**

  * 通过用户帐号判断该用户是否存在! 必须保证是线程安全的。

  *

  * @param userAccount

  * @return

  */

 public synchronized boolean existUser(String userAccount) {

  users.trimToSize();

  boolean existUser = false;

  for (int i = 0; i < users.capacity(); i++) {

   if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {

    existUser = true;

    break;

   }

  }

  return existUser;

 }

 

 /**

  * @param sessionid

  * @return

  */

 public synchronized boolean existSession(String sessionid) {

  users.trimToSize();

  boolean existUser = false;

  for (int i = 0; i < users.capacity(); i++) {

   if (sessionid.equals(((OnLineUser) users.get(i)).getSessionId())) {

    existUser = true;

    break;

   }

  }

  return existUser;

 }

 

 

 /**

  * 删除用户

  *

  * @param userAccount

  * @return

  */

 public synchronized boolean deleteUser(String userAccount) {

  users.trimToSize();

  if (existUser(userAccount)) {

   int currUserIndex = -1;

   for (int i = 0; i < users.capacity(); i++) {

    if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {

     currUserIndex = i;

     break;

    }

   }

   if (currUserIndex != -1) {

    users.remove(currUserIndex);

    users.trimToSize();

    log.debug("用户" + userAccount + "退出系统"

      + DateUtil.getCurrentDateTime());

    log.debug("在线用户数为:" + getCount());

    return true;

   }

  }

  return false;

 }

 

 /**

  * 根据用户帐号,获取在线用户信息

  * @param userAccount

  * @return

  */

 public synchronized OnLineUser getUser(String userAccount) {

  users.trimToSize();

  if (existUser(userAccount)) {

   int currUserIndex = -1;

   for (int i = 0; i < users.capacity(); i++) {

    if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {

     currUserIndex = i;

     break;

    }

   }

   if (currUserIndex != -1) {

    return  users.get(currUserIndex);

   }

  }

  return null;

 }

 

 /**

  * 获取到在线用户的信息。

  *

  * @return

  */

 public synchronized Vector<OnLineUser> getOnLineUser() {

  return users;

 }

 

 public synchronized void addUser(OnLineUser onLineUser) {

  users.trimToSize();

  if (!existUser(onLineUser.getUserAccount())) {

   users.add(onLineUser);

   log.debug(onLineUser.getUserAccount() + "/t登录到系统/t" + DateUtil.getCurrentDateTime());

   // 通过request才能够获取到用户的ip等信息

  } else {

   log.debug(onLineUser.getUserAccount() + "已经存在");

  }

  log.debug("在线用户数为:" + getCount());

 }

 

}

 ==================OnLineUser.java============================

view plaincopy to clipboardprint?
package com.work.qxgl.login;  
 
 
 
import java.io.Serializable;  
 
 
 
import javax.servlet.http.HttpSession;  
 
 
 
/** 
 
 * @author wangmingjie 
 
 * @date 2008-6-30下午04:56:37 
 
 */ 
 
public class OnLineUser implements Serializable {  
 
 
 
    /** 
 
     *  
 
     */ 
 
    private static final long serialVersionUID = 5461473880667036331L;  
 
      
 
    private String userId; //用户id  
 
    private String userAccount; //用户帐号  
 
    private String userName; //用户名称   
 
      
 
    private String loginTime; //登陆时间戳  
 
      
 
    private String sessionId; //session的ID  
 
    private String userIp ;//ip地址  
 
      
 
    private HttpSession session; //记住session对象,测试能否用来将人员踢出系统  
 
      
 
 
 
    public String getUserId() {  
 
        return userId;  
 
    }  
 
 
 
    public void setUserId(String userId) {  
 
        this.userId = userId;  
 
    }  
 
 
 
    public String getUserAccount() {  
 
        return userAccount;  
 
    }  
 
 
 
    public void setUserAccount(String userAccount) {  
 
        this.userAccount = userAccount;  
 
    }  
 
 
 
    public String getUserName() {  
 
        return userName;  
 
    }  
 
 
 
    public void setUserName(String userName) {  
 
        this.userName = userName;  
 
    }  
 
 
 
    public String getSessionId() {  
 
        return sessionId;  
 
    }  
 
 
 
    public void setSessionId(String sessionId) {  
 
        this.sessionId = sessionId;  
 
    }  
 
 
 
    public String getUserIp() {  
 
        return userIp;  
 
    }  
 
 
 
    public void setUserIp(String userIp) {  
 
        this.userIp = userIp;  
 
    }  
 
 
 
    public HttpSession getSession() {  
 
        return session;  
 
    }  
 
 
 
    public void setSession(HttpSession session) {  
 
        this.session = session;  
 
    }  
 
 
 
    public String getLoginTime() {  
 
        return loginTime;  
 
    }  
 
 
 
    public void setLoginTime(String loginTime) {  
 
        this.loginTime = loginTime;  
 
    }  
 
    public String toString(){  
 
        return  "OnLineUser{userId="+userId+",userAccount="+userAccount  
 
        +",userName"+userName+",loginTime="+loginTime+",userIp="+userIp+",sessionId="+sessionId+"}";  
 
    }  
 
      
 
    //===============下面的数据只有在系统登陆日期中记录==================================  
 
//  private String logoutTime;//退出时间戳;  
 
//  private String logoutType;//退出方式 “session超时退出”;“1主动退出”  
 
//  private String lastAccessedTime;// 最后访问时间  
 
 
 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wmj2003/archive/2008/07/01/2601802.aspx

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值