热门标签 | 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登录的功能),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


推荐阅读
  • 高效重装Windows 10系统指南
    如何快速地为您的电脑重装Windows 10系统?本文将详细介绍从下载系统镜像到安装完成的每一步操作。 ... [详细]
  • SSM框架下的在线教育平台源代码与文档
    本文介绍了基于SSM(Spring, Spring MVC, MyBatis)框架开发的教务网络管理系统。该系统旨在有效管理学生各学年的成绩,支持快速查询学生成绩和班级信息。系统具备完善的需求分析、设计和实现方案,确保数据的安全性和系统的易用性。 ... [详细]
  • 在React中使用setState时遇到错误,本文将详细分析错误原因并提供解决方案。 ... [详细]
  • 本文探讨了 TypeScript 中泛型的重要性和应用场景,通过多个实例详细解析了泛型如何提升代码的复用性和类型安全性。 ... [详细]
  • 解决MAC远程桌面连接证书无效问题
    本文介绍如何解决在使用MAC远程桌面连接时遇到的“证书或相关链无效”错误。通过详细步骤和专业建议,帮助用户顺利连接远程桌面。 ... [详细]
  • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
  • 阿里云服务器搭建详解——Ubuntu
    由于自己电脑配置跟不上,双系统一开,整个电脑就会变得非常卡顿,所以决定在阿里云买一个云服务器。听朋友说,学生买的话是非常便宜 ... [详细]
  • 小程序的授权和登陆
    小程序的授权和登陆 ... [详细]
  • 本文介绍了 Go 语言中的高性能、可扩展、轻量级 Web 框架 Echo。Echo 框架简单易用,仅需几行代码即可启动一个高性能 HTTP 服务。 ... [详细]
  • PHP 5.5.31 和 PHP 5.6.17 安全更新发布
    PHP 5.5.31 和 PHP 5.6.17 已正式发布,主要包含多个安全修复。强烈建议所有用户尽快升级至最新版本以确保系统安全。 ... [详细]
  • Cookie学习小结
    Cookie学习小结 ... [详细]
  • 本文将深入探讨 iOS 中的 Grand Central Dispatch (GCD),并介绍如何利用 GCD 进行高效多线程编程。如果你对线程的基本概念还不熟悉,建议先阅读相关基础资料。 ... [详细]
  • 一个初秋的雨夜,我独自漫步在校园的小道上,心中突然涌起对理想爱情的憧憬。这篇文章将分享我对理想伴侣的期望,以及与他共度美好时光的愿景。 ... [详细]
  • Spring Data JdbcTemplate 入门指南
    本文将介绍如何使用 Spring JdbcTemplate 进行数据库操作,包括查询和插入数据。我们将通过一个学生表的示例来演示具体步骤。 ... [详细]
  • 本文详细解析了ASP.NET 2.0中的Callback机制,不仅介绍了基本的使用方法,还深入探讨了其背后的实现原理。通过对比Atlas框架,帮助读者更好地理解和应用这一机制。 ... [详细]
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社区 版权所有