In the current web project, many situations are that the same account information can be logged in at different login portals this time, so it will not be so beautiful.
Recommended reading:
Implementation of Java multi-user login restrictions
There are now two solutions:
1. Save the user's login information with a field in a flag. Each time the login is successful, it is marked 1, and the login is marked 0. When it is marked 1, it is not allowed to log in.
2. Save the user's login information in the built-in scope of the application, and then use the session listener to monitor the login status of each logged-in user.
Obviously, the first method requires operating the database every time you log in, which adds some unnecessary performance overhead. Moreover, if the computer suddenly shuts down during the login state, you will never be able to log in, and the usability is relatively low.
But the second method is different, it is highly operable and convenient to maintain the information of all online users.
Next, we will mainly introduce the specific implementation of the second method:
1. In the login method for processing login, first query the database to verify whether the user exists. If there is, determine whether the login account has been locked. Then take out all login information from the application built-in scope object to check whether the username account has been logged in. If it is logged in, it will be a friendly prompt. Otherwise, it means that you can log in and save the login information in the application in the form of a key-value pair.
The code is as follows:
//Action must be added to each access method before zero configuration, otherwise 404 @Action(value="login", results={ @Result(name="index", location="index.jsp"), }) public String login() throws Exception { try{ User result = userService.login(user.getFuUserName(), user.getFuPassword()); if(result!=null){ if(result.getFuStatus()!=null && result.getFuStatus()==0){ super.setRequestAttr(Constant.MESSAGE, "Sorry, this user has been locked!"); return "error"; } Map<String, String> loginUserMap = (Map<String, String>) super.getApplicationAttr(Constant.LOGIN_USER_MAP); boolean isExist = false; String sessionId = super.getSessionId(false); if(loginUserMap==null){ loginUserMap = new HashMap<String, String>(); } for (String username: loginUserMap.keySet()) { //Judge whether the logged-in user's information has been saved or if the same user has repeatedly logged in, then login is allowed if(!username.equals(result.getFuUserName()) || loginUserMap.containsValue(sessionId)){ continue; } isExist = true; break; } if(isExist){ super.setRequestAttr(Constant.MESSAGE, "Sorry, the user is logged in!"); return "error"; }else { loginUserMap.put(result.getFuUserName(), sessionId); } //Login successfully super.setSessionAttr(Constant.LOGIN_USER, result); super.setApplicationAttr(Constant.LOGIN_USER_MAP, loginUserMap); logger.info(result.getFuUserName() + "Login successfully! "); //If fromUrl has a value in the session, jump to the page String fromUrl = (String)super.getSessionAttr(Constant.FROM_URL); if(fromUrl!=null){ super.setSessionAttr(Constant.FROM_URL, null); super.getResponse().sendRedirect(fromUrl.toString()); return null; } return "index"; } } catch (Exception e) { e.printStackTrace(); logger.info("Login failed: "+e.getMessage()); } super.setRequestAttr("message", "error"); return "error"; }2. After the login portal is processed, considering that the session ends, the corresponding login user should also log out of the login accordingly. We can write a Session listener. When the session is destroyed, we logged out the logged-in user, that is, remove it from the application. It means that the user has been offline.
The code is as follows:
package com.facelook.util; import java.util.Map; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import org.apache.log4j.Logger; import com.facelook.entity.User; public class SessionListener implements HttpSessionListener{ private Logger logger = Logger.getLogger(this.getClass()); @Override public void sessionCreated(HttpSessionEvent event) { } @Override public void sessionDestroyed(HttpSessionEvent event) { //Clear the key value pairs saved in loginUserMap when the session is destroyed User user = (User)event.getSession().getAttribute("loginUser"); if(user!=null){ Map<String, String> loginUserMap = (Map<String, String>)event.getSession().getServletContext().getAttribute("loginUserMap"); loginUserMap.remove(user.getFuUserName()); event.getSession().getServletContext().setAttribute("loginUserMap",loginUserMap); } } }The configuration in web.xml is as follows:
<!-- session listener --> <listener> <listener-class>com.facelook.util.SessionListener</listener-class> </listener>
3. In addition, there is another problem. If the logged in user suddenly closes the browser or page without clicking the logout button. Then you can use the beforeunload event to fire when the browser refreshes or closes.
//Events $(window).bind('beforeunload',function(){ $.ajax({ url:"${ctx}/system/user/user!logout.action", type:"post", success:function(){ alert("You have logged out"); } }); );However, if some objective reasons, such as the computer suddenly shut down, automatic restart, etc., these cannot be avoided, so you can only wait for the server-side session session to reset before you can log in again.
Unless it is a module that counts all online personnel, the administrator manages the login and logout status of online personnel, and directly destroys those logged in users with problems.
Next, let’s briefly introduce the management of online personnel modules:
1. First, a session listener is needed to monitor all reply create situations. At this time, every time a session is created, count+1 can be counted, and then count-1 is destroyed. In addition, a ServletContext listener is needed to monitor the life cycle of the web application, obtain the servletContext object, and then count the total number of online personnel and store it in;
The specific code is as follows:
package com.facelook.util; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import javax.servlet.http.HttpSessionListener; import org.apache.log4j.Logger; import com.facelook.entity.User; public class SessionListener implements HttpSessionListener,ServletContextListener{ private int count; private ServletContext servletContext = null; public SessionListener() { count = 0; } private Logger logger = Logger.getLogger(this.getClass()); @Override public void sessionCreated(HttpSessionEvent event) { count++; setContext(event); logger.info("************ the http session is created...******************"); } @Override public void sessionDestroyed(HttpSessionEvent event) { //Clear the key value pairs saved in loginUserMap when the session is destroyed User user = (User)event.getSession().getAttribute("loginUser"); if(user!=null){ Map<String, String> loginUserMap = (Map<String, String>)event.getSession().getServletContext().getAttribute("loginUserMap"); loginUserMap.remove(user.getFuUserName()); event.getSession().getServletContext().setAttribute("loginUserMap",loginUserMap); } count--; setContext(event); logger.info("************ the http session is destroyed...*********************"); } public void setContext(HttpSessionEvent httpSessionEvent){ httpSessionEvent.getSession().getServletContext().setAttribute("online", count); } @Override public void contextDestroyed(ServletContextEvent servletcontextevent) { this.servletContext = null; logger.info("************ the servlet context is destroyed...*********************"); } @Override public void contextInitialized(ServletContextEvent servletcontextevent) { this.servletContext = servletcontextevent.getServletContext(); logger.info("************ the servlet context is initialized...******************"); } }2. Create a module to manage online users in UserAction and support the forced exit function;
/** * Logout* @return * @throws ServletException * @throws IOException */ public String logout() throws ServletException, IOException{ try { Map<String, String> loginUserMap = (Map<String, String>) super.getApplicationAttr(Constant.LOGIN_USER_MAP); User user = (User) super.getSessionAttr(Constant.LOGIN_USER); super.removeAttribute(Constant.LOGIN_USER_MAP); loginUserMap.remove(user.getFuUserName()); super.setApplicationAttr(Constant.LOGIN_USER_MAP,loginUserMap); logger.info("Login login successful!"); } catch (Exception e) { e.printStackTrace(); logger.error("Login failed: "+e.getMessage()); } return INPUT; } /** * Online user management* @return */ public String loginManager(){ return SUCCESS; } /** * Force exit from other users* @return */ public String logoutOther(){ try { String username = ServletActionContext.getRequest().getParameter("username"); Map<String, String> loginUserMap = (Map<String, String>) super.getApplicationAttr(Constant.LOGIN_USER_MAP); if(username!=null && loginUserMap.containsKey(username)){ loginUserMap.remove(username); super.setApplicationAttr(Constant.LOGIN_USER_MAP, loginUserMap); } } catch (Exception e) { e.printStackTrace(); logger.info("Forcibly exit failed: "+e.getMessage()); } return null; }3. Load the list of online users on the management page;
After the corresponding method is defined, then add an online list to the corresponding management page, as follows:
<%@page import="java.util.Map"%> <%@page import="java.util.Map.Entry"%> <%@page language="java" pageEncoding="UTF-8" %> <%@ include file="/common/taglib.jsp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Welcome to Facelook</title> <%@ include file="/common/resource.jsp" %> <script type="text/javascript"> <!-- // Events $(window).bind('beforeunload',function(){ $.ajax({ url:"${ctx}/system/user/user!logout.action", type:"post", success:function(){ alert("You have logged out"); } }); }); function logout(username){ if(username=="${sessionScope.loginUser.fuUserName}"){ alert("Logout of your account!"); return; } $.ajax({ url:"${ctx}/system/user/user!logoutOther.action?username="+username, type:"post", success:function(){ $("#tr"+username).hide(); var count = parseInt($("#count").html()); $("#count").html(count-1); alert("Exit successfully! "); } } }); } //--> </script> </head> <body> <%@ include file="/common/header.jsp" %> <div id="main"> <%@ include file="/common/lefter.jsp" %> <div> <div> <h2>Login List</h2> <%Map<String,String> map = (Map<String,String>)application.getAttribute("loginUserMap"); out.println("Currently there are <font id='count'>"+map.size()+"</font> users online!!"); %> <table> <%for(Entry<String,String> m : map.entrySet()){%> <tr id="tr<%=m.getKey()%>"> <td> <%=m.getKey()%> </td> <td> <a href="javascript:logout('<%=m.getKey()%>')">Force exit</a> </td> </tr> <%}%> </table> </div> </div> </div> <%@ include file="/common/footer.jsp" %> <%@ include file="/common/message.jsp" %> </body> </html>OK, start the deployment project, then start the service, and enter the online user management module. The simple effect is as follows:
It should be noted that the current login user is not allowed to force log out of his/her login information.
In this way, cases of preventing multiple users from logging in can basically be realized!
The above is the perfect solution for Java Web development to prevent multiple users from logging in repeatedly. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support to Wulin.com website!