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)这三个单词上的首字母组成.它是一种应用模型,它的 ...
随机推荐
- fiddler 手机+浏览器 抓包
用fiddler对手机上的程序进行抓包 前提: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在同一wi ...
- .Net Core微服务——网关(2):ocelot集成consul
有consul基础的都知道,consul可以发现新增的服务,剔除掉无效的服务,赋予应用自动伸缩的能力.而ocelot如果集成了consul,那ocelot也能拥有这些能力,还可以自主选择负载均衡策略, ...
- VSCode PHP 开发环境配置 详细教程
VSCode PHP 开发环境配置 详细教程 这篇文章主要介绍了VScode+PHPstudy配置PHP开发环境的步骤,整理了官方以及优秀第三方的内容,对于学习和工作有一定借鉴意义. 配置过程 第一步 ...
- Linux 系统分区方案 详细教程
简单分区方案 实际上,很多时候我们只需要分两个区:/和交换分区,日常使用基本不会有任何影响,甚至于交换分区对于现在的电脑来说都不是必要的,我们完全可以只分配一个根分区.linux只需要一个/根分区就可 ...
- Centos6.8 yum报错及修复YumRepo Error: All mirror URLs are not using ftp, http[s] or file. Eg. Invalid
问题 使用yum安装软件时报错 YumRepo Error: All mirror URLs are not using ftp, http[s] or file. Eg. Invalid relea ...
- [Vue warn]: Unknown custom element: <sapn> - did you register the component correctly? For recursive components, make sure to provide the "name" option. found in ---> <Evaluate> at src/views/index/
关于vue报错: [Vue warn]: Unknown custom element: <sapn> - did you register the component correctly ...
- 不可忽视的Dubbo线程池
问题描述 线上突然出现Dubbo超时调用,时间刚好为Consumer端设置的超时时间. 有好几个不同的接口都报超时了 第1次调用超时,第2次(或第3次)重试调用非常快(正常水平) Dubbo调用超时的 ...
- Mybatis动态传入tableName--非预编译(STATEMENT)
在使用Mybatis过程中,你可以体会到它的强大与灵活之处,由衷的为Mybatis之父点上999个赞!在使用过程中经常会遇到这样一种情况,我查询数据的时候,表名称是动态的从程序中传入的,比如我们通过m ...
- 用图像识别玩Chrome断网小游戏
先来看一下效果 正文 最近在学习机器学习方面的知识,想着做个东西玩玩,然后就接触到了TensorFlow这个机器学习框架,这个框架封装了机器学习的一些常用算法. 不过要自己实现一套流程还是比较麻烦,我 ...
- Jetpack架构组件学习(2)——ViewModel和Livedata使用
要看本系列其他文章,可访问此链接Jetpack架构学习 | Stars-One的杂货小窝 原文地址:Jetpack架构组件学习(2)--ViewModel和Livedata使用 | Stars-One ...