来公司两个月了, 进组也有1个多月,这是我的第一份工作, 也是第一个项目, 所以决定留下文字记录还是好些,由于入组相对晚,我负责的也相对独立些 -- 系统管理, 首先要做的就是登录, 既然是应用系统肯定不允许同一账号异地重复登录, 就这个问题我查了很多资料, 想做的完美些, 可谓是听取了百家之言。

我目前所知的方法可分为两种, 一是数据库来记录用户在线情况, 在登录把该用户数据库的标识字段赋值, 退出时让该字段复位. 二是通过全局的内存对象来记录用户情况,  以该用户的登录名如user做为key存入application中或是定义的一个全局的hashmap中, 退出删除全局对象中该user对应的信息, 据说还可用Cache全局对象,但相比.NET,java实现Cache不是太容易. 而这些对于用户的登录事件都能实时的做出处理, 但用户的退出显然多种多样, 乖乖点击注销可能性很小, 还得考虑断电,掉线等情况, 所以用户的退出事件程序是捕获不了的, 这是由session的机制决定的, 所以用户退出时,服务器想做到实时刷新是几乎是不可能的(除非用户点注销), 很多在线统计人数都不是实时的, 一般都是通过添加session监听器, 然后设置session失效时间, 时间到了则调用监听器的对应方法释放相关的数据, 如删除application中该用户的信息. 所以很可能会出现的一种情况是用户刚刚登录上系统, 然后掉线或其它原因, 然后该用户重新登录, 但系统提示该用户已经登录, 无法再次登录. 只能等到原来的session失效, 遇到这种情况想必是很郁闷. 这种情况是无法解决的, 就其根本还是因为用户的退出是无法确定的, 服务器无法区分用户的真在线还是假在线. 既然这样可以像QQ一样以顶号的方式来处理, 就是用户登录时判断application中是否有该用户信息存在, 有则替换, 无则写入, 这样同一个账号的话, 先登录的会被后登录的踢出, 这就无需理会先登录的用户是真在线还是假在线, 达到了实时的效果。不过我们项目不让这么用, 目办法只能用session监听了。Servlet里面一共有八个监听, 其中有四个是session的监听接口与之关联的两个session事件,
这四个接口分别是:
HttpSessionAttributeListener and HttpSessionBindingEvent
HttpSessionBindingListener and HttpSessionBindingEvent
HttpSessionListener and HttpSessionEvent
HttpSessionActivationListener and HttpSessionEvent

HttpSessionAttributeListener: 用来监听session中的属性添加, 替换和删除, 只需创建一个类来实现HttpSessionAttributeListener接口, 然后在web.xml配个listener属性,其中litener-class是这个类的路径. 该类会实现HttpSessionAttributeListener的三个方法. 分别对应session中的属性添加, 替换和删除. 该类无需我们实例化使用, 因为servlet容器会创建该类的一个实例, 并是单例. 所以访问该系统的所有用户对session属性的操作都会被HttpSessionAttributeListener监听到. HttpSessionBindingEvent事件的触发对象是任何object的实例, 因为session的setAttribute方法中可以存放任何object的实例。HttpSessionBindingListener: 创建实现HttpSessionBindingListener接口的类, 不需在web.xml中配置, 该类会实现HttpSessionBindingListener的两个方法valueBound()和valueUnbound(), 该类需要实例化使用, 将该类实例对象放入session后会马上触发valueBound()方法, 从session中remove掉该实例时或session超时会马上触发valueUnbound(), 很显然每个servlet都会创建一个该类的对象,所以多用户并发调用时它们都是相互独立的, 而且可以创建多个实现HttpSessionBindingListener接口的类, 效果依然一样。
HttpSessionBindingEvent事件的触发对象是该类的实例本身(有点绕口),

举例
public class SessionListener implements HttpSessionBindingListener....
SessionListener sessionListener = new SessionListener();

//下面这句即是触发HttpSessionBindingEvent事件, 而触发对象正是sessionListener, 监听器的实例本身
request.getSession().setAttribute(request.getSession().getId(), sessionListener);

HttpSessionListener:监听session的创建和释放, 需在web.xml中配置, 重写sessionCreated()和sessionDestroyed()方法, 它同样是容器创建的单列对象, 可以监听所有用户的session创建, 适合来做统计, 得注意的一点是, 在浏览器访问服务器时, session的会话就创建了, 而session释放后才会调用sessionDestroyed()方法, 所以不能在sessionDestroyed()内做session清理工作, 因为已经无法获得session了。

HttpSessionActivationListener:当session在分布式环境中跨JVM时,实现该接口的对象得到通知, 需实行的方法sessionDidActivate()和sessionWillPassivate(),  Activate与Passivate是用于置换对象的动作,当session对象为了资源利用或负载平衡等原因而必须暂时储存至硬盘或其它储存器时(透过对象序列化),所作的动作称之为Passivate,而硬盘或储存器上的session对象重新加载JVM时所采的动作称之为Activate,所以容易理解的,sessionDidActivate()与 sessionWillPassivate()分别于Activeate后与将Passivate前呼叫。

这四个都与session有关,但能做到验证登录的只有HttpSessionBindingListener and HttpSessionListener,无疑使用前者更合适些。

转载于:https://www.cnblogs.com/carekee/articles/1745099.html

