La idea de implementación de Javaweb que solo puede iniciar sesión en un lugar al mismo tiempo (similar a la función de inicio de sesión QQ) es la siguiente:
1. ¿Cuál es la función de esta función?
Todos piensan en ello. De todos modos, siempre habrá una gran demanda. No habrá demanda en estos días. . jeje. A veces puede no ser un requisito, y es muy probable que también lo haga por seguridad. Por ejemplo, el sistema de examen y el sistema de chat en línea son necesarios para hacerlo.
2. Proceso de implementación
a. Análisis de problemas
En el sistema, generalmente vinculamos la información de inicio de sesión a la sesión. Parece que comenzar a partir de esto es posible encontrar una solución. Para decirlo sin rodeos, cuando el usuario inicie sesión, determine si el usuario ha iniciado sesión. Si inicia sesión, estará bien para borrar la sesión anterior. . Parece muy simple, ¿verdad? De hecho, si lo piensa cuidadosamente, encontrará el siguiente problema: cómo obtener el usuario ha iniciado sesión antes, es decir, cómo acceder a toda la información de sesión registrada en la sesión.
b. Implementación específica
Como todos sabemos, parece que no hay un método específico para obtener directamente toda la información de la sesión en la API J2EE. Pero podemos monitorear todos los procesos de creación y destrucción de la sesión configurando los oyentes, así como monitorear los procesos de atributos de creación, eliminación y reemplazo de atributos en la sesión.
De hecho, solo necesitamos hacer lo siguiente:
Al guardar la información de inicio de sesión del usuario en la sesión, la sesión correspondiente es el proceso atributado de crear un atributo, que puede registrar la sesión actual en una lista de matrices.
De hecho, al guardarlo en la lista, primero debe atravesar si existe la información de inicio de sesión del usuario en esta lista. Si existe, destruya la información de la sesión presente en esta lista y elimínela de la lista. Si no existe, coloque la información de la sesión en la lista.
Cuando se destruya la información de inicio de sesión de la sesión, elimine la sesión de la lista directamente.
Además, cuando el usuario inicia sesión sin iniciar sesión y registra directamente, este es un proceso de reemplazar el atributo de sesión. También es necesario determinar si el nuevo usuario ya existe en otras sesiones además de la sesión actual. Si existe, elimínelo.
El código específico es el siguiente:
paquete com.weirhp; import java.util.arrayList; import java.util.collections; import java.util.list; import javax.servlet.http.httpsession; import javax.servlet.http.htttpsessionattributelistener; import javax.servlet.servlet.httttpsession javax.servlet.http.httpSessionEvent; import javax.servlet.http.httpsessionListener; public class RegistrossionSessionListener implementa httpsessionatTributEntener, httpsessionListener {Lista estática privada <SessionandUser> Sessions; Public Static Stringflag = "Loginuser"; null) {sessions = collections.synChronizedList (new ArrayList <sessionandUser> ());}} public void attributeadDed (httpsessionBindingEvent e) {httpsession session = e.getSession (); system.println ("--------------*comienza*-----------------------------");登录 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 (); // Llame automáticamente a RemoBreak;}} SessionAndUser Sau = nuevo SessionAndUser (); sau.setUserId (NowUser.getName ()); Sau.setsession (session); Sau.setsid (session.getId ()); sessions.add (sau);}} public void atributereMoved (httpsessionbindingevent) {session de httpsession = session = E.getSession (); System.out.println ("-------------*Comience a eliminar*-----------------------"); 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 atributeRePlaced (httpsessionbindingevent e) {HttpSession Session = E.GetSession (); System.out.println ("-------------*Iniciar reemplazo*-----------------------"); String attrName = e.getName (); int dels = -1; // 登录 if (attrname.equals (loginflag)) {// user nowuser = (user) e.getvalue (); // antiguo valor nowuser = = = = = = (Usuario) session.getAttribute (loginflag); // El usuario en la sesión actual // atraviesa todo 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 ("Eliminar: invalidar 1!"); dels = i;} else if (tem.getSid (). Equals (session.getId ())) {tem.SetUserId (NowUser.getName ());}} if (dels! =-1) {sessions.get (dels) .getSession (). Invalidate (); // El método de eliminación se llama automáticamente cuando se invalidan. También se eliminará de las sesiones}}} public void session created (httpsessionEvent e) {} public void sessionDestroyed (httpsessionEvent e) {}}Formulación en web.xml
<Oyerer> <Spant-Name> Recordsession </Display-Name> <Oyerer-class> com.weirhp.RecordSessionListener </oyearclass> </oyente>
3. Posibles problemas
Puede haber algunas cosas que todo el programa no esperaba. Puede haber algunos errores, y debe ser cauteloso cuando se usa en proyectos específicos. Todos son bienvenidos a hacer una foto y esperan dar algunas sugerencias. Lo mejoraré de nuevo.
4. Algunos pensamientos más tarde
Si ambas máquinas usan la misma cuenta para iniciar sesión en el sistema al mismo tiempo, ¿se pueden registrar ambas cuentas con éxito? . (Además, cuando esta lista de sesión es muy grande, dos máquinas pueden iniciar sesión con éxito al iniciar sesión en el sistema utilizando la misma cuenta al mismo tiempo durante el período transversal). Muy enredado. . ¿Cómo debe controlarse?
(Solución: después de las pruebas, el oyente es un singleton en el sistema. Agregar la palabra clave de sincronización a su método puede garantizar la seguridad de los subprocesos de la lista).
Lo anterior es el Javaweb que le presenta que el editor solo puede iniciar sesión en un lugar al mismo tiempo (similar a la función de inicio de sesión QQ). Espero que sea útil para todos. Si tiene alguna pregunta, déjame un mensaje y el editor responderá a todos a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!