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)这三个单词上的首字母组成.它是一种应用模型,它的 ...
随机推荐
- Windows 防火墙
本文防火墙配置是基于 Windows Server 2008 R2 服务器进行叙述,其他Windows服务器版本仅供参考 防火墙安全策略 定义 :安全策略按照一定规则检查数据流是否可以通过防火墙的基本 ...
- VSCode 微信小程序 开发环境配置 详细教程
本博客已暂停更新,需要请转新博客http://www.whbwiki.com/231.html 配置 VsCode 微信小程序开发环境并非不用官方的 微信小程序开发者工具 ,而是两者配合适用,可以极大 ...
- 浅讲.Net 6 并与之前版本写法对比
介绍 昨天vs2022正式版已经推出了,估计很多人已经下载并开始创建.Net 6 开始尝鲜了, 本节我简要的给大家介绍一下.Net 6的一些改动. 正文 本次.Net6带来最明显的变化就是: 采用顶级 ...
- HTTPS-自己生成数字证书
一.获取证书的途径 自签名证书,适用于开发者测试HTTPS,最快速的途径就是生成自签名证书,非常方便. Let's Encrypt证书,可以使用免费CA机构签发的证书. 使用收费CA机构签发的证书,如 ...
- 探讨 Rust 智能指针 | Vol.17
分享主题:<探讨 Rust 智能指针>| Vol. 17 分享讲师:苏林 分享时间: 周日晚上 2021-11-14 20:30-21:30 腾讯会议地址: https://meeting ...
- 加班时的灵感迸发,我用selenium做了个窗口化的爬*宝数据。(附源码链接)
完整代码&火狐浏览器驱动下载链接:https://pan.baidu.com/s/1pc8HnHNY8BvZLvNOdHwHBw 提取码:4c08 双十一刚过,想着某宝的信息看起来有些少很难做 ...
- CentOS 8.4安装Docker
前言: Docker 是一个用于开发.传送和运行应用程序的开放平台.Docker 使您能够将应用程序与基础设施分开,以便您可以快速交付软件.使用 Docker,您可以像管理应用程序一样管理基础设施.通 ...
- 力扣 - 剑指 Offer 12. 矩阵中的路径
题目 剑指 Offer 12. 矩阵中的路径 思路1(回溯.DFS) 这题可以使用回溯+递归来解决,思路如下: 将二维数组的每一个元素都作为起点进行回溯查找 每次查找的时候,都有四个方向,但是上一个方 ...
- [bzoj4094]Optimal Milking
建立线段树,维护区间左端点选/不选,右端点选/不选且不含有相邻两个同时选的最大值,合并时注意细节即可 1 #include<bits/stdc++.h> 2 using namespace ...
- [cf1421E]Swedish Heroes
令$p_{i}$为最终$a_{i}$之前的系数($p_{i}\in \{-1,1\}$),则有$n+\sum_{i=1}^{n}[p_{i}=-1]\equiv 1(mod\ 3)$ 证明:对于两个满 ...