[Java] - 项目中的防止同用户异地登录问题相关推荐

  1. 项目中的防止同用户异地登录问题

    来公司两个月了, 进组也有1个多月,这是我的第一份工作, 也是第一个项目, 所以决定留下文字记录还是好些,由 于入组相对晚,我负责的也相对独立些 -- 系统管理, 首先要做的就是登录, 既然是应用系统 ...

  2. 为什么我会在2012年的新企业Java项目中使用Java EE而不是Spring

    这个问题经常出现. 我的新项目也在2011年11月发布. 在这个新的Enterprise Java项目中,我将使用Java EE(JEE)代替Spring框架. 我知道:关于此主题的文章,博客和论坛讨 ...

  3. 如何在Java项目中查找未使用/无效的代码

    本文翻译自:How to find unused/dead code in java projects What tools do you use to find unused/dead code i ...

  4. Java项目中利用Freemarker模板引擎导出--生成Word文档

    应邀写的一篇文章:Java项目中利用Freemarker模板引擎导出--生成Word文档 资源下载:https://download.csdn.net/download/weixin_41367523 ...

  5. 设计银行项目中的注册银行用户基本信息的类,包括账户卡号、姓名、身份证号、联系电话、家庭住址。

    什么是类和对象? 类是模子,确定对象会拥有的特征(属性)和行为(方法),类的特点:类是对象的类型,具有相同属性和方法的一组对象的集合.对象是类的实例,什么是对象的属性?属性是对象拥有的各种特征:每个对 ...

  6. java项目中rides的使用

    项目开发中一些特定的数据我们不一定要关系型数据库来存储,使用非关系型数据库反而更方便读取数据,效率高,这里介绍一下在java中rides的使用 1. 导入rides所需要的相关依赖jar包(在pom文 ...

  7. 关于Java项目中,word和Excel类型文件的预览功能实现

    关于Java项目中,word和Excel类型文件的预览功能实现 背景 Aspose说明 Aspose.Words Aspose.Cells pom依赖引入 引入license.xml(授权文件) 创建 ...

  8. Mac笔记本中是用Idea开发工具在Java项目中调用python脚本遇到的环境变量问题解决...

    问题描述: mac笔记本本身会自带几个python版本,比如python2.7版本,我没有改动mac默认的python版本,只是安装了python3.7版本. 使用Pycharm开发Python项目没 ...

  9. java聊天室小程序论文_在Java项目中利用continue与break制作一个聊天室小程序

    在Java项目中利用continue与break制作一个聊天室小程序 发布时间:2020-12-08 16:03:27 来源:亿速云 阅读:98 作者:Leah 在Java项目中利用continue与 ...

  10. java项目怎么定义异常_在Java项目中如何实现自定义异常

    在Java项目中如何实现自定义异常 发布时间:2020-11-11 15:41:32 来源:亿速云 阅读:77 作者:Leah 这篇文章将为大家详细讲解有关在Java项目中如何实现自定义异常,文章内容 ...

最新文章

  1. 关于ASP.NET Web 部件连接的引入
  2. OCRNet: 目标区域上下文信息的特征表达 | ECCV 2020
  3. 业界丨2018,人工智能革命走向风口浪尖
  4. 关于 SoftEther ***
  5. 接口文档-swagger-bootstrap
  6. mysql集群之MMM简单搭建
  7. ecshop后台实现用ajax动态修改/更新用户评论的时间
  8. 虚拟机随服务器启动,VMware Server中虚拟机随宿主机自动启动
  9. [Spark]Could not locate executable null\bin\winutils.exe in the Hadoop binaries
  10. 42张PPT揭秘字节跳动人力资源体系(推荐收藏)
  11. 【C语言】利用递归解决猴子吃桃问题
  12. python共享内存mmap_python - IPC在单独的Docker容器中的Python脚本之间共享内存 - 堆栈内存溢出...
  13. 1394接口_电视机的音频输出接口
  14. 硕士论文中期汇报ppt_做一场合格的中期汇报
  15. 传奇外网架设教程带图文解说——Gom引擎
  16. 搭载TI最强芯片CC2652RB,昇润科技突破技术壁垒给你的电子产品“另一种心跳”
  17. Python3官方手册中文在线版
  18. PAT Basic 1031
  19. 文件监控(二) 代码
  20. LikeLib:区块链+云计算的结合技术现在成熟了吗?

热门文章

  1. 摇滚吧HTML5!有声前端交互!(Hello, Jsonic!)
  2. STP是一个需要众力协作的协议
  3. [WebApi] 捣鼓一个资源管理器--数据库辅助服务器文件访问
  4. 对vue.config.js中的代理服务器的理解
  5. php生成图片不显示,php绘图不显示图片怎么办
  6. 安卓期末作品小项目_学在澎雅 | 探索红叶李,闯关我最棒——杭州市澎雅小学二年级期末游园活动...
  7. windows 不安装jdk 运行 jar_详解Windows系统安装运行Mongodb服务(推荐)
  8. hsql mybatis 表不存在_Mybatis-plus 查询数据库表时抛异常提示数据库表不存在
  9. xcode动态改变窗口大小_[SwiftUI 100天] 在 SwiftUI 中动态过滤 @FetchRequest
  10. java 809 128 题_java编程题809*??=800*??+9*??+1