java-同一用户顶替操作(session过期或无效)
同一账号后者登录前者被强制退出:(可以通过监听器或过滤器进行监测session是否无效)
首先根据输入的用户名和密码做验证,通过验证查询用户信息。在用户信息不为空的前提下,比较静态变量中的sessionid和浏览器session获取的getId(),判断两个值是否一致,若一致,则通过 正常走流程,若不一致,则返回登录页面,session设置msg,提示“账户失效或异地登录”;
web.xml:
<session-config>
<session-timeout>180</session-timeout><!--session过期时间设置-->
</session-config>
controller:
    public static Map<HttpSession, String> loginSessionList = new HashMap<>();//保存当前登录的所有用户
    //登录方法
    @ResponseBody
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ResponseResult login(User user, HttpServletRequest request,HttpSession session) {
          //.............................
            session.setAttribute("username", user.getLoginName());
            session.setAttribute("logoutType", "0");
            checkLoginSession(session,user.getLoginName());
            loginSessionList.put(session, user.getLoginName());
          //.............................  
     }
     /**
     * 检查用户是否已经登录
     * @param session
     * @param loginName
     * @return
     */
    private String checkLoginSession(HttpSession session,String loginName) {
        String checkValue = "0";
        HttpSession reSession = null;
        try {
            Set<HttpSession> keys = loginSessionList.keySet();
            for (HttpSession key : keys) {
                if (loginSessionList.get(key).equals(loginName) && !session.equals(key)) {
                    //key.invalidate();//如果该用户名有登录,则使前者失效(适用于方法一)
                    key.setAttribute("logoutType", "1");
                    checkValue = "1";
                    reSession = key;
                    break;
                }
            }
            if (checkValue.equals("1") && reSession != null) {
                //防止用户直接关闭浏览器
                loginSessionList.remove(reSession);
            }
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        return null;
    }
参考链接:servlet/filter/listener/interceptor区别与联系
方法一:(使用 HttpSessionListener进行监听)
使用监听器监听对页面跳转不好进行控制
web.xml:
<!-- session监听 -->
<listener>
<listener-class>net.nblh.system.shiro.OnlineUserListener</listener-class><!--监听器类的路径-->
</listener>
OnlineUserListener:
package net.nblh.system.shiro; import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; import net.nblh.system.controller.SystemController; public class OnlineUserListener implements HttpSessionListener{ /**
* 监听session创建
*/
@Override
public void sessionCreated(HttpSessionEvent arg0) {
// TODO 自动生成的方法存根 } /**
* 监听session销毁
*/
@Override
public void sessionDestroyed(HttpSessionEvent event){
try {
// TODO 自动生成的方法存根
HttpSession session = event.getSession();
// 取得登录的用户名
String username = (String) session.getAttribute("username");
SystemController.loginSessionList.remove(session);
System.out.println(username + "退出。");
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} } }
方法二:(使用Filter进行过滤)
web.xml:
<!-- session过滤器 -->
<filter>
<filter-name>sessionFilter</filter-name>
<filter-class>net.nblh.system.shiro.SessionFilter</filter-class><!--过滤器类的路径-->
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
SessionFilter:
package net.nblh.system.shiro; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import net.nblh.system.controller.SystemController;
import net.nblh.system.entity.SysConfigItemValue;
import net.nblh.utils.StringUtils; /**
* Session拦截器
* @author lijd
*
*/
public class SessionFilter implements Filter { @Override
public void destroy() {
// TODO 自动生成的方法存根 } @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
// TODO 自动生成的方法存根
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
HttpSession session = httpRequest.getSession(); //异地顶替账号登录url
String toLoginUrl = session.getServletContext().getContextPath()+"/system/tologin2";//列席人登录页面
//session过期登录url
String sessionLoginUrl = StringUtils.isNotEmpty(SysConfigItemValue.getValue("sessionOutTimeToURL"))?SysConfigItemValue.getValue("sessionOutTimeToURL"):toLoginUrl;
String url = httpRequest.getRequestURI();
String path = url.substring(url.lastIndexOf("/"));
/*// 判断是否为ajax请求
if (httpRequest.getHeader("x-requested-with") != null && httpRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
//该请求是 AJAX 异步HTTP请求
if (session.getAttribute("shiroSavedRequest") != null && session.getAttribute("currentUser") == null) {
SystemController.loginSessionList.remove(session);
session.invalidate();
httpResponse.addHeader("sessionstatus", "timeOut");//Session已过期
httpResponse.addHeader("loginPath", sessionLoginUrl);
chain.doFilter(request, response);
}else {
chain.doFilter(request, response);// 不可少,否则请求会出错
}
}*/
if (path.indexOf("sessionTimeOut") != -1 && session.getAttribute("shiroSavedRequest") != null && session.getAttribute("currentUser") == null) {
SystemController.loginSessionList.remove(session);
session.invalidate();
//session过期
toLoginUrl(response,"会话已过期",sessionLoginUrl);
}
else if(session.getAttribute("logoutType") != null && session.getAttribute("logoutType").equals("1")){
SystemController.loginSessionList.remove(session);
session.invalidate();
// logoutType=0:正常,logoutType=1:异地登录
toLoginUrl(response,"用户已在别处登录",toLoginUrl);
} else {
try {
chain.doFilter(request, response);
} catch (Exception e) {
SystemController.loginSessionList.remove(session);
session.invalidate();
toLoginUrl(response,"会话已过期!",sessionLoginUrl);
}
}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
} @Override
public void init(FilterConfig arg0) throws ServletException {
// TODO 自动生成的方法存根 } /**
* session无效后跳转指定路径
* @param response
* @param message
* @param loginUrl
*/
private void toLoginUrl (ServletResponse response,String message,String loginUrl) {
String str = "<script language='javascript'>alert('"+ message +"');" + "top.location.href='" + loginUrl + "';</script>";
response.setContentType("text/html;charset=UTF-8");// 解决中文乱码
try {
PrintWriter writer = response.getWriter();
writer.write(str);
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
或
使用响应头进行JS控制:
httpResponse.addHeader("sessionstatus", "timeOut");//Session已过期
httpResponse.addHeader("loginPath", sessionLoginUrl);
chain.doFilter(request, response);
js:
<script type="text/javascript">
$(document).ajaxComplete(function(event, xhr, settings) {
if(xhr.getResponseHeader("sessionstatus")=="timeOut"){
if(xhr.getResponseHeader("loginPath")){
alert("会话过期,请重新登陆!");
window.location.replace(xhr.getResponseHeader("loginPath"));
}else{
alert("请求超时请重新登陆 !");
}
}
});
</script>
java-同一用户顶替操作(session过期或无效)的更多相关文章
- java web session过期 跳转页面没有跳出frame的问题
		对于frame页面框架的java web项目,如果session过期执行跳转操作时,只在一个frame中(例如center frame)跳转到设置的login页面了,为了能直接跳转到最初的登录页面,就 ... 
- Java操作Session与Cookie
		1,Java操作Session Java操作Session非常简单,步骤如下 1.1,在servlet中通过request获取session HttpSession session = request ... 
- 关于使用struts2时子窗体页面跳转后在父窗体打开的问题以及Session过期后的页面跳转问题
		问题1:传统的系统界面,iframe了三个页面,上,左,右,用户点击注销的按钮在上面得top.jsp里面,方法:<a href="../adminAction/admin_logout ... 
- js--Ajax的小知识(二):处理ajax的session过期的请求
		问题的产生: 现如今Ajax在Web项目中应用广泛,几乎可以说无处不在. 有时会碰到这样个问题:当Ajax请求遇到Session超时,应该怎么办? 显而易见,传统的页面跳转在此已经不适用,因为Ajax ... 
- session过期时间
		在一般系统登录后,都会设置一个当前session失效的时间,以确保在用户没有使用系统一定时间后,自动退出登录,销毁session. 具体设置很简单: 在主页面或者公共页面中加入:session.set ... 
- MVC 访问IFrame页面Session过期后跳转到登录页面
		Web端开发时,用户登录后往往会通过Session来保存用户信息,Session存放在服务器,当用户长时间不操作的时候,我们会希望服务器保存的Session过期,这个时候,因为Session中的用户信 ... 
- asp.net web.config 设置Session过期时间
		在Asp.net中,可以有四处设置Session的过期时间:(原文作者:望月狼地址:http://www.cnblogs.com/wangyuelang0526/) 一.全局网站(即服务器)级 IIS ... 
- Senparc.Weixin.MP SDK 微信公众平台开发教程(七):解决用户上下文(Session)问题
		从这篇文章中我们已经了解了微信公众平台消息传递的方式,这种方式有一个先天的缺陷:不同用户的请求都来自同一个微信服务器,这使得常规的Session无法使用(始终面对同一个请求对象,况且还有对方服务器Co ... 
- [转]菜鸟程序员之Asp.net MVC Session过期异常的处理
		本文转自:http://www.cnblogs.com/JustRun1983/p/3377652.html 小赵是刚毕业的计算机专业方面的大学生,4年的大学时间里面,他读过了很多编程方面的数据,也动 ... 
随机推荐
- 基于uniGui开发的Delphi后台管理框架uniFramework
			uniGui是基于Delphi的一套开发Web应用的UI框架,前端使用的是ExtJS,最新版的uniGUI1.5 1480已支持新版的ExtJS6.5.3.我认为uniGUI是目前Delphi下最完善 ... 
- DeepCTR专题:DeepFM论文学习和实现及感悟
			论文地址:https://arxiv.org/pdf/1703.04247.pdf CTR预估我们知道在比较多的应用场景下都有使用.如:搜索排序.推荐系统等都有广泛的应用.并且CTR具有极其重要的 地 ... 
- db2 常见错误以及解决方案[ErrorCode SQLState]
			操作数据库流程中,遇到许多疑问,很多都与SQL CODE和SQL State有关,现在把一个完整的SQLCODE和SQLState不正确信息和有关解释作以下说明,一来可以自己参考,对DB2不正确自行找 ... 
- NIO 概述 与 通信实例
			NIO 简述: NIO是在jdk1.4之后加入的一种基于缓冲区(buffer)和通道(channel)的I/O方式, nio是同步非阻塞的i/o模式,同步是指线程不断地轮询i/o事件,非阻塞是在处理i ... 
- 在Servlet中获取spring容器WebApplicationContext
			WebApplicationContext springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(ge ... 
- win7安装python3.6.1及scrapy
			---恢复内容开始--- 第一篇博客,记录自己自学python的过程及问题. 首先下载python3.6.1及所需资料 百度云:https://pan.baidu.com/s/1geOEp6z 密码: ... 
- Hadoop学习------Hadoop安装方式之(二):伪分布部署
			要想发挥Hadoop分布式.并行处理的优势,还须以分布式模式来部署运行Hadoop.单机模式是指Hadoop在单个节点上以单个进程的方式运行,伪分布模式是指在单个节点上运行NameNode.DataN ... 
- div嵌套,常见左右分类栏目
			最终效果图如下: html代码如下: <div class="smalItem"> <div class="leftnav"> < ... 
- Python_在Ubuntu中搭建科学计算环境
			本文针对 Ubuntu 下搭建 Python 科学计算的环境,罗列了关键词和部分链接,最后附上了自己的一点分享. 1.升级 关键词: python ubuntu 升级 推荐: ubuntu16.04下 ... 
- dubbo could not get local host ip address will use 127.0.0.1 instead 异常处理
			dubbo could not get local host ip address will use 127.0.0.1 instead 查看hostname localhost:spring wls ... 
