Implementar la gestión de sesiones distribuidas en primavera
Este artículo implementa principalmente la sesión distribuida en primavera y utiliza Redis para persistir en la sesión. De esta manera, cuando se implementa la aplicación, no es necesario configurar distribuidos en contenedores como resina y Tomcat, lo cual es conveniente para agregar nuevos servidores de nodo para la expansión del clúster. La sesión no depende de los servidores de cada nodo y se puede obtener directamente de Redis. Aquí está el código central de la función:
1. Primero configelo en Web.xml
Agregar al interceptor:
< 2 maneras, 1 corresponde a frijoles, el formato es frijoles: clave. 2 cadenas, formatos como: affffrfgv-> <amamname> key </param-name> <amam-value> xxxxxxxxx </amam-value> </it-param> <iten-param> <!-requerido, el bean correspondiente a redis es bean: xx-> <amamname> cachebean </param-name> <Amam-Value> Bean: RedIsperSistent </Param-Value> // distributeBaseInterface, correspondiente a esta interfaz, realiza la operación de persistencia de sesión </it-param> <it-param> <!-requerido,-> <amamname-Name> Cookiename </param-name> <Amam-Value> testSessionId </amam-value> </inicial> </filtro> </filther> <filter-name> DistributedSessionFilter </filter-name> <url-pattern>*. do </sl-pattern> </filter-mapping> <!-End de sesión distribuida->
2. La implementación del interceptor, el código central es el siguiente
Hay principalmente las siguientes categorías:
1. DistributedSessionFilter Implementa Filtro:
import java.io.ioException; import java.util.hashmap; import java.util.map; import javax.servlet.filter; import javax.servlet.filterchain; import javax.servlet.filterconfig; import javax.servlet.servletexception; import javax.servlet.servlet javax.servlet.servletResponse; import javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; import org.springframework.web.context.webapplicationContext; import org.springframework.web.context.support.webapplicationContextUtils; public class DistributedSessionFilter implementa el filtro {private static final Logger log = loggerFactory.getLogger (distributedSessionFilter.class); Cadena privada Cookiename; // Es principalmente una operación para administrar la sesión privada DistributedSessionManager DistributedSessionManager; clave de cadena privada;}Método de inicialización Cuando se inicia el contenedor:
@Override public void init (FilterConfig config) lanza ServletException {WebApplicationContext wac = webApplicationContextUtils.getRequiredWebApplicationContext (config .getServletContext ()); String key = config.getInitParameter ("Key"); String Cookiename = config.getInitParameter ("Cookiename"); String CacheBean = config.getInitParameter ("CacheBean"); // Obtenga el nombre del bean, la configuración es "Bean:" String RedisBeanStr = CacheBean.Substring (5); DistributedBaseInterface DistributedCache = (DistributedBaseInterface) wac.getBean (redisBeanStr); // Obtenga la clave, hay 2 métodos de configuración, 1 corresponde a Bean, y el formato es Bean: Key. 2 cadena if (key.startswith ("bean:")) {this.key = (string) wac.getBean (key.substring (5)); } else {this.key = key; } this.cookiename = Cookiename; this.distributedSessionManager = distributedSessionManager.getInstance (DistributedCache); // Se omite el manejo de excepciones. . . }Realice la intercepción de solicitud real:
@Override public void dofilter (ServLetRequest ServLetRequest, ServLetResponse ServLetResponse, FilterChain FilterChain) lanza ServLetException, IOException {DistributedHttpServletRequestWrapper Distreq = null; Pruebe {// Solicitar procesamiento distribuyeq = creatiCribyedRequest (ServLetRequest, ServLetResponse); filtreChain.dofilter (distribuye, servletResponse); } Catch (lanzable e) {// omitido. . . } Finalmente {if (distribuyeq! = null) {try {// Después de procesar la solicitud, procese la sesión (Guardar principalmente la sesión de la sesión) DealSessessionAfterRequest (distribuyeq.getSession ()); } Catch (lanzable e2) {// omitido. . . }}}}} // Solicitud distribuida DistributedHttpServletRequestWrapper creado DistributedRequest (ServLetRequest ServLetRequest, ServletResponse ServletResponse) lanza ioexception, servletException {httpServletRequest request = (httpServletRequest) ServletRequest; HttpservletResponse respuesta = (httpservletResponse) servletResponse; String UsersID = CookieUtil.getCookie (Cookiename, solicitud); String realSid = distributedSessionManager.getActualSID (ussereSID, request, key); if (stringUtil.isblank (realSid)) {if (stringUtil.isnotblank (usersId)) {log.info ("UsersId [{}] verificación falla", UssersId); } // Escribir cadena de cookie [] UserSidarr = DistributedSessionManager.CreateUserSID (solicitud, clave); UserSID = UssIdarr [0]; CookieUtil.setcookie (Cookiename, UserSid, solicitud, respuesta); realSid = UssIdarr [1]; } realSid = "sid:" + realSid; Distributedhttpsessionwrapper distsession = null; Pruebe {MAP <String, Object> AllAttribute = DistributedSessionManager.getSession (realSid, request.getSession () .getMaxInactiveInterval ()); Distsession = new DistributedHttPsessionWrapper (realSid, request.getSession (), AllAttribute); } catch (Throwable e) {// ocurrió un error, elimine los datos en caché log.error (e.getMessage (), e); Map <string, object> allattribute = new HashMap <String, Object> (); Distsession = new DistributedHttPsessionWrapper (realSid, request.getSession (), AllAttribute); distributedSessionManager.removesession (distsesión); } DistributedHttPservletRequestWrapper requestSwrapper = new DistributedHttPservletRequestWrapper (solicitud, distsession); devolver request Prapper; } // Sesión de operación Void private DealSessessionAfterRequest (distributedHttPsessionWrapper Session) {if (session == null) {return; } if (session.changed) {distributeDessionsionManager.savesession (sesión); } else if (session.Invalidated) {DistributedSessionManager.removesession (sesión); } else {DistributedSessionManager.EXPIRE (sesión); }}2. DistributedSessionManager, se trata principalmente de sesiones distribuidas, código central:
class DistributedSessionManager {protegido estático Final Logger log = loggerFactory.getLogger (distributedSessionManager.class); Instancia privada estática DistributedSessionManager = NULL; // Redis maneja la interfaz de sesión e implementa privado DistributedBaseInterface DistributedBaseInterface; byte estático privado [] bloqueo = nuevo byte [1]; Private DistributedSessionManager (DistributedBaseInterface DistributedBaseInterface) {this.DistributedBaseInterface = DistributedBaseInterface; } public static DistributedSessionManager getInstance (distributeDbaseInterface redis) {if (instance == null) {sincronizado (bloqueo) {if (instance == null) {instancia = new DistributedSessionManager (redis); }}} instancia de retorno; } // Obtener session public map <String, Object> getSession (String Sid, int Second) {String Json = this.DistributedBaseInterface.get (Sid, segundo); if (StringUtil.IsNotBlank (JSON)) {return jsonutil.unserializeMap (json); } return new HashMap <String, Object> (1); } // Guardar sesión public void saveSession (distributedHttpSessionWrapper session) {map <string, object> map = session.allattribute; if (maputil.isempty (map)) {return; } Cadena json = jsonutil.SerializEmap (map); this.DistributedBaseInterface.set (session.getID (), json, session.getMaxInactiveInterval ()); } // Eliminar sesión public void eliminar eliminación (distributedhttpsessionwrapper session) {distributedBaseInterface.del (session.getId ()); } public void expire (distributedHttPsessionWrappers Session) {DistributedBaseInterface.Eppire (session.getID (), session.getMaxInactiveInterval ()); } /** * Crear sid de la cookie * /public string [] createUsersId (httpservletRequest request, Key de cadena) {// ...} public String getACTualSID (String UssId, HttpServletRequest Request, Key String Key) {// ...}}}}}3. DistributedHttPsessionWrapper implementa la httpsession y realiza el envasado de sesión distribuido, código central:
clase pública distributedhttpsessionWrapper implementa httpsession {Orgission privada de httpsession; cadena privada Sid; Boolean cambiado = falso; booleano invalidado = falso; Map <string, object> allattribute; public DistributedHttPsessionWrapper (String Sid, Httpsession Session, Map <String, Object> AllAttribute) {this.orgisession = session; this.sid = sid; this.allattribute = allattribute; } @Override public String getId () {return this.sid; } @Override public void setAttribute (nombre de cadena, valor de objeto) {cambiado = true; allattribute.put (nombre, valor); } @Override Public Object getAttribute (nombre de cadena) {return allattribute.get (nombre); } @Override public enumeración <String> getAttributeNames () {set <string> set = allattribute.keySet (); Iterator <String> iterator = set.iterator (); devuelve nueva myEnumeration <String> (iterator); } MyEnumeration de clase privada <t> implementa la enumeración <t> {iterator <T> iterator; public MyeneMeration (iterator <T> iterator) {super (); this.iterator = iterator; } @Override public boolean HasmoreElements () {return iterator.hasNext (); } @Override public t nextElement () {return iterator.next (); }} @Override public void invalidate () {this.invalidated = true; } @Override public void RemoveAttribute (nombre de cadena) {cambiado = true; allattribute.remove (nombre); } @Override public Long GetCreationTime () {return Orgisession.getCreationTime (); } @Override public Long getLastAccessTtime () {return Orgisession.getLastAccessTime (); } @Override public int getMaxInactiveInterval () {return Orgisession.getMaxInactiveInterval (); } @Override public ServletContext getServletContext () {return Orgisession.getServletContext (); } @Override Public Object getValue (String arg0) {return Orgisession.getValue (arg0); } @Override public String [] getValueNames () {return Orgisession.getValueames (); } @Override public boolean isNew () {return Orgisession.isNew (); } @Override public void putValue (String arg0, object arg1) {Orgisession.putValue (arg0, arg1); } @Override public void RemoLEValue (String Arg0) {Orgisession.RemoveValue (arg0); } @Override public void setMaxInactiveInterval (int arg0) {Orgisession.SetMaxInactiveInterval (arg0); } @Override public httpsessionContext getSessionContext () {return Orgisession.getSessionContext (); }4. DistributedHttPservletRequestWrapper implementa httpservletRequestWrapper, envuelve la sesión procesada y la solicitud original, código central:
Public Class DistributedHttpServletRequestWrapper extiende javax.servlet.http.httpservletrequestwrapper {private httpservletRequest Orgirequest; Sesión privada distributedhttpsessionwrapper; Public DistributedHttPservletRequestWrapper (solicitud httpservletRequest, distributedhttpsessionwrapper session) {super (request); if (session == null) {// manejo de excepciones. . } if (request == null) {// manejo de excepciones. . } this.orgirequest = request; this.session = session; } public DistributedHttPsessionWrapper getSession (boolean create) {orgirequest.getSession (create); sesión de regreso; } public DistributedHttPsessionWrapper getSession () {Sesión de retorno; }}5. Además, defina la interfaz DistributedBaseInterface para manejar la sesión en Redis para operaciones de persistencia:
Public Interface DistributedBaseInterface { / ** * Obtenga datos en caché basados en la clave * @param clave * @param segundos * / public string get (clave de cadena, int segundos); / ** * Actualizar datos en caché * @param clave * @param json * @param segundos */ public void set (clave de cadena, string json, int segundos); / *** Eliminar caché* @param key*/ public void del (tecla de cadena); / ** * Establezca datos caducados * @param clave * @param segundos */ public void expire (clave de cadena, int segundos);Nota: Este artículo solo utiliza el método Redis para administrar las sesiones en la primavera, y hay muchos otros métodos de implementación, como la configuración en contenedores, etc., y diseña un algoritmo de enrutamiento para hacer que las sesiones dependan de varios servidores de nodos en el grupo,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,, ,,,,,,,,,,,,,,,,,,,,,,E ,,,,,,,,,,,,,,,,,,,,,,e,,,,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,,,,,,,,, a ,,,,,,,,,,,,,,,,,,, a ,,,,,,,,,,,,,,,,,,,,, a,. ,, ,,,,,,,,,,,,,,,,,,,,,,E ,,,,,,,,,,,,,,,,,,,,,,e,,,,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,,,,,,,,, a ,,,,,,,,,,,,,,,,,,, a ,,,,,,,,,,,,,,,,,,,,, a,. ,, ,,,,,,,,,,,,,,,,,,,,,,E ,,,,,,,,,,,,,,,,,,,,,,e,,,,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,,, a ,,,,,,,,,,,,,,,,,, a ,,,,,,,,,,,,,,,,,,, a ,,,,,,,,,,,,,,,,,,,,, a,.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.