防止用户重复登录解决方案

前一段时间碰到一个需求:一个账号只能登录一次,不能重复登录问题。

在网上找了下,大概有两种解决方案:
1、通过数据库状态位判断该用户是否已经登录。
2、利用session监听器监听每一个登录用户的登录情况。

个人想了下,第一种解决方案很简单,但需要考虑用户非正常退出的情况,如直接关闭浏览器等等,可用性较低。

接下来,主要介绍第二种方案的具体实现:

A.用户登录后,先去数据库查询该登录名是否存在、是否锁定,在登录名存在且非锁定的情况下,从application内置作用域对象中取出所有的登录信息,查看该登录名是否已经登录,如果登录了,就友好提示下;反之表示可以登录,将该登录信息保存在application中。


02 //所有的登录信息
03 Map loginUserMap = (Map) super.getApplicationAttr(Constant.LOGIN_USER_MAP);
04 boolean isExist = false;
05 String sessionId = super.getSessionId(false);
06  
07 if(loginUserMap==null){
08 loginUserMap = new HashMap();
09 }
10  
11 for (String username : loginUserMap.keySet()) {
12 //判断是否已经保存该登录用户的信息,是否为同一个用户进行重复登录
13 if(!username.equals(user.getFuUserName()) || loginUserMap.containsValue(sessionId)){
14 continue;
15 }
16 isExist = true;
17 break;
18 }
19  
20 if(isExist){
21 //该用户已登录
22 //
23 }else {
24 //该用户没有登录
25 loginUserMap.put(result.getFuUserName(), sessionId);
26 //
27 }
28 //


B.登录考虑完之后,来考虑考虑退出。
用户正常退出时,我们需要将该用户的登录信息从session中移除。我们可以写一个Session监听器,监听sessioon销毁的时候,我们将登录的用户注销掉,也就是从application中移除。表示该用户已经下线了。 

主要代码如下:

//
02 public void sessionDestroyed(HttpSessionEvent event) {  
03         //      
04         //在session销毁的时候 把loginUserMap中保存的键值对清除   
05         User user = (User)event.getSession().getAttribute("loginUser");  
06         if(user!=null){  
07                 Map loginUserMap = (Map)event.getSession().getServletContext().getAttribute("loginUserMap");  
08                 loginUserMap.remove(user.getFuUserName());  
09 event.getSession().getServletContext().setAttribute("loginUserMap",loginUserMap);
10         }
11         //
12 }
13 //
另外,还有一个问题,如果说登录的用户突然关闭了浏览器而没有点击退出按钮。那么可以利用beforeunload 事件,在浏览器刷新或者关闭的时候触发。

//在刷新或关闭时调用的事件
02  
03 $(window).bind('beforeunload',function(){
04    $.ajax({
05        url:"${ctx}/system/user/user!logout.action",
06        type:"post",
07        success:function(){
08            alert("您已退出登录");
09        }
10    });
11 });
这样基本就实现了需求了。

你可能感兴趣的:(java相关)