This article mainly introduces the use of session listening in Java to achieve login restrictions and number of logins for the same account. The specific code is as follows:
Problem domain:
1. Log in with the same account: If this account is already logged in, you cannot log in again (the opposite to QQ mode).
2. If the number of logged in is limited, if the number of people exceeds or has been reached, the prompt is: the system is busy, try again later.
Solution: Use the HttpSessionAttributeListener listener (although I used the HttpSessionListener at the same time, it feels difficult to operate)
Knowledge reserve: HttpSessionAttributeListener has three methods: attributeAdd, attributeRemove, and attributeReplace.
The setAttribute and removeAttribute of the session will trigger the attributeAdd and attributeRemove methods. Repeated settings of the same attribute of the same session will trigger the attributeReplace method.
The reason why HttpSessionListener is difficult to operate: as long as you access the jsp page, you will create a session (you will not create a session when accessing the html. On the server side, for example, if you call HttpServletRequest.getSession(true) in the servlet, you will create it). Jsp is a dynamic page, and is essentially a servlet. My login.jsp is obviously a jsp. When I invalidate a session in the listener and return to the login page, I immediately created another session. This is something I don’t feel clear about, and I haven’t gotten home from my skills.
Specific implementation:
Listener code
public class OnlineListener implements HttpSessionListener, HttpSessionAttributeListener { private static List<SessionAndUser> sessions; static int delS = -1; static boolean flag = false; static { if (sessions == null) { sessions = Collections .synchronizedList(new ArrayList<SessionAndUser>()); } } public void sessionCreated(HttpSessionEvent hse) { System.out.println(hse.getSession() + "-" + new Date()); System.out.println(hse.getSession() + "-" + new Date()); } public void sessionDestroyed(HttpSessionEvent hse) { System.out.println("-------------sessionDestroyed()-----------"); System.out.println(hse.getSession() + " " + new Date(hse.getSession().getLastAccessedTime())); System.out.println(hse.getSession() + " " + new Date()); } public void attributeAdded(HttpSessionBindingEvent e) { System.out.println("-------------*start added*-----------------------" + sessions.size()); HttpSession session = e.getSession(); ActionContext ctx = ActionContext.getContext(); boolean newOne = true; String attrName = e.getName(); // Log in if (attrName.equals(Constant.USER_NAME)) { // Check the number of logins if (sessions.size() >= Constant.USER_LIMIT) { newOne = false; ctx.put("timeoutMSG", "serverBusy"); } String nowUser = (String) e.getValue(); // Traverse all sessions to check whether you have logged in. If so, it prompts that you have logged in for (int i = sessions.size() - 1; i >= 0; i--) { SessionAndUser tem = sessions.get(i); if (tem.getUserName().equals(nowUser)) { newOne = false; ctx.put("timeoutMSG", "beenLoged");// tem.getSession().invalidate();// // Log in with the same account and automatically call remove break; } } // Add the new login account to the account maintenance list if (newOne) { SessionAndUser sau = new SessionAndUser(); sau.setUserName(nowUser); sau.setSession(session); sau.setSid(session.getId()); sessions.add(sau); } } } public void attributeRemoved(HttpSessionBindingEvent e) throws IllegalStateException { HttpSession session = e.getSession(); System.out .println("-------------*start Removed*-----------------------" + sessions.size()); if (delS > -1) { if (flag) { sessions.remove(delS); flag = false; } } else { // 登录String attrName = e.getName(); if (attrName.equals(Constant.USER_NAME)) { String nowUser = (String) e.getValue(); // traverse all sessions for (int i = sessions.size() - 1; i >= 0; i--) { SessionAndUser tem = sessions.get(i); if (tem.getUserName().equals(nowUser)) { sessions.remove(i); break; } } } } } public void attributeReplaced(HttpSessionBindingEvent e) { HttpSession session = e.getSession(); System.out .println("-------------*start replace*-----------------------" + sessions.size()); String attrName = e.getName(); delS = -1; // 登录if (attrName.equals(Constant.USER_NAME)) { // User nowUser = (User) e.getValue();//old value String nowUser = (String) session.getAttribute(Constant.USER_NAME);// 当前session中的user // traverse all sessions for (int i = sessions.size() - 1; i >= 0; i--) { SessionAndUser tem = sessions.get(i); if (tem.getUserName().equals(nowUser) && !tem.getSid().equals(session.getId())) { System.out.println("Remove:invalidate 1!"); delS = i; flag = true; } else if (tem.getSid().equals(session.getId())) { tem.setUserName(nowUser); } } if (delS != -1) { sessions.get(delS).getSession().invalidate();// The remove method is automatically called when it fails. It will also be removed from sessions} } }} The main idea of the code is to define a static List<SessionAndUser> to store session and account name.
The code to get the listener return value and process it in the logged-in Action
session.setAttribute(Constant.USER_NAME, operator.getUsername()); ActionContext ctx = ActionContext.getContext(); if("serverBusy".equals(ctx.get("timeoutMSG"))){ ctx.put("timeoutMSG", "The server is busy, please try again later"); return "jump"; } if("beenLoged".equals(ctx.get("timeoutMSG"))){ ctx.put("timeoutMSG", "This account is logged in elsewhere"); return "jump"; } Page capture prompt information code
<%@taglib prefix="s" uri="/struts-tags"%><s:property value="#attr.timeoutMSG" />
Thank you for reading, I hope it can help you. Thank you for your support for this site!