同一账号后者登录前者被强制退出:(可以通过监听器或过滤器进行监测session是否无效)

首先根据输入的用户名和密码做验证,通过验证查询用户信息。在用户信息不为空的前提下,比较静态变量中的sessionid和浏览器session获取的getId(),判断两个值是否一致,若一致,则通过 正常走流程,若不一致,则返回登录页面,session设置msg,提示“账户失效或异地登录”;

web.xml:

  1. <session-config>
  2. <session-timeout>180</session-timeout><!--session过期时间设置-->
  3. </session-config>

controller:

  1. public static Map<HttpSession, String> loginSessionList = new HashMap<>();//保存当前登录的所有用户
  2.  
  3. //登录方法
  4. @ResponseBody
  5. @RequestMapping(value = "/login", method = RequestMethod.POST)
  6. public ResponseResult login(User user, HttpServletRequest request,HttpSession session) {
  7. //.............................
  8. session.setAttribute("username", user.getLoginName());
  9. session.setAttribute("logoutType", "0");
  10. checkLoginSession(session,user.getLoginName());
  11. loginSessionList.put(session, user.getLoginName());
  12. //.............................
  13.  
  14. }
  15.  
  16. /**
  17. * 检查用户是否已经登录
  18. * @param session
  19. * @param loginName
  20. * @return
  21. */
  22. private String checkLoginSession(HttpSession session,String loginName) {
  23. String checkValue = "0";
  24. HttpSession reSession = null;
  25. try {
  26. Set<HttpSession> keys = loginSessionList.keySet();
  27. for (HttpSession key : keys) {
  28. if (loginSessionList.get(key).equals(loginName) && !session.equals(key)) {
  29. //key.invalidate();//如果该用户名有登录,则使前者失效(适用于方法一)
  30. key.setAttribute("logoutType", "1");
  31. checkValue = "1";
  32. reSession = key;
  33. break;
  34. }
  35. }
  36. if (checkValue.equals("1") && reSession != null) {
  37. //防止用户直接关闭浏览器
  38. loginSessionList.remove(reSession);
  39. }
  40. } catch (Exception e) {
  41. // TODO 自动生成的 catch 块
  42. e.printStackTrace();
  43. }
  44. return null;
  45. }

参考链接:servlet/filter/listener/interceptor区别与联系

方法一:(使用 HttpSessionListener进行监听)

使用监听器监听对页面跳转不好进行控制

web.xml:

  1. <!-- session监听 -->
  2. <listener>
  3. <listener-class>net.nblh.system.shiro.OnlineUserListener</listener-class><!--监听器类的路径-->
  4. </listener>

OnlineUserListener:

  1. package net.nblh.system.shiro;
  2.  
  3. import javax.servlet.http.HttpSession;
  4. import javax.servlet.http.HttpSessionEvent;
  5. import javax.servlet.http.HttpSessionListener;
  6.  
  7. import net.nblh.system.controller.SystemController;
  8.  
  9. public class OnlineUserListener implements HttpSessionListener{
  10.  
  11. /**
  12. * 监听session创建
  13. */
  14. @Override
  15. public void sessionCreated(HttpSessionEvent arg0) {
  16. // TODO 自动生成的方法存根
  17.  
  18. }
  19.  
  20. /**
  21. * 监听session销毁
  22. */
  23. @Override
  24. public void sessionDestroyed(HttpSessionEvent event){
  25. try {
  26. // TODO 自动生成的方法存根
  27. HttpSession session = event.getSession();
  28. // 取得登录的用户名
  29. String username = (String) session.getAttribute("username");
  30. SystemController.loginSessionList.remove(session);
  31. System.out.println(username + "退出。");
  32. } catch (Exception e) {
  33. // TODO 自动生成的 catch 块
  34. e.printStackTrace();
  35. }
  36.  
  37. }
  38.  
  39. }

方法二:(使用Filter进行过滤)

web.xml:

  1. <!-- session过滤器 -->
  2. <filter>
  3. <filter-name>sessionFilter</filter-name>
  4. <filter-class>net.nblh.system.shiro.SessionFilter</filter-class><!--过滤器类的路径-->
  5. </filter>
  6. <filter-mapping>
  7. <filter-name>sessionFilter</filter-name>
  8. <url-pattern>/*</url-pattern>
  9. </filter-mapping>

SessionFilter:

  1. package net.nblh.system.shiro;
  2.  
  3. import java.io.IOException;
  4. import java.io.PrintWriter;
  5.  
  6. import javax.servlet.Filter;
  7. import javax.servlet.FilterChain;
  8. import javax.servlet.FilterConfig;
  9. import javax.servlet.ServletException;
  10. import javax.servlet.ServletRequest;
  11. import javax.servlet.ServletResponse;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. import javax.servlet.http.HttpSession;
  15.  
  16. import net.nblh.system.controller.SystemController;
  17. import net.nblh.system.entity.SysConfigItemValue;
  18. import net.nblh.utils.StringUtils;
  19.  
  20. /**
  21. * Session拦截器
  22. * @author lijd
  23. *
  24. */
  25. public class SessionFilter implements Filter {
  26.  
  27. @Override
  28. public void destroy() {
  29. // TODO 自动生成的方法存根
  30.  
  31. }
  32.  
  33. @Override
  34. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  35. throws IOException, ServletException {
  36. try {
  37. // TODO 自动生成的方法存根
  38. HttpServletRequest httpRequest = (HttpServletRequest) request;
  39. HttpServletResponse httpResponse = (HttpServletResponse) response;
  40. HttpSession session = httpRequest.getSession();
  41.  
  42. //异地顶替账号登录url
  43. String toLoginUrl = session.getServletContext().getContextPath()+"/system/tologin2";//列席人登录页面
  44. //session过期登录url
  45. String sessionLoginUrl = StringUtils.isNotEmpty(SysConfigItemValue.getValue("sessionOutTimeToURL"))?SysConfigItemValue.getValue("sessionOutTimeToURL"):toLoginUrl;
  46. String url = httpRequest.getRequestURI();
  47. String path = url.substring(url.lastIndexOf("/"));
  48. /*// 判断是否为ajax请求
  49. if (httpRequest.getHeader("x-requested-with") != null && httpRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
  50. //该请求是 AJAX 异步HTTP请求
  51. if (session.getAttribute("shiroSavedRequest") != null && session.getAttribute("currentUser") == null) {
  52. SystemController.loginSessionList.remove(session);
  53. session.invalidate();
  54. httpResponse.addHeader("sessionstatus", "timeOut");//Session已过期
  55. httpResponse.addHeader("loginPath", sessionLoginUrl);
  56. chain.doFilter(request, response);
  57. }else {
  58. chain.doFilter(request, response);// 不可少,否则请求会出错
  59. }
  60. }*/
  61. if (path.indexOf("sessionTimeOut") != -1 && session.getAttribute("shiroSavedRequest") != null && session.getAttribute("currentUser") == null) {
  62. SystemController.loginSessionList.remove(session);
  63. session.invalidate();
  64. //session过期
  65. toLoginUrl(response,"会话已过期",sessionLoginUrl);
  66. }
  67. else if(session.getAttribute("logoutType") != null && session.getAttribute("logoutType").equals("1")){
  68. SystemController.loginSessionList.remove(session);
  69. session.invalidate();
  70. // logoutType=0:正常,logoutType=1:异地登录
  71. toLoginUrl(response,"用户已在别处登录",toLoginUrl);
  72. } else {
  73. try {
  74. chain.doFilter(request, response);
  75. } catch (Exception e) {
  76. SystemController.loginSessionList.remove(session);
  77. session.invalidate();
  78. toLoginUrl(response,"会话已过期!",sessionLoginUrl);
  79. }
  80. }
  81. } catch (Exception e) {
  82. // TODO 自动生成的 catch 块
  83. e.printStackTrace();
  84. }
  85. }
  86.  
  87. @Override
  88. public void init(FilterConfig arg0) throws ServletException {
  89. // TODO 自动生成的方法存根
  90.  
  91. }
  92.  
  93. /**
  94. * session无效后跳转指定路径
  95. * @param response
  96. * @param message
  97. * @param loginUrl
  98. */
  99. private void toLoginUrl (ServletResponse response,String message,String loginUrl) {
  100. String str = "<script language='javascript'>alert('"+ message +"');" + "top.location.href='" + loginUrl + "';</script>";
  101. response.setContentType("text/html;charset=UTF-8");// 解决中文乱码
  102. try {
  103. PrintWriter writer = response.getWriter();
  104. writer.write(str);
  105. writer.flush();
  106. writer.close();
  107. } catch (Exception e) {
  108. e.printStackTrace();
  109. }
  110. }
  111. }

使用响应头进行JS控制:

  1. httpResponse.addHeader("sessionstatus", "timeOut");//Session已过期
  2. httpResponse.addHeader("loginPath", sessionLoginUrl);
  3. chain.doFilter(request, response);

js:

  1. <script type="text/javascript">
  2. $(document).ajaxComplete(function(event, xhr, settings) {
  3. if(xhr.getResponseHeader("sessionstatus")=="timeOut"){
  4. if(xhr.getResponseHeader("loginPath")){
  5. alert("会话过期,请重新登陆!");
  6. window.location.replace(xhr.getResponseHeader("loginPath"));
  7. }else{
  8. alert("请求超时请重新登陆 !");
  9. }
  10. }
  11. });
  12. </script>

java-同一用户顶替操作(session过期或无效)的更多相关文章

  1. java web session过期 跳转页面没有跳出frame的问题

    对于frame页面框架的java web项目,如果session过期执行跳转操作时,只在一个frame中(例如center frame)跳转到设置的login页面了,为了能直接跳转到最初的登录页面,就 ...

  2. Java操作Session与Cookie

    1,Java操作Session Java操作Session非常简单,步骤如下 1.1,在servlet中通过request获取session HttpSession session = request ...

  3. 关于使用struts2时子窗体页面跳转后在父窗体打开的问题以及Session过期后的页面跳转问题

    问题1:传统的系统界面,iframe了三个页面,上,左,右,用户点击注销的按钮在上面得top.jsp里面,方法:<a href="../adminAction/admin_logout ...

  4. js--Ajax的小知识(二):处理ajax的session过期的请求

    问题的产生: 现如今Ajax在Web项目中应用广泛,几乎可以说无处不在. 有时会碰到这样个问题:当Ajax请求遇到Session超时,应该怎么办? 显而易见,传统的页面跳转在此已经不适用,因为Ajax ...

  5. session过期时间

    在一般系统登录后,都会设置一个当前session失效的时间,以确保在用户没有使用系统一定时间后,自动退出登录,销毁session. 具体设置很简单: 在主页面或者公共页面中加入:session.set ...

  6. MVC 访问IFrame页面Session过期后跳转到登录页面

    Web端开发时,用户登录后往往会通过Session来保存用户信息,Session存放在服务器,当用户长时间不操作的时候,我们会希望服务器保存的Session过期,这个时候,因为Session中的用户信 ...

  7. asp.net web.config 设置Session过期时间

    在Asp.net中,可以有四处设置Session的过期时间:(原文作者:望月狼地址:http://www.cnblogs.com/wangyuelang0526/) 一.全局网站(即服务器)级 IIS ...

  8. Senparc.Weixin.MP SDK 微信公众平台开发教程(七):解决用户上下文(Session)问题

    从这篇文章中我们已经了解了微信公众平台消息传递的方式,这种方式有一个先天的缺陷:不同用户的请求都来自同一个微信服务器,这使得常规的Session无法使用(始终面对同一个请求对象,况且还有对方服务器Co ...

  9. [转]菜鸟程序员之Asp.net MVC Session过期异常的处理

    本文转自:http://www.cnblogs.com/JustRun1983/p/3377652.html 小赵是刚毕业的计算机专业方面的大学生,4年的大学时间里面,他读过了很多编程方面的数据,也动 ...

随机推荐

  1. Beta阶段冲刺二

    Beta冲刺二 1.团队TSP 团队任务 预估时间 实际时间 完成日期 对数据库的最终完善 120 150 12.2 对学生注册功能的完善--新增触发器 150 140 11.29 对教师注册功能的完 ...

  2. 常用的数组函数-S

    header('content-type:text/html;charset=utf-8'); //声明一个数组 $arr=['one'=>'aaa','two'=>'bbb','thre ...

  3. input搜索框:根据历史记录自动填充后,去除默认黄色背景

    如果是纯色背景,直接通过box-shadow覆盖即可: input:-webkit-autofill { color: #333!important; -webkit-text-fill-color: ...

  4. Openresty 进行限流的方法

    1.使用Openresty进行限流, 使用漏桶原理进行设计 和路由系统设计类似. LUA脚本去通过变量去redis取值,从redis中得到队列的大小.漏和桶的大小. 然后通过比较,队列大小与漏和桶进行 ...

  5. 入门项目 A6 lib common 登陆状态装饰

    # 用户认证装饰器 def auth(func): from core import src def inner(*args, **kwargs): # 调用被装饰函数前需要做的操作 if src.u ...

  6. 玩转BLE(3)_使用微信蓝牙精简协议伪造记步数据

    1. 前言 在物联网时代,有一个问题肯定会让人头疼(现在已经初露端倪了): 物联网中的IOT设备有两个主要特点: 1)简单小巧(不具备复杂的人机交互接口,需要手机等终端设备辅助完成配置.控制等功能). ...

  7. matlab批量读取一个文件夹里类似命名的mat文件

    参考网址: Matlab读取同一路径下多个txt或mat文件总结 matlab 批量读取数据文件.mat .dat 整理:matlab批量读入数据文件的方法 首先命名方式体现在只是名字里数字有变化,其 ...

  8. javamail发邮件

    使用JavaMail发送一封简单邮件的步骤:(1)创建代表邮件服务器的网络连接信息的Session对象.(2)创建代表邮件内容的Message对象(3)创建Transport对象.连接服务器.发送Me ...

  9. golang channel

    ex1 package main /* goroutine 是由GO运行时管理的轻量级线程 go f(x,y, z) 就启动了一个goroutine, 其中f,x,y,z在当前goroutine中立即 ...

  10. imeiimsi生成规则

    添加SMI 和 IMSI修改  添加模拟器名修改(MEmu_ 修改成其他的名字,不支持批量修改)   IMSI第十位:7代表是145卡,6代表186卡,3代表156,0代表130,其他的可以自己找 预 ...