如何实现单一用户单一机子登录

来源:互联网 发布:牛在印度的地位知乎 编辑:程序博客网 时间:2024/04/30 01:47

 1、要解决同一台电脑上只允许有一个用户登录系统,只有一个办法。监视每一个连接的来源,如果发现有一个新的连接与某个已经存在的连接来自同一台电脑,则终止其中的一个(当然,也可以提醒用户,让他自己决定终止哪一个)。

    2、要禁止一个用户账号同时在不同的客户端登录,只有监视每一个连接的用户账号,如果发现一个新连接的用户账号跟某个已经存在的连接的用户账号相同,则自动将前一个终止(同样,也可以让用户自己决定终止哪一个)。

    确定了基本思路以后,就要找具体办法了。我最初的想法是在数据库建立一张表,存放已登录用户的用户名、物理地址、Session id等信息。当用户登录时,与这张表里面的数据进行匹配,如果发现物理地址与表中的某条记录相同,则表示是同一台客户端上有多个用户再登录,如果发现正在登录的用户的用户名与表中已有记录相同而主机名不同,则表示是一个账号同时在不同的客户端使用。

    相信很多一开始遇到这个问题的人都会考虑这种解决办法。但是这种办法有很多问题,最主要的问题有两个:第一是效率,每一次都要从数据库里面取数据进行匹配。第二是用户退出时需要删除表中的记录,而当用户非正常退出时,很难及时监测(后来发现其实有办法监测)。

    后来在网上的某个帖子里面看到一位大侠提到用监听器,只是那位大侠说的太含糊,照他说的办法根本无法解决。虽然无法解决,但是提供了一个思路。于是我找了一本书,仔细看了其中关于监听器的部分。解决办法就在其中了!!!

    监听器的详细介绍见我的下一篇博文,这里先把解决办法告诉大家:

监听器可以监听Session及其所包含的属性,即Attribute。

所以我们要做的就是:

1、建立一个监听器,实现HttpSessionAttributeListener接口,监听每一个Attribute的增加、编辑、删除事件。监听器中还要建立一个map,将所有的session放入这个map中。

2、在用户登录时将用户名、物理地址、Session id存到Session中去(可以建立一个用户登录地址数据传输对象,我建立了一个UserSessionAdd类,里面包含username,macAdd,sessionId三个属性,用户登录时将这个数据对象初始化,并存入到session中)。

3、每个新会话开启时,在监听器中对Session包含的属性进行判断,如果新增的属性与map中已有session的用户登录地址数据相同,则表示新会话与我们要做的两个限制相冲突。将与之冲突的会话提取出来,销毁掉!

这么说,还是不够清楚,下面看代码:

[html] view plaincopyprint?
  1. Web.xml文件:  
  2.   
  3. <listener>  
  4.   
  5.        <listener-class>监听器类的路径,如:com.web.MyListener</ listener-class >  
  6.   
  7. </listener>  


 

用户登录地址数据传输对象:

[java] view plaincopyprint?
  1. publicclass UserSessionAdd {  
  2.   
  3.   
  4. private Stringadd;  
  5.   
  6.   
  7. private Stringsessid;  
  8.   
  9.   
  10. private String username  
  11.   
  12. public String getUsername(){  
  13.   
  14. return username  
  15.   
  16. }  
  17.   
  18. Public void setUsername(String username){  
  19.   
  20.        this.username=username;  
  21.   
  22.     }  
  23.   
  24. public String getIp() {  
  25.   
  26. returnadd;  
  27.   
  28. }  
  29.   
  30. publicvoid setAdd(String add) {  
  31.   
  32. this.add = add;  
  33.   
  34. }  
  35.   
  36. public String getSessid() {  
  37.   
  38. returnsessid;  
  39.   
  40. }  
  41.   
  42. publicvoid setSessid(String sessid) {  
  43.   
  44. this.sessid = sessid;  
  45.   
  46. }  
  47.   
  48.   
  49. }  


 

用户登录的代码:

[java] view plaincopyprint?
  1. ···  
  2.   
  3. String userHost = request.getRemoteHost();  
  4.   
  5. String sessionId = request.getSession().getId();  
  6.   
  7. UserSessionAdd usa = new UserSessionAdd();  
  8.   
  9. usa.setUsername(username);  
  10.   
  11. usa.setSessid(sessionId);  
  12.   
  13. usa.setAdd(userHost);  
  14.   
  15. request.getSession().setAttribute(“usa”,usa);  


 

监听器代码:

[java] view plaincopyprint?
  1. publicclass MyListenerimplementsHttpSessionAttributeListener{  
  2.   
  3.   
  4. Map<String, HttpSession> map =new HashMap<String, HttpSession>();  
  5.   
  6. publicvoidattributeAdded(HttpSessionBindingEvent event) {  
  7.   
  8. String name = event.getName();  
  9.   
  10. if(name.equals("usa")){  
  11.   
  12. UserSessionAdd usa = (UserSessionAdd)event.getValue();  
  13.   
  14. if(map.get(usa.getAdd())!=null){  
  15.   
  16. HttpSession sess = map.get(usa.getAdd());  
  17.   
  18. UserSessionAdd usa1 = (UserSessionAdd)sess.getAttribute("usa");  
  19.   
  20. sess.removeAttribute("usa");  
  21.   
  22. sess.invalidate();  
  23.   
  24. }  
  25.   
  26. map.put(usa.getAdd(), event.getSession());  
  27.   
  28. }  
  29.   
  30. }  
  31.   
  32.   
  33. publicvoidattributeRemoved(HttpSessionBindingEvent event) {  
  34.   
  35. String name = event.getName();  
  36.   
  37. if(name.equals("usa")){  
  38.   
  39. UserSessionAdd usa = (UserSessionAdd)event.getValue();  
  40.   
  41. map.remove(usa.getAdd());  
  42.   
  43. }  
  44.   
  45. }  
  46.   
  47.   
  48. publicvoidattributeReplaced(HttpSessionBindingEvent event) {  
  49.   
  50. // TODO Auto-generated method stub  
  51.   
  52. ````  
  53.   
  54. }  
  55.   
  56. }  
  57.   
  58.    
原创粉丝点击