The implementation idea of JavaWeb that can only log in at one place at the same time (similar to the QQ login function) is as follows:
1. What is the function of this function?
Everyone think about it. Anyway, there will always be such a demand. There will be no demand these days. . hehe. Sometimes it may not be a requirement, and it is very likely that it will also do so for safety. For example, the examination system and the online chat system are necessary to do this.
2. Implementation process
a. Problem analysis
In the system, we usually bind the login information to the session. It seems that starting from this is possible to find a solution. To put it bluntly, when the user logs in, determine whether the user is logged in. If he logs in, it will be OK to clear the previous session. . It seems very simple, right? In fact, if you think about it carefully, you will find the following problem: How to get the user has logged in before, that is, how to access all logged in session information?
b. Specific implementation
As we all know, there seems to be no specific method to directly obtain all session information in the j2ee API. But we can monitor all session creation and destruction processes by configuring listeners, as well as monitor the creation, deletion and replacement processes of attributes in the session.
In fact, we just need to do the following:
When saving user login information to session, the corresponding session is the attributeAdded process of creating an attribute, which can record the current session into an ArrayList.
In fact, when saving it to the list, you must first traverse whether there is the login information of the user already exists in this list. If it exists, destroy the session information present in this list and remove it from the list. If it does not exist, put the session information into the list.
When the session's login information is destroyed, remove the session from the list directly.
Also, when the user logs in without logging out and logs directly, this is a process of replacing the session attribute. It is also necessary to determine whether the new user already exists in other sessions besides the current session. If it exists, delete it.
The specific code is as follows:
package com.weirhp;import java.util.ArrayList;import java.util.Collections;import java.util.List;import javax.servlet.http.HttpSession;import javax.servlet.http.HttpSessionAttributeListener;import javax.servlet.http.HttpSessionBindingEvent;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;public class RecordSessionListener implements HttpSessionAttributeListener,HttpSessionListener {private static List<SessionAndUser> sessions;public static String loginFlag = "loginUser";static {if (sessions == null) {sessions = Collections.synchronizedList(new ArrayList<SessionAndUser>());}}public void attributeAdded(HttpSessionBindingEvent e) {HttpSession session = e.getSession();System.out.println("-------------*start added*-----------------------");String attrName = e.getName();// 登录if (attrName.equals(loginFlag)) {User nowUser = (User) e.getValue();User sUser = (User)session.getAttribute(loginFlag);// 遍历所有sessionfor (int i = sessions.size()-1; i >= 0; i--) {SessionAndUser tem = sessions.get(i);if (tem.getUserID().equals(nowUser.getName())) {tem.getSession().invalidate();//Automatically call removebreak;}}SessionAndUser sau = new SessionAndUser();sau.setUserID(nowUser.getName());sau.setSession(session);sau.setSid(session.getId());sessions.add(sau);}}public void attributeRemoved(HttpSessionBindingEvent e) {HttpSession session = e.getSession();System.out.println("-------------*start Removed*-----------------------");String attrName = e.getName();// 登录if (attrName.equals(loginFlag)) {User nowUser = (User) e.getValue();// 遍历所有sessionfor (int i = sessions.size()-1; i >= 0; i--) {SessionAndUser tem = sessions.get(i);if (tem.getUserID().equals(nowUser.getName())) {sessions.remove(i);break;}}}}public void attributeReplaced(HttpSessionBindingEvent e) {HttpSession session = e.getSession();System.out.println("-------------*start replace*-----------------------");String attrName = e.getName();int delS=-1;// 登录if (attrName.equals(loginFlag)) {// User nowUser = (User) e.getValue();//old valueUser nowUser = (User)session.getAttribute(loginFlag);//The user in the current session//traverses all sessionfor (int i = sessions.size()-1; i >= 0; i--) {SessionAndUser tem = sessions.get(i);if (tem.getUserID().equals(nowUser.getName())&&!tem.getSid().equals(session.getId())) {System.out.println("Remove:invalidate 1!");delS=i;}else if(tem.getSid().equals(session.getId())){tem.setUserID(nowUser.getName());}}if (delS!=-1) {sessions.get(delS).getSession().invalidate();//The remove method is automatically called when invalidated. It will also be removed from the sessions}}}public void sessionCreated(HttpSessionEvent e) {}public void sessionDestroyed(HttpSessionEvent e) {}}Formulation in web.xml
<listener><display-name>recordSession</display-name><listener-class>com.weirhp.RecordSessionListener</listener-class></listener>
3. Possible problems
There may be some things that the entire program did not expect. There may be some bugs, and you need to be cautious when used in specific projects. Everyone is welcome to make a picture and hope to give some suggestions. I'll improve it again.
4. Some thoughts later
If both machines use the same account to log in to the system at the same time, can both accounts be logged in successfully? . (Also, when this session List is very large, two machines may log in successfully when logging in to the system using the same account at the same time during the traversal period). Very entangled. . How should it be controlled?
(Solution: After testing, Listener is a singleton in the system. Adding the synchronize keyword to its method can ensure the thread safety of the list.)
The above is the JavaWeb introduced to you that the editor can only log in at one place at the same time (similar to the QQ login function). 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!