In java web, only one location can be logged on to the same account at a time (similar to QQ login)

Source: Internet
Author: User

I haven't logged on to my blog for many days. Recently, some netizens asked me how to implement the QQ login function in java web. The same account cannot log on to two computers at the same time.

I. What is the function?

Think about it. There will always be such a demand. There will be no demand in this year .. Haha. Sometimes it is not necessarily a requirement. It is very likely that this will also be done for security. Such as the examination system and online chat system.

II. Implementation Process

A. Problem Analysis

In the system, we usually bind the login information to the session. It seems that the solution may be found here. To put it bluntly, when the user logs on, it determines whether the user has logged on. If the user logs on, it is OK to clear the previous session .. Does it seem simple? As a matter of fact, you will find the following problems: how can you obtain the information about the previous user's logon, that is, how to access all the logged-on sessions?

B. Specific implementation

As you know, there seems to be no specific method in j2ee api to directly obtain all session information. However, you can configure listeners to monitor the creation, deletion, and replacement of all sessions, as well as the creation, deletion, and replacement of attributes in sessions.

In fact, we only need to do the following:

When saving the user login information to the session, attributeAdded refers to the creation process of a session attribute, which records the current session to an ArrayList.

In fact, when saving to the list, you must first traverse whether the user's logon information already exists in the list. If yes, the session information in the list will be destroyed and removed from the list. If no session information exists, the session information will be placed in the list.

When the session login information is destroyed, the sesseion is directly removed from the list.

In addition, when a user does not log on and does not log on directly, This is a session attribute replacement process. It also needs to be processed to determine whether a new user exists in other sessions except the current session. If yes, delete it.

The 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 ();

// Log on
If (attrName. equals (loginFlag )){
User nowUser = (User) e. getValue ();
User sUser = (User) session. getAttribute (loginFlag );
// Traverse all sessions
For (int I = sessions. size ()-1; I> = 0; I --){
SessionAndUser tem = sessions. get (I );
If (tem. getUserID (). equals (nowUser. getName ())){
Tem. getSession (). invalidate (); // automatically call remove
Break;
}
}

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 ();
// Log on
If (attrName. equals (loginFlag )){
User nowUser = (User) e. getValue ();
// Traverse all sessions
For (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;
// Log on
If (attrName. equals (loginFlag )){
// User nowUser = (User) e. getValue (); // old value
User nowUser = (User) session. getAttribute (loginFlag); // the user in the current session
// Traverse all sessions
For (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 it becomes invalid. It will also remove it from sessions
}

}
}

Public void sessionCreated (HttpSessionEvent e ){
}

Public void sessionDestroyed (HttpSessionEvent e ){
}

}

Preparation in web. xml

1   <listener>
2 <display-name>recordSession</display-name>
3 <listener-class>com.weirhp.RecordSessionListener</listener-class>
4 </listener>
Iii. Code Testing

Source code download

Iv. Possible Problems

The whole program may not be thought. There may be some bugs. Be cautious when using them for specific projects. You are welcome to make some suggestions. I will try again.

5. later thoughts

If two machines use the same account to log on to the system at the same time, can both accounts successfully log on .. (When the session List is large, two machines may log on to the system at the same time using the same account in the traversal period ). Very tangled .. How should we control it?

(Solution: the Listener is a singleton in the system. The thread security of the list can be ensured by adding the synchronize keyword to the Listener method .)

This article is original author, reproduced please indicate the source http://www.cnblogs.com/weirhp/archive/2011/05/08/sesssionlistener.html

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.