求助!spring实现同一个账号,重复登陆,后一个会把前一个挤掉,删除session的问题,附我的源代码!
首先是web.xml配置的监听器
<!-- session监听器 监听用户登录 -->
<listener>
<listener-class>
com.xm.util.SessionListener
</listener-class>
</listener>然后是监听器的类
ackage com.xm.util;
import javax.servlet.http.HttpServletRequest;
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;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.xm.entity.User;
import java.util.*;
/**
*
* 日期 : 2016-5-7<br>
* 作者 : zhangshulong<br>
* 项目 : ScaleWeb<br>
* 功能 :
* 监听器:用来监听用户登陆session,防止多次登陆,要求用户登陆方法中存放session格式为session.setAttribute("user"
* ,user);<br>
*/
public class SessionListener implements HttpSessionListener,
HttpSessionAttributeListener {
// log4j
private final static Log log = LogFactory.getLog(SessionListener.class);
/**
* seeionId和用户的绑定关系
*/
public static final Map<String, String> SESSIONID_USER=new HashMap<String,String>();
/**
* 用户和Session绑定关系
*/
public static Map<String, HttpSession> loginUser = new HashMap<String, HttpSession>();// 保存当前登录的所有用户
// 用这个作为session中的key
public static String SESSION_LOGIN_NAME = "user";
// 执行setAttribute的时候, 当这个属性本来不存在于Session中时, 调用这个方法.
public void attributeAdded(HttpSessionBindingEvent se) {
// 如果添加的属性是用户名, 则加入map中
if (se.getName().equals(SESSION_LOGIN_NAME)) {
User u = (User) se.getValue();
loginUser.put(u.getUsername(), se.getSession());
System.out.println("执行attributeAdded");
}
}
// 当执行removeAttribute时调用的方法
public void attributeRemoved(HttpSessionBindingEvent se) {
// 如果移除的属性是用户名, 则从map中移除
if (se.getName().equals(SESSION_LOGIN_NAME)) {
try {
User u = (User) se.getSession().getAttribute("user");
loginUser.remove(u.getUsername());
System.out.println("执行attributeRemoved");
} catch (Exception e) {
System.out.println("=============1===============");
log.debug(e);
}
}
}
// 当执行setAttribute时 ,如果这个属性已经存在, 覆盖属性的时候, 调用这个方法
public void attributeReplaced(HttpSessionBindingEvent se) {
// 如果改变的属性是用户名, 则跟着改变map
if (se.getName().equals(SESSION_LOGIN_NAME)) {
User u = (User) se.getValue();
loginUser.put(u.getUsername(), se.getSession());
System.out.println("执行attributeReplaced");
}
}
// session创建时调用这个方法
public void sessionCreated(HttpSessionEvent se) {
log.debug("SessionListener........session创建-----"
+ se.getSession().getId());
}
// Session失效或者过期的时候调用的这个方法,
public void sessionDestroyed(HttpSessionEvent se) {
// 如果session超时, 则从map中移除这个用户
try {
String sessionId=se.getSession().getId();
//User u = (User) se.getSession().getAttribute("user");
//loginUser.remove(u.getUsername());
loginUser.remove(SESSIONID_USER.remove(sessionId));
System.out.println("销毁session:"+sessionId);
} catch (Exception e) {
System.out.println("=============2===============");
log.debug(e);
}
}
/**
* 用户登录时的处理
* 处理一个账号同时只有一个地方登录的关键
* @param request
*/
public static void userLoginHandle(HttpServletRequest request){
//当前登录的用户
String userName=request.getParameter("userName");
//当前sessionId
String sessionId=request.getSession().getId();
//删除当前sessionId绑定的用户,用户--HttpSession
loginUser.remove(SESSIONID_USER.remove(sessionId));
//删除当前登录用户绑定的HttpSession
HttpSession session=loginUser.remove(userName);
if(session!=null){
SESSIONID_USER.remove(session.getId());
session.removeAttribute("userName");
session.setAttribute("userMsg", "您的账号已经在另一处登录了,你被迫下线!");
}
}
}
然后是工具类
import java.util.Set;
import javax.servlet.http.HttpSession;
/**
*
* 日期 : 2016-5-7<br>
* 作者 : zhangshulong<br>
* 项目 : ScaleWeb<br>
* 功能 : 登陆验证工具类<br>
*/
public class LogUtil {
/**
*
* Description : 判断用户是否登陆过
* @param username
* @return
*/
public static boolean isLogonUser(String username) {
Set<String> keys = SessionListener.loginUser.keySet();
if(keys.contains(username))
return true;
return false;
}
/**
*
* Description : 删除session,并将全局变量中的session删除
* @param username
*/
public static void removeSession(String username){
SessionListener.loginUser.get(username).invalidate();
}
}最后是Controller层的登陆方法,在这里我只写登陆方法
@RequestMapping("lg")
public String login(Model model,HttpServletRequest request,String username,String password,String isFront){
HttpSession session = request.getSession();
if(username==null){
return "login";
}
List<User> list = userService.findUserByName(username);
User user = list.get(0);
System.out.println("=============username==================="+username);
if(LogUtil.isLogonUser(username)){//判断该账号是否登陆过
System.out.println("重复");
SessionListener.userLoginHandle(request);
System.out.println("删除之前同一账户登陆过的session");
}
session.setAttribute("user", user);
model.addAttribute("user", user);
if(isFront.equals("front")){
return "front/index";
}
return "back/index";
}
以上就是我的代码,实现不了,求大神们帮忙看一看啊
相关推荐
[code]SSH 实现注册,登陆,查看,添加,修改,删除
标题中的“SSH 实现注册,登陆,查看,添加,修改,删除”指的是使用SSH(Spring、Struts2、Hibernate)框架组合开发一个功能完备的Web应用程序。
CISP-CSE注册云安全工程师备考资源包基础教程
随着云计算技术的普及,云安全已成为网络安全领域的核心议题。CISP-CSE(注册云安全工程师)认证由中国信息安全测评中心颁发,旨在培养具备云安全专业知识和实践能力的实战型人才。本教程将结合"CISP-CSE注册云安全工程师备考资源包",系统性地为您梳理云安全的核心知识体系,并提供实战案例分析,助您高效备考。
绘图模拟:在冲动环境中固定时间的示例 附matlab代码.rar
绘图模拟:在冲动环境中固定时间的示例 附matlab代码.rar
基于规则的电动汽车混合能源管理系统,采用MATLAB、Simulink、Simscape Electrical和Stateflow。.zip
1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
完全复现虚拟同步发电机VSG自适应惯量阻尼控制仿真、根轨迹、调节系数对比(Simulink仿真、Matlab代码实现)
内容概要:本文围绕虚拟同步发电机(VSG)的自适应惯量阻尼控制展开深入研究,通过Simulink搭建详细的系统仿真模型,并结合Matlab代码实现控制算法,系统分析了根轨迹特性及不同调节系数对系统动态响应的影响。研究重点在于设计并验证一种能够根据电网频率变化自动调整惯量和阻尼参数的自适应控制策略,有效提升了VSG在面对负载突变或新能源波动时的频率稳定性与抗干扰能力,为高比例可再生能源接入下的电力系统稳定运行提供了关键技术支撑。; 适合人群:具备电力系统分析、自动控制理论及新能源并网技术基础的研究生、科研人员以及从事微电网、分布式能源系统设计与运维的工程技术人员。; 使用场景及目标:①深入理解虚拟同步发电机的工作原理及其在提升电网惯性方面的关键作用;②掌握基于Simulink的电力电子与控制系统建模与仿真方法;③学习并实践惯量和阻尼自适应控制策略的设计流程,通过根轨迹分析手段优化控制器参数,提升系统动态性能。; 阅读建议:建议读者结合所提供的Simulink仿真模型与Matlab代码进行同步操作,重点关注控制器设计逻辑与参数整定过程,通过改变调节系数观察系统响应变化,深化对稳定性判据与控制性能之间关系的理解。


Web 开发
