- 浏览: 334929 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (59)
- wicket (1)
- java (24)
- js (27)
- xml (3)
- Android (1)
- 服务器 (7)
- 数据库 (7)
- spring (1)
- hibernate (1)
- ssh (6)
- web (25)
- oracle (1)
- 函数 (2)
- mysql (1)
- 手机 (6)
- javascript (21)
- session (3)
- cookie (4)
- struts (1)
- ngnix (1)
- 软件使用 (2)
- linux (1)
- vi (1)
- 前端 (6)
- javascrip (2)
- html (3)
- js css (2)
- 正则 (1)
- ajax (1)
- toast (1)
- 消息提示 (1)
- 确认弹窗 (1)
- springmvc (1)
- 倒计时 (1)
最新评论
-
wenm168:
美观的图片上传前预览效果:http://www.anyrt.c ...
JavaScript 图片的上传前预览(兼容所有浏览器) -
口弦1992:
我的ie9并没有图片预览出来啊。
JavaScript 图片的上传前预览(兼容所有浏览器) -
axie1234567:
分享的东西很有用。
java web中实现同一帐号同一时间只能一个地点登陆(类似QQ登录的功能) -
wyl4728:
32个赞
mysql函数大全 -
yu_long:
seeker.getCountry(ip);
解析出来的 ...
根据IP地址获取所在地
在java web中如何实现像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<SessionAndUser> sessions;
public static String loginFlag = "loginUser";
static {
if (sessions == null) {
sessions = Collections.synchronizedList(new ArrayList<SessionAndUser>());
}
}
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中的配制
1 <listener>
2 <display-name>recordSession</display-name>
3 <listener-class>com.weirhp.RecordSessionListener</listener-class>
4 </listener>
三、具体代码测试
四、可能存在的问题
整个个程序可能有的点没有想到。可能存在一些bug,用于具体项目需谨慎,欢迎大家拍砖,也希望给点建议。我再改进。
五、后来的一些思考
如果两台机器使用同一帐号在同一时刻登录系统,是不是两个帐号都可以登录成功呢。。(还有就是这个session List很大时,在遍历的时间段中两台机器使用同一帐号在同一时刻登录系统也可能会成功登录的)。很是纠结。。应该怎么控制呢?
(解决办法:经测试Listener在系统中是一个单例,在它的方法上加上synchronize关键字就可以保证list的线程安全了。)
本文为作者原创,转载请注明出处http://www.cnblogs.com/weirhp/archive/2011/05/08/sesssionlistener.html
发表评论
-
简单倒计时模板插件
2017-07-12 12:01 639Countdown.js (function() { ... -
简单上传文件插件
2017-07-12 11:46 690team777.upload.js js: ; ... -
简化的原生ajax
2015-03-23 14:25 660/* * * path: seaAjax.js ... -
简单入门-JavaScript正则表达式
2015-03-23 14:19 865什么是正则表达式?这个问题可以参见:“正则表达式30分钟入门 ... -
Fxtpl v1.0 繁星前端模板引擎(非原创)
2014-08-18 13:48 3122Fxtpl 全新的JS模板引擎 Download t ... -
WEB前端开发数据模拟工具JOJO
2014-08-15 18:28 2481注:图片见压缩包中的word文档! 前端数据模拟工 ... -
利用html5进行城市定位!aqi指数的获取
2014-07-08 17:52 21437<html><head> < ... -
seajs打包部署工具spm的使用总结
2014-06-30 14:22 942相信使用seajs的好处大家都是知道的,接触seajs好像 ... -
eclispe 编辑XML时,输入<无法自动提示的修复
2014-02-20 14:40 1019eclispe 当编辑XML时,一 ... -
javaScript的性能优化
2014-01-17 14:05 1288随着网络的发展,网速 ... -
秒杀倒计时控件
2014-01-17 11:20 3171/** * User: yongwang * Da ... -
百度地图API文档
2012-11-13 18:31 1157sdfsfsdf -
可以用来解析字符串表达式的包
2012-10-16 10:57 2129import com.singularsys.jep.J ... -
JavaScript 图片的上传前预览(兼容所有浏览器)
2012-10-11 09:17 52552功能描述 通过 JavaScript 实现图片的 ... -
实现局部图片的懒加载
2012-08-31 14:52 5521此方式适用和iscroll结合使用,若用于普 ... -
iscroll介绍
2012-06-12 18:52 0参考 http://hi.baidu.com/xiaowuph ... -
JS页面跳转和js对iframe进行页面跳转、刷新
2012-04-17 10:48 4088一、JS方式的页面跳转1.window.loc ... -
struts1的一些总结
2012-04-16 11:11 1757struts1 7大组件 ActionServlet 控制器 ... -
两种 js下载文件的方法
2012-04-13 22:07 176911 function DownURL(strRemoteUR ... -
eval函数解析json数据的小细节
2012-04-13 17:05 2466关于json数据在客户端使用程度比较频繁,与服务器交互使 ...
相关推荐
在JavaWeb开发中,实现同一账号同一时间只能在一个地点登录的功能,主要目的是为了增强系统的安全性,防止用户账户被他人恶意登录或同时在多个设备上使用,例如在在线考试系统、即时通讯应用等场景中尤为关键。...
java Web 同一个用户名不能同时登陆的思路 .doc ...java web中实现同一帐号同一时间只能一个地点登陆(类似QQ登录的功能).doc java中如何实现同一账号不能同时登录.doc session保证两用户不能同时登陆一个账号.doc
在Java Web开发中,实现QQ登录功能并限制一个账号同一时间只能一个人登录,涉及到的关键技术包括用户会话管理、状态跟踪以及异常情况处理。以下是对这个功能实现的详细解析: 首先,我们需要一个全局的存储结构来...
本解决方案主要关注如何利用DWR来实现一个用户在同一时间只能登录一次的功能,类似于QQ的单点登录机制。 首先,我们需要理解DWR的基本工作原理。DWR允许JavaScript直接调用服务器端的Java方法,并将结果返回到...
例如,在即时通讯软件如QQ中,如果一个账号在另一台设备上登录,则原先的登录会自动断开。本知识点主要介绍一种利用Java的`session`技术配合`session`监听器来实现这一功能的方法。 #### 实现原理与步骤 为了实现...
这里我们探讨的是一种集群环境下的解决方案,它允许我们确保一个账号在同一时间只能在一个地方登录,即实现“单点登录”功能。这个方案主要基于Spring Boot和Redis技术栈来实施。 **Spring Boot** 是一种基于Java的...
根据提供的文件信息,文档主要描述了如何使用JSP和servlet技术实现一个特定功能:当同一用户尝试在不同位置登录时,能够“挤掉”之前的登录会话,且实现这一过程时页面不需要刷新。 ### 关键知识点解析 #### 1. ...
【标题】"精选_基于JAVA的局域网聊天软件的设计与实现(仿制QQ)_源码打包"揭示了这是一个关于使用Java编程语言开发的局域网聊天应用项目,旨在模仿QQ的功能。这个软件的设计和实现涉及到网络通信、图形用户界面(GUI...
在Java Web开发中,Cookie是一种常用的客户端存储机制,它用于在用户浏览器中保存少量信息,以便在用户访问网站的不同页面时能够保持用户的登录状态。"JAVA cookie记住登录状态10天"这个主题主要关注如何利用Cookie...
在本场景中,"ssh写的用户登录权限实现"指的是使用SSH协议来控制用户登录的权限,确保在同一时间只有一个用户能够使用特定的账号登录系统。这种机制可以防止未经授权的并发登录,增加系统的安全性。 Struts2、...
下面是一个简单的Java示例代码,展示了如何实现用户登录状态的管理和检测异地登录的功能: ```java public class User implements HttpSessionBindingListener { private static java.util.Vector allUsers = new ...
- 设计一个清晰易用的登录界面,提供QQ登录选项,并支持用户选择不同的账号登录。 - 在登录成功后,应显示用户的基本信息(如头像、昵称等),提高用户体验感。 9. **安全性考虑** - 在实现过程中,需要关注...
Java在线聊天系统是一种基于Web的即时通讯应用,它利用了Java技术栈来实现用户之间的实时通信功能,类似于我们在日常生活中使用的浏览器版QQ。这个系统可以让多个用户在同一时间进行互动交流,提供了一个便捷、高效...
Java是一种广泛使用的编程语言,尤其在开发Web应用时,它提供了丰富的库和工具来实现各种功能,其中之一就是生成和验证...这些文件暗示了这是一个Eclipse基于的Java Web项目,可能已经包含了部分验证码实现的代码。
验证码软件包是一个专门为Java开发者设计的工具,旨在简化Web应用中的验证码实现过程。这个软件包遵循了Apache 2.0开源许可协议,这意味着它允许用户自由地使用、修改和分发代码,为开发者提供了极大的灵活性和便利...
- **继承**:继承允许一个类继承另一个类的属性和方法,从而实现代码的复用。书中可能会通过实例介绍如何在Java中实现继承。 - **多态**:多态是指允许不同子类型的对象对同一消息做出响应的能力。Java中的多态主要...
《Java基础案例教程(第2版)》是一本旨在教授初学者Java编程基础知识的教材,其PPT形式的压缩包提供了清晰、直观的教学材料。在深入探讨这些知识点之前,我们首先了解一下Java语言的基础概念。 Java是一种面向对象...
- **简单服务器与客户端**:创建一个简单的TCP或UDP服务器和客户端,实践网络通信。 - **Web应用开发**:使用Servlet和JSP实现基于HTTP的Web应用。 10. **高级话题**: - **NIO(非阻塞I/O)**:Java的NIO库提供...