热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

JavaWeb实现同一帐号同一时间只能一个地点登陆(类似QQ登录的功能)

最近做了企业项目,其中有这样的需求要求同一帐号同一时间只能一个地点登陆类似QQ登录的功能。下面小编通过本文给大家分享实现思路,感兴趣的朋友参考下吧

JavaWeb实现同一帐号同一时间只能一个地点登陆(类似QQ登录的功能)的实现思路如下所示:

一、该功能有什么作用

大家想想吧。反正总会有这样的需求的。这年头什么需求不会有。。呵呵。有时候也不一定是需求,很有可能为了安全也会这么做。例如考试系统,在线聊天系统,很有必要做成这样的吧。

二、实现过程

a.问题分析

    在系统中,我们一般都是把登录信息绑定到session中,看来从这入手是可能找到解决办法。说白了,也就是当用户登录时,判断一下这个用户有没有登录,如果登录了,就把以前的那个session清除掉就OK了。。看似很简单是不?其实你细想你会发现有以下问题:如何得到之前这个用户有没有登录过,也就是如何访问到所有登录的session信息呢?

b.具体实现

   大家知道,在j2ee api好像是没有具体的方法直接得到所有session信息的。但是我们可以通过配制监听器,监控所有的session创建和消毁过程,以及可以监控session中的属性的创建,删除和替换过程。

其实我们只要做以下处理即可:

在保存用户登录信息到session时,对应的也就是session一个属性的创建过程(attributeAdded),可以把当前这个session记录到一个ArrayList中。

其实在保存到list中时你要首先遍历一下这个list中有没有已经存在该用户的登录信息。如果存在就消毁掉这个list中存在的session信息,并且从list中移除,不存在就把该session信息放到list中。

在session的登录信息消毁时,直接把该sesseion从list中移除掉。

还有就是当用户登录后没有退出直接登录这个时候是一个session属性的替换过程。也要做处理判断新的用户是否已经在除了当前session的其它session中是否存在。存在则删除。

具体代码如下:

package com.weirhp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class RecordSessionListener implements HttpSessionAttributeListener,
HttpSessionListener {
private static List sessions;
public static String loginFlag = "loginUser";
static {
if (sessiOns== null) {
sessiOns= Collections.synchronizedList(new ArrayList());
}
}
public void attributeAdded(HttpSessionBindingEvent e) {
HttpSession session = e.getSession();
System.out.println("-------------*start added*-----------------------");
String attrName = e.getName();
// 登录
if (attrName.equals(loginFlag)) {
User nowUser = (User) e.getValue();
User sUser = (User)session.getAttribute(loginFlag);
// 遍历所有session
for (int i = sessions.size()-1; i >= 0; i--) {
SessionAndUser tem = sessions.get(i);
if (tem.getUserID().equals(nowUser.getName())) {
tem.getSession().invalidate();//自动调用remove
break;
}
}
SessionAndUser sau = new SessionAndUser();
sau.setUserID(nowUser.getName());
sau.setSession(session);
sau.setSid(session.getId());
sessions.add(sau);
}
}
public void attributeRemoved(HttpSessionBindingEvent e) {
HttpSession session = e.getSession();
System.out.println("-------------*start Removed*-----------------------");
String attrName = e.getName();
// 登录
if (attrName.equals(loginFlag)) {
User nowUser = (User) e.getValue();
// 遍历所有session
for (int i = sessions.size()-1; i >= 0; i--) {
SessionAndUser tem = sessions.get(i);
if (tem.getUserID().equals(nowUser.getName())) {
sessions.remove(i);
break;
}
}
}
}
public void attributeReplaced(HttpSessionBindingEvent e) {
HttpSession session = e.getSession();
System.out.println("-------------*start replace*-----------------------");
String attrName = e.getName();
int delS=-1;
// 登录
if (attrName.equals(loginFlag)) {
// User nowUser = (User) e.getValue();//old value
User nowUser = (User)session.getAttribute(loginFlag);//当前session中的user
// 遍历所有session
for (int i = sessions.size()-1; i >= 0; i--) {
SessionAndUser tem = sessions.get(i);
if (tem.getUserID().equals(nowUser.getName())&&!tem.getSid().equals(session.getId())) {
System.out.println("Remove:invalidate 1!");
delS=i;
}else if(tem.getSid().equals(session.getId())){
tem.setUserID(nowUser.getName());
}
}
if (delS!=-1) {
sessions.get(delS).getSession().invalidate();//失效时自动调用了remove方法。也就会把它从sessions中移除了
}
}
}
public void sessionCreated(HttpSessionEvent e) {
}
public void sessionDestroyed(HttpSessionEvent e) {
}
}

在web.xml中的配制


recordSession
com.weirhp.RecordSessionListener

三、可能存在的问题

整个个程序可能有的点没有想到。可能存在一些bug,用于具体项目需谨慎,欢迎大家拍砖,也希望给点建议。我再改进。

四、后来的一些思考

  如果两台机器使用同一帐号在同一时刻登录系统,是不是两个帐号都可以登录成功呢。。(还有就是这个session List很大时,在遍历的时间段中两台机器使用同一帐号在同一时刻登录系统也可能会成功登录的)。很是纠结。。应该怎么控制呢?

(解决办法:经测试Listener在系统中是一个单例,在它的方法上加上synchronize关键字就可以保证list的线程安全了。)

以上所述是小编给大家介绍的JavaWeb实现同一帐号同一时间只能一个地点登陆(类似QQ登录的功能),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


推荐阅读
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 信息安全等级保护是指对国家秘密信息、法人和其他组织及公民的专有信息以及公开信息和存储、传输、处理这些信息的信息系统分等级实行安全保护,对信息系统中使用的信息安全产品实 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 学习笔记(34):第三阶段4.2.6:SpringCloud Config配置中心的应用与原理第三阶段4.2.6SpringCloud Config配置中心的应用与原理
    立即学习:https:edu.csdn.netcourseplay29983432482?utm_sourceblogtoedu配置中心得核心逻辑springcloudconfi ... [详细]
author-avatar
朝朝宝宝
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有