前一段时间碰到一个需求:一个账号只能登录一次,不能重复登录问题。
在网上找了下,大概有两种解决方案:
1、通过数据库状态位判断该用户是否已经登录。
2、利用session监听器监听每一个登录用户的登录情况。
个人想了下,第一种解决方案很简单,但需要考虑用户非正常退出的情况,如直接关闭浏览器等等,可用性较低。
接下来,主要介绍第二种方案的具体实现:
另外,还有一个问题,如果说登录的用户突然关闭了浏览器而没有点击退出按钮。那么可以利用beforeunload 事件,在浏览器刷新或者关闭的时候触发。
这样基本就实现了需求了。
在网上找了下,大概有两种解决方案:
1、通过数据库状态位判断该用户是否已经登录。
2、利用session监听器监听每一个登录用户的登录情况。
个人想了下,第一种解决方案很简单,但需要考虑用户非正常退出的情况,如直接关闭浏览器等等,可用性较低。
接下来,主要介绍第二种方案的具体实现:
A.用户登录后,先去数据库查询该登录名是否存在、是否锁定,在登录名存在且非锁定的情况下,从application内置作用域对象中取出所有的登录信息,查看该登录名是否已经登录,如果登录了,就友好提示下;反之表示可以登录,将该登录信息保存在application中。
02 | //所有的登录信息 |
03 | Map<String, String> loginUserMap = (Map<String, String>) 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<String, String>(); |
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<String, String> loginUserMap = (Map<String, String>)event.getSession().getServletContext().getAttribute( "loginUserMap" ); |
08 | loginUserMap.remove(user.getFuUserName()); |
09 | event.getSession().getServletContext().setAttribute( "loginUserMap" ,loginUserMap); |
10 | } |
11 | // |
12 | } |
13 | // |