java保持同一时间同一账号只能在一处登录
//登录页面 login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="./js/jquery-3.5.1.min.js"></script> <script type="text/javascript" src="./js/vue.js"></script> <title>登录</title> <% String msg = (String)(request.getAttribute("msg")==null?"":request.getAttribute("msg")); %> <script type="text/javascript"> function show(){ if('<%=msg%>'!=''){ alert('<%=msg%>'); } } </script> </head> <body style="text-align: center" οnlοad="show();"> <form action="${pageContext.request.contextPath}/login.do" method="post"> <table border="1"> <tr> <td align="center" colspan="2"> <h3>用户登录</h3> </td> </tr> <tr> <td align="right"> 用户名 </td> <td align="left"> <input type="text" id="userName" name="userName"> </td> </tr> <tr> <td align="right"> 密 码 </td> <td align="left"> <input type="password" id="password" name="password"> </td> </tr> <tr> <td align="center" colspan="2"> <input type="submit" value="登录"> <input type="reset" value="重置"> </td> </tr> </table> </form> </body> </html>
//主页面 main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>登录成功</title> <script type="text/javascript" src="./js/jquery-3.5.1.min.js"></script> <script type="text/javascript" src="./js/vue.js"></script> </head> <% response.setHeader("Pragma","No-cache"); response.setHeader("Cache-Control","No-cache"); response.setDateHeader("Expires", -1); response.setHeader("Cache-Control", "No-store"); String userName = ""; userName = (String)(session.getAttribute("userName")==null?"":session.getAttribute("userName")); %> <script type="text/javascript"> var count; var userMsg = ''; var i =0; function checkUserOnline(){ $.ajax({ type:"post", url:"${pageContext.request.contextPath}/checkUserOnline.do", dataType : "text", success:function(data){ userMsg = data; //alert(JSON.stringify(userMsg)) }, error:function(){ alert("获取用户信息失败!"); clearInterval(count); reLogin(); } }); if(userMsg=='null'||userMsg==''|| userMsg == 'undefined'){ return; }else{ //alert(JSON.stringify(userMsg)); clearInterval(count); reLogin(); } } function reLogin(){ window.location = "login.jsp"; } function checkLogin(){ alert("检查"); count = setInterval("checkUserOnline()",5000); } </script> <body onclick="checkLogin()"> <% if(!"".equals(userName)){ out.print("登陆成功!<br/>用户名:<span id='userName'>"+userName+"</span><br/><input type='button' value='重新登陆' οnclick='reLogin();'/>"); } %> </body> </html>
//控制类 LoginController
package com.zjn.oneLogin.dengLu; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class LoginController{ /** * 用户和Session绑定关系 */ public static final Map<String, HttpSession> USER_SESSION = new HashMap<String, HttpSession>(); /** * seeionId和用户的绑定关系 */ public static final Map<String, String> SESSIONID_USER = new HashMap<String, String>(); @RequestMapping("/login") @ResponseBody public Map<String,Object>toLogin(HttpServletRequest request, HttpServletResponse response) throws Exception{ //获取请求命令 request.setCharacterEncoding("utf-8"); String servletPath = request.getServletPath();//获取请求路径 String uri = servletPath.substring(1, servletPath.lastIndexOf(".do")); try{ //登录 if ("login".equals(uri)){ HttpSession session = request.getSession(); String userName = request.getParameter("userName"); String password = request.getParameter("password"); if (userName != null && !"".equals(userName.trim())){ //登录成功 if (login(userName, password)){ //处理用户登录(保持同一时间同一账号只能在一处登录) userLoginHandle(request); //添加用户与HttpSession的绑定 USER_SESSION.put(userName.trim(), session); //添加sessionId和用户的绑定 SESSIONID_USER.put(session.getId(), userName); System.out.println("添加sessionId和用户的绑定 ==="+session.getId()); System.out.println("用户[" + userName + "] 已上线..."); session.setAttribute("userName", userName); session.removeAttribute("userMsg");//从session中移除用户信息 //重定向到首页 response.sendRedirect("main.jsp"); } //登录失败 else{ System.out.println("用户[" + userName + "] 登录失败..."); request.setAttribute("msg", "登录失败,请重新登录!"); //response.sendRedirect("login.jsp"); request.getRequestDispatcher("login.jsp").forward(request, response); } } else{ System.out.println("用户[" + userName + "] 登录失败..."); request.setAttribute("msg", "登录失败,请重新登录!"); //response.sendRedirect("login.jsp"); request.getRequestDispatcher("login.jsp").forward(request, response);//跳转到用户页面,返回请求响应对象 } }else if ("reLogin".equals(uri)){ //重新登陆 HttpSession session = request.getSession(); String userName = (String)session.getAttribute("userName"); if (session != null){ //销毁相关session //USER_SESSION.remove(SESSIONID_USER.remove(session.getId())); session.invalidate(); } if (userName != null && !"".equals(userName)){ System.out.println("用户[" + userName + "] 已下线..."); } //重定向到登录页面 response.sendRedirect("login.jsp"); } } catch (Exception e){ System.out.println(e.getClass() + e.getMessage()); PrintWriter out = response.getWriter(); out.print("服务器内部错误!"); } return null; } /** * * Description:用户登录时的处理 <br> * @param request * @see */ private void userLoginHandle(HttpServletRequest request){ //当前登录的用户 String userName = request.getParameter("userName"); System.out.println("userName=="+userName); //当前sessionId //String sessionId = request.getSession().getId(); //删除当前sessionId绑定的用户,用户--HttpSession //USER_SESSION.remove(SESSIONID_USER.remove(sessionId)); //删除当前登录用户已绑定的HttpSession HttpSession session = USER_SESSION.remove(userName);//map中的remove方法返回删除value值 if (session != null){ //删除已登录的sessionId绑定的用户 SESSIONID_USER.remove(session.getId()); session.removeAttribute("userName"); session.setAttribute("userMsg", "您的账号已经在另一处登录,您被迫下线!"); } } /** * * Description: 模拟DB登录判断<br> * @param userName 用户 * @param password 密码 * @return * @see */ private boolean login(String userName, String password){ return ("peizhongxian".equals(userName) && "123456".equals(password)); } /** * 判断用户是否同时登陆同一个用户 * * */ @RequestMapping(value="/checkUserOnline") @ResponseBody public void checkUserOnline(HttpServletRequest request,HttpServletResponse response) throws IOException{ HttpSession session=request.getSession(); PrintWriter out = response.getWriter(); out.print(session.getAttribute("userMsg")); } }
//监听器 MyListener
package com.zjn.oneLogin.dengLu; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class MyListener implements HttpSessionListener { /** * 实现HttpSessionListener接口监听 监听session的创建事件 */ public void sessionCreated(HttpSessionEvent se){ String sessionId = se.getSession().getId(); System.out.println("创建session sessionId= " + sessionId); } /** * 实现HttpSessionListener接口监听 监听session的销毁事件 */ public void sessionDestroyed(HttpSessionEvent se){ String sessionId = se.getSession().getId(); System.out.println("sessionId========="+sessionId); //当前session销毁时删除当前session绑定的用户信息 //同时删除当前session绑定用户的HttpSession LoginController.USER_SESSION.remove(LoginController.SESSIONID_USER.remove(sessionId)); System.out.println("销毁session sessionId= " + sessionId); } }
//web.xml 文件
<listener> <listener-class>com.zjn.oneLogin.dengLu.MyListener</listener-class> </listener>