java web 限制同一个用户在不同处登入
用到的技术:map集合,sessionListener监听器,Fiter过滤器。
实现思路:
一.利用一个全局的map集合来保存每个用户sessionID的值的一个集合。一个用户对应一个sessionID当相同的用户登录的时候判断它在集合总有没有值。(保存用户所有登录记录)
二.
2.1.实现sessionListener在当一个session被销毁的时候强制移除当前用户所对应的sessionID
2.2.实现Fiter来判断每次请求map集合中是否有值。(实现强制退出)
代码:代码是复制别人的,做了些修改。
public
class
LoginUserMap {
ConcurrentHashMap这个集合是线程安全的而且性能方面比hasTable和hasMap都好。在高并发的条件下执行速度更快。
private
static
Map<String, String> loginUsers =
new
ConcurrentHashMap<String, String>();
/**
* 将用户和sessionId存入map
* @param key
* @param value
*/
public
static
void
setLoginUsers(String loginId, String sessionId) {
loginUsers.put(loginId, sessionId);
}
/**
* 获取loginUsers
* @return
*/
public
static
Map<String, String> getLoginUsers() {
return
loginUsers;
}
/**
* 根据sessionId移除map中的值
* @param sessionId
*/
public
static
void
removeUser(String sessionId) {
for
(Map.Entry<String, String> entry : loginUsers.entrySet()) {
if
(sessionId.equals(entry.getValue())) {
loginUsers.remove(entry.getKey());
break
;
}
}
}
/**
* 判断用户是否在loginusers中
* @param loginId
* @param sessionId
* @return
*/
public
static
boolean
isInLoginUsers(String loginId, String sessionId) {
return
(loginUsers.containsKey(loginId) && sessionId.equals(loginUsers.get(loginId)));
}
}
//登录方法所在的地方
public
void
login(ttpServletRequest request) {
try
{
......
//一系列登录的方法
HttpSession session = request.getSession();
LoginUserMap.setLoginUsers(username, session.getId());
//保存sessionId到map中
}
catch
(LoginException ex) {
throw
ex;
}
}
HttpSessionListener
public
class
SessionListener
implements
HttpSessionListener {
private
Log log = LogFactory.getLog(SessionListener.
class
);
/**
* 创建session时候的动作
* @param event
*/
@Override
public
void
sessionCreated(HttpSessionEvent event) {
}
/**
* 销毁session时候的动作
* @param event
*/
@Override
public
void
sessionDestroyed(HttpSessionEvent event) {
HttpSession session = event.getSession();
String sessionId = session.getId();
//移除loginUsers中已经被销毁的session
LoginUserMap.removeUser(sessionId);
log.info(sessionId +
"被销毁!"
);
}
}
<
listener
>
<
listener-class
>....SessionListener</
listener-class
>
</
listener
>
public
class
LoginLimitFilter
implements
Filter{
private
Log log = LogFactory.getLog(LoginLimitFilter.
class
);
/**
* 销毁时的方法
*/
@Override
public
void
destroy() {
}
/**
* 过滤请求
* @param request
* @param response
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public
void
doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain)
throws
IOException, ServletException {
HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletResponse servletResponse = (HttpServletResponse) response;
HttpSession session = servletRequest.getSession();
//获取项目路径
String path = servletRequest.getContextPath();
String basePath = servletRequest.getScheme()+
"://"
+servletRequest.getServerName()+
":"
+servletRequest.getServerPort()+path;
try
{
//获取登录信息
String loginId = session.getAttribute("yhid")
//判断当前用户的sessionId是否在loginUsers中,如果没有执行if后的操作
if
(!LoginUserMap.isInLoginUsers(loginId, session.getId())) {
//当前用户logout 注:退出登录最好别用session销毁的方法。
logout();
//自己的logout方法
//调到登录页面,并表明退出方式为挤下线
servletResponse.sendRedirect(basePath +
"?logoutway=edge"
);
}
}
catch
(Exception e) {
log.debug(
"获取当前用户信息失败,用户未登陆!"
, e);
}
finally
{
filterChain.doFilter(request, response);
}
}
/**
* 初始化方法
* @param arg0
* @throws ServletException
*/
@Override
public
void
init(FilterConfig arg0)
throws
ServletException {
}
}
<
filter
>
<
filter-name
>LoginLimitFilter</
filter-name
>
<
filter-class
>io.github.brightloong.loginlimite.LoginLimitFilter</
filter-class
>
</
filter
>
<
filter-mapping
>
<
filter-name
>LoginLimitFilter</
filter-name
>
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
window.onload = function(){
if
(window.parent != window){
window.parent.location.href=window.location.href;
}
else
{
if
(GetQueryString(
'logoutway'
)) {
alert('该用户已在其他地方登录,你已下线');
var url = window.location.href;
window.location.href = url.substr(
0
,url.indexOf(
'?logoutway=edge'
));
}
}
}
function GetQueryString(name)
{
var reg =
new
RegExp(
"(^|&)"
+ name +
"=([^&]*)(&|$)"
);
var r = window.location.search.substr(
1
).match(reg);
if
(r!=
null
)
return
unescape(r[
2
]);
return
null
;
}
java web 限制同一个用户在不同处登入的更多相关文章
- [转]Java web 开发 获取用户ip
如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,那么真正的用户端的真实IP则是取X-Forwarded-For中第一个非unknown的有效IP字符串. pu ...
- Struts2+AJAX+JQuery 实现用户登入与注册功能。
要求 必备知识 JAVA/Struts2,JS/JQuery,HTML/CSS基础语法. 开发环境 MyEclipse 10 演示地址 演示地址 预览截图(抬抬你的鼠标就可以看到演示地址哦): 关于U ...
- hibernate连接oracle12c数据库报:java.sql.SQLException: ORA-01017: 用户名/口令无效; 登录被拒绝。(用户名/口令在oracle客户端以及cmd命令都能登入)
报错信息: 2017-09-22 15:40:07,354 WARN [org.hibernate.cfg.SettingsFactory] - Could not obtain connection ...
- Struts2+AJAX+JQuery 实现用户登入与注册功能
要求:必备知识:JAVA/Struts2,JS/JQuery,HTML/CSS基础语法:开发环境:MyEclipse 10 关于UI部分请查看下列链接,有详细制作步骤: 利用:before和:afte ...
- Java Web 开发利用Struts2+Spring+mybatis写一个用户登录界面以及简单的数据交互
框架的东西太复杂也难以讲通,直接上代码: 一.首先得配置环境 和导入必要的jar包 有一些重要的如下: Filter文件夹下的SafetyFilter.java model文件夹下的 Global ...
- 【适合公司业务】全网最详细的IDEA里如何正确新建【普通或者Maven】的Java web项目并发布到Tomcat上运行成功【博主强烈推荐】(类似eclipse里同一个workspace下【多个子项目】并存)(图文详解)
不多说,直接上干货! 首先,大家要明确,IDEA.Eclipse和MyEclipse等编辑器之间的新建和运行手法是不一样的. 如果是在Myeclipse里,则是File -> new -> ...
- java web用户登录界面
做这次实验,主要用到了mysql java web 的 内容 实验代码: IUserDao.java package com.jaovo.msg.dao; import java.util.List ...
- Java Web实现用户登录界面
一.学习Java Web需要的技术: Java语言基础:算法基础.常用数据结构.编程规范. 掌握常见的数据结构和实用算法:培养良好的编程习惯. Java面向对象:封装.继承.多态等,面向对象程序设计, ...
- Java Web实现用户登录功能
java web 学习记录一下 mvc结构实现mysql 连接 什么是mvc MVC是模型(model).视图(view).控制(controller)这三个单词上的首字母组成.它是一种应用模型,它的 ...
随机推荐
- C++ 变量声明 定义 作用域 链接性总结
变量定义 变量的定义用于为变量分配存储空间,还可以为变量指定初始值.在一个程序中,变量有且仅有一个定义. 变量声明 用于向程序表明变量的类型和名字.程序中变量可以声明多次,但只能定义一次. 变量的类型 ...
- 使用BadBoy录制JMeter脚本
BadBoy简介 BadBoy是一款免费WEB自动化测试工具,其实就是一个浏览器模拟工具,具有录制和回放功能,支持对录制出来的脚本进行调试.同时支持捕获表单数据的功能,所以能够进行自动化测试.但目前 ...
- tomcat9启动报错too low setting for -Xss
在tomcat下部署war包启动时报错,关键错误信息如下: Caused by: java.lang.IllegalStateException: Unable to complete the sca ...
- 表现层(jsp)、持久层(dao)、业务层(逻辑层、service)
转自:http://www.blogjava.net/jiabao/archive/2007/04/08/109189.html 为了实现web层(struts)和持久层(Hibernate)之间的松 ...
- 问题 G: 心急的C小加
题目描述 C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的时间,如果第i+1个木棒的重量和长度都大于等于第i个处理的木棒,那么将不会耗费时间,否 ...
- C 语言基础,来喽!
前言 C 语言是一门抽象的.面向过程的语言,C 语言广泛应用于底层开发,C 语言在计算机体系中占据着不可替代的作用,可以说 C 语言是编程的基础,也就是说,不管你学习任何语言,都应该把 C 语言放在首 ...
- 菜鸡的Java笔记 数字操作类
数字操作类 Math 类的使用 Random 类的使用 BigInteger 和 BigDecimal 类的使用 Math 是一 ...
- ubuntu更換清華軟件源
打开软件源的编辑sudo gedit /etc/apt/sources.list 软件源: Ubuntu--更改国内镜像源(阿里.网易.清华.中科大) 打開軟件源文件進行修改: 使用 sudo vim ...
- 微软商店打不开的教程(错误代码0x80131500)
1 打开win+R 输入`inetcpl.cpl` 2 点击高级 3 勾选上`使用TLS 1.2`或者点击还原默认设置就可以啦 4 然后就可以打开啦
- 新装centos机器基础配置之基础软件包安装
新装系统在做完基础的基线配置和加固还有yum源配置,还要安装一些基础软件.以备后期安装不便. centos6和7都可安装类基础包 yum install tree nmap dos2unix lsof ...