java web开发一个帐号同一时间唯其如此一个人登录

java web开发一个帐号同一时间只能一个人登录

可采用如下解决方案:

1 .当用户第一次登录时,把用户添加到一个ArrayList中,再次登录时查看ArrayList中有没有该用户,如果ArrayList中已经存在该用户,则阻止其登录。(说明,为保证该操作在每一次登录时都能执行,最好写在一个filter或listener中),代码参考如下:

Java代码 java web开发一个帐号同一时间唯其如此一个人登录 java web开发一个帐号同一时间唯其如此一个人登录java web开发一个帐号同一时间唯其如此一个人登录
  1. public static List loginInfoList=Collections.synchronizedList(new ArrayList()); //保存所有登录帐户(要作为一个静态成员变量保存)    
  2.   
  3.   
  4. boolean accountLogined=false// 账户是否已经登录   
  5.         if(HomeController.loginInfoList.isEmpty()){   
  6.             HomeController.loginInfoList.add(loginInfo); // loginInfo:当前登录帐户   
  7.         }   
  8.         }else{    
  9.             for(int i=0;i<HomeController.loginInfoList.size();i++){   
  10.             LoginInfo tempInfo=HomeController.loginInfoList.get(i);    
  11.             if(tempInfo.getUserId().equals(MisUtils.getSessionUser(request).getId())){   
  12.                 accountLogined=true;// 当前账户已在使用   
  13.                 break;    
  14.                 }    
  15.             }    
  16.         if(!accountLogined){ // 列表中不存在该账户   
  17.             HomeController.loginInfoList.add(loginInfo);    
  18.             }    
  19.         }    
  20.         if(accountLogined){ throw new MisException("当前账户正在使用,不能重复登录");    
  21.         }  
public static List loginInfoList=Collections.synchronizedList(new ArrayList()); //保存所有登录帐户(要作为一个静态成员变量保存) 


boolean accountLogined=false; // 账户是否已经登录
		if(HomeController.loginInfoList.isEmpty()){
			HomeController.loginInfoList.add(loginInfo); // loginInfo:当前登录帐户
		}
		}else{ 
			for(int i=0;i<HomeController.loginInfoList.size();i++){
			LoginInfo tempInfo=HomeController.loginInfoList.get(i); 
			if(tempInfo.getUserId().equals(MisUtils.getSessionUser(request).getId())){
				accountLogined=true;// 当前账户已在使用
				break; 
				} 
			} 
		if(!accountLogined){ // 列表中不存在该账户
			HomeController.loginInfoList.add(loginInfo); 
			} 
		} 
		if(accountLogined){ throw new MisException("当前账户正在使用,不能重复登录"); 
		}

 

 

 
2、当用户退出时,需要从该ArrayList中删除该用户,这又分为三种情况

① 使用注销按钮正常退出
② 点击浏览器关闭按钮或者用Alt+F4退出,可以用javascript捕捉该页面关闭事件,
执行一段java方法删除ArrayList中的用户
③ 非正常退出,比如客户端系统崩溃或突然死机,可以采用隔一段时间session没活动就删除该session所对应的用户来解决,这样用户需要等待一段时间之后就可以正常登录。

①③ 可采用相同的核心代码,只不过③须放在一个sessionListener中,参考代码如下:

 

 

Java代码 java web开发一个帐号同一时间唯其如此一个人登录 java web开发一个帐号同一时间唯其如此一个人登录java web开发一个帐号同一时间唯其如此一个人登录
  1. Iterator<LoginInfo> it=HomeController.loginInfoList.iterator();   
  2.     while(it.hasNext()){    
  3.         LoginInfo tempInfo=it.next();    
  4.         if(MisUtils.getSessionUser(req).getId().equals(tempInfo.getUserId())){ //MisUtils.getSessionUser(req).getId()为当前登录用户的id    
  5.             it.remove();    
  6.         }    
  7.     }  
Iterator<LoginInfo> it=HomeController.loginInfoList.iterator();
	while(it.hasNext()){ 
		LoginInfo tempInfo=it.next(); 
		if(MisUtils.getSessionUser(req).getId().equals(tempInfo.getUserId())){ //MisUtils.getSessionUser(req).getId()为当前登录用户的id 
			it.remove(); 
		} 
	}

 

 

 说明:对于在遍历list的同时进行删除操作,最好通过Iterator,否则如果一次要删除多个元素时,通过loginInfoList.remove(i)可能出现与期望值不一样的结果。

对于② 浏览器关闭时,可在前台使用 window.onbeforeunload事件进行捕捉,并使用ajax从列表中删除用户,参考如下:

 

Js代码 java web开发一个帐号同一时间唯其如此一个人登录 java web开发一个帐号同一时间唯其如此一个人登录java web开发一个帐号同一时间唯其如此一个人登录
  1. //窗口关闭时触发    
  2. window.onbeforeunload=function(){    
  3.          if(event.clientX>document.body.clientWidth && event.clientY<0||event.altKey||window.event.ctrlKey){   
  4.            $.get("destroyCurrentUser.htm"); //jquery中简单的ajax    
  5.            }    
  6. }   
//窗口关闭时触发 
window.onbeforeunload=function(){ 
         if(event.clientX>document.body.clientWidth && event.clientY<0||event.altKey||window.event.ctrlKey){
           $.get("destroyCurrentUser.htm"); //jquery中简单的ajax 
           } 
} 

 

 其中destroyCurrentUser.htm中的核心代码与前面类似。

当然这种解决方案还存在许多问题,比如 客户端死机情况下用户并不会从列表中删除,致使下次再无法登录;当使用多标签浏览器时,关闭浏览器,window.onbeforeunload事件通常不会触发,导致登录用户也不会从列表中删除。所以最好是建一个可以无限次登录的super账户,并能查看登录用户列表及强制注销登录用户。

 

转自:http://sfc235300.iteye.com/blog/847306