Implémenter la gestion des sessions distribuées au printemps
Cet article implémente principalement la session distribuée au printemps et utilise Redis pour persister la session. De cette façon, lorsque l'application est déployée, il n'est pas nécessaire de configurer distribué dans des conteneurs tels que la résine et le tomcat, ce qui est pratique pour ajouter de nouveaux serveurs de nœuds pour l'expansion des cluster. La session ne dépend pas des serveurs de chaque nœud et peut être obtenue directement à partir de redis. Voici le code central de la fonction:
1. Configurez-le d'abord dans web.xml
Ajouter à l'intercepteur:
<! - Démarrage de la session distribuée -> <filter> <Filter-Name> DistributedSessionFilter </filter-name> <Filter-Class> DistributedSessionFilter </filter-Class> <Init-Param> <! - requise, clé. 2 façons, 1 correspond au haricot, le format est Bean: Key. 2 chaînes, formats tels que: affffrfgv -> <param-name> key </ param-name> <param-valeur> xxxxxxxx </ param-value> </ init-param> <Init-param> <! - requis, le bean correspondant à redis est bean: xx -> <param-name> cachebean </onsam-name> <Ar param-Value> Bean: redispersistentant </onsam-valie> // DistributedBaseInterface, correspondant à cette interface, effectuez l'opération de persistance de session </1nit-param> <in init-param> <! - Obligatoire, -> <param-name> Cookiename </onsam-name> <param-Value> TestSessionId </onsam-Value> <Filter-Name> DistributedSessionFilter </filter-name> <url-sattern> *. do </url-sattern> </filter-mapping> <! - Session distribuée fin ->
2. L'implémentation de l'intercepteur, le code central est le suivant
Il existe principalement les catégories suivantes:
1. DistributedSessionFilter implémente filtre:
Importer java.io.ioException; import java.util.hashmap; import java.util.map; import javax.servlet.filter; importer javax.servlet.filterchain; import javax.servlet.filterconfig; import javax.servlet.Servlexect; import javax.sservlet.Servletreque javax.servlet.servletResponse; import javax.servlet.http.httpsservletRequest; import javax.servlet.http.httpservletResponse; import org.springframework.web.context.webappcationcontext; import; org.springframework.web.context.support.webapplicationContextUtils; public class DistributedSessionFilter implémente Filter {private static final logger log = loggerfactory.getLogger (distributionSessionFilter.class); corde privée Cookiename; // Il s'agit principalement d'une opération pour gérer la session Private DistributedSessionManager DistributedSessionManager; clé de chaîne privée;}Méthode d'initialisation lorsque le conteneur démarre:
@Override public void init (filterConfig config) lève ServletException {webApplicationContext wac = webApplicationContextUtils.getRequiredWebApplicationContext (config .getServletContext ()); String key = config.getInitParameter ("key"); String Cookiename = config.getInitParameter ("Cookiename"); String cacheBean = config.getInitParameter ("CacheBean"); // Obtenez le nom du bean, la configuration est "bean:" String redisbeanstr = cacheBean.SubString (5); DistributedBaseInterface DistributedCache = (DistributedBaseInterface) wac.getBean (redisbeanstr); // Obtenez la clé, il existe 2 méthodes de configuration, 1 correspond à Bean et le format est la clé Bean:. 2 String if (key.startswith ("bean:")) {this.key = (string) wac.getBean (key.substring (5)); } else {this.key = key; } this.cookiename = Cookiename; this.DistributedSessionManager = DistributedSessionManager.getInstance (DistributedCache); // La gestion des exceptions est omise. . . }Effectuer une interception réelle de la demande:
@Override public void dofilter (servletRequest servletRequest, servletResponse servletResponse, filterchain filterchain) lève ServletException, ioException {distribuéhttpservletRequestwrapper deteq = null; essayez {// de demande de traitement destReq = CreatedSiStRributeDequest (ServLetRequest, ServletResponse); FilterChain.Dofilter (DESTREQ, ServletResponse); } catch (jetable e) {// omis. . . } Enfin {if (destreq! = null) {try {// Après le traitement de la demande, traitez la session (enregistrer principalement la session de session) DealSessionAfterRequest (destreq.getSession ()); } catch (jetable e2) {// omis. . . }}}}} // Demande distribuée private DistributedHTTPServLetRequestWrapper CreatedSiStributeDequest (ServLetRequest ServleTrequest, ServletResponse ServletResponse) Throws ioException, servlexception {httpservletRequest request = (httServeRequest) ServletRequest; HttpServletResponse Response = (httpServletResponse) servletResponse; String UsersId = CookieUtil.getCookie (Cookiename, demande); String réelSID = DistributedSessionManager.GetActualSid (USERSID, demande, clé); if (stringUtil.isblank (acalSid)) {if (stringUtil.isnotblank (usersId)) {log.info ("usersId [{}] vérification échoue", usersId); } // Écriture de la chaîne de cookie [] usersIdarr = distributionsessemanager.createusersId (request, key); usersID = usersIdarr [0]; CookieUtil.setcookie (Cookiename, UsersId, demande, réponse); acelSid = usersIdarr [1]; } réelSid = "Sid:" + réelSid; DistributedHTTSSESSSEWPRAPPER DISSESSION = NULL; try {map <string, object> allAttribute = DistributedSessionManager.getSession (réelSid, request.getSession () .getMaxInActiveInterval ()); DISTSESSION = NOUVEAU DISTRIBUDHTTSSESSESSEWPRAPPER (ACREALSID, REQUÊTE.getSession (), AllAtTribute); } catch (Throwable E) {// Une erreur s'est produite, supprimez le log.Error de données en cache (e.getMessage (), e); Map <string, object> allAttribute = new HashMap <String, Object> (); DISTSESSION = NOUVEAU DISTRIBUDHTTSSESSESSEWPRAPPER (ACREALSID, REQUÊTE.getSession (), AllAtTribute); DistributedSessionManager. } DistributedHTTPServLetRequestwrapper requestwrapper = new DistributedHTTPServLetRequestwrapper (request, distSession); return requestwrapper; } // Session d'opération Session privée void OFFRESSEAFTERREQUEST (Session DistributedHTTPSessionwrapper) {if (session == null) {return; } if (session.changed) {DistributedSessionManager.Savession (session); } else if (session.invalidated) {DistributedSessionManager.RemoveSession (session); } else {DistributedSessionManager.Expire (session); }}2. DistributedSessionManager, traite principalement des sessions distribuées, code de base:
classe DistributedSessionManager {Protected Static Final Logger Log = LoggerFactory.GetLogger (DistributedSessionManager.Class); Instance privée statique DistributedSessionManager = null; // Redis gère l'interface de session et implémente privé DistributedBaseInterface DistributedBaseInterface; octet statique privé [] verrouillage = nouvel octet [1]; Private DistributedSessionManager (DistributedBaseInterface DistributedBaseInterface) {this.DistributedBaseInterface = DistributedBaseInterface; } public static DistributedSessionManager GetInstance (DistributedBaseInterface redis) {if (instance == null) {synchronisé (lock) {if (instance == null) {instance = new DistributedSessionManager (redis); }}} Instance de retour; } // Get Session Public Map <String, Object> GetSession (String Sid, int Second) {String JSON = this.DistributedBaseInterface.get (Sid, deuxième); if (stringUtil.isnotblank (json)) {return jsonutil.unserializemap (json); } return new hashmap <string, objet> (1); } // Enregistrer la session publique void SaveSession (DistributedHTTPSessionWrapper Session) {map <string, object> map = session.AllAttribute; if (mapUtil.iSempty (map)) {return; } String json = jsonutil.serializemap (map); this.DistributedBaseInterface.Set (session.getId (), JSON, session.getMaxInactiveInterval ()); } // Supprimer la session publique void Suppression (Session DistributedHTTPSessionWrapper) {DistributedBaseInterface.del (session.getId ()); } public void expire (DistributedHTTPSessionwrapper session) {DistributedBaseInterface.Expire (session.getID (), session.getMaxInactiveInterval ()); } / ** * Créer SID du cookie * / public String [] CreateUSeSID (HttpServLetRequest Request, String Key) {// ...} public String getActualSid (String UsersId, httpServLetRequest Request, String Key) {// ...}}3. DistributedHTTSSessionwrapper implémente httpSession et effectue un emballage de session distribué, code de base:
classe publique DistributedHTTSSessionwrapper implémente httpSession {private httpSession orgiscession; chaîne privée Sid; booléen changé = false; booléen invalidé = false; Map <string, objet> allAttribute; public DistributedHTTPSessionWrapper (String Sid, HttpSession Session, Map <String, Object> allAttribute) {this.orgiscession = session; this.sid = sid; this.AllAtTribute = allAttribute; } @Override public String getID () {return this.sid; } @Override public void setAttribute (nom de chaîne, valeur d'objet) {changé = true; allAttribute.put (nom, valeur); } @Override Public Object GetAttribute (String Name) {return allAtTribute.get (name); } @Override Public Enumeration <string> getAtTrutEnames () {set <string> set = allAttribute.KeySet (); Iterator <string> iterator = set.iterator (); return new myEnumeration <string> (iterator); } classe privée Myenumeration <T> implémente l'énumération <T> {Iterator <T> Iterator; Myenumeration publique (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 (nom de chaîne) {changé = true; allAttribute.Remove (nom); } @Override public long getCreationTime () {return orgiSession.getCreationTime (); } @Override public long getLastAccessEdTime () {return orgiscession.getLastAccessEdTime (); } @Override public int getMaxInactiveInterval () {return orgission.getMaxInactiveInterval (); } @Override public ServletContext getServletContext () {return orgission.getServletContext (); } @Override public objet getValue (String arg0) {return orgission.getValue (arg0); } @Override public String [] getValueNames () {return orgission.getValuEnames (); } @Override public boolean isnew () {return orgission.isnew (); } @Override public void putValue (String arg0, objet arg1) {orgiscession.putValue (arg0, arg1); } @Override public void demoveValue (String arg0) {orgiSession.RemoveValue (arg0); } @Override public void setMaxInactiveInterval (int arg0) {orgission.setMaxInactiveInterval (arg0); } @Override public httSessionContext getSessionContext () {return orgisession.getSessionContext (); }4. DistributedHTTPServLetRequestwrapper implémente httpservletRequestwrapper, enveloppe la session traitée et la demande d'origine, CODE CODE:
classe publique DistributedHttpServletRequestwrapper étend javax.servlet.http.httpservletRequestwrapper {privé httpservletRequest orgirequest; Session privée DistributedHTTSSessionwrapper; public DistributedHTTPServLetRequestwrapper (demande httpservletRequest, session DistributedHTTSSessionwrapper) {super (request); if (session == null) {// Gestion des exceptions. . } if (request == null) {// Gestion des exceptions. . } this.orGirequest = request; this.Session = session; } public DistributedHTTSSessionwrapper getSession (boolean create) {orgirequest.getSession (create); Session de retour; } public DistributedHTTSSessionwrapper getSession () {return session; }}5.
Interface publique DistributedBaseInterface {/ ** * Obtenez des données en cache basées sur la clé * @param key * @param secondes * / public String get (string key, int Seconds); / ** * Mettez à jour les données en cache * @param key * @param json * @param secondes * / public void set (string key, string json, int secondes); / ** * supprimer le cache * @param key * / public void del (key string); / ** * Définir les données expirées * @param key * @param secondes * / public void expire (string key, int secondes);Remarque: Cet article utilise uniquement la méthode Redis pour gérer les sessions au printemps, et il existe de nombreuses autres méthodes d'implémentation, telles que la configuration dans les conteneurs, etc., et conçoit un algorithme de routage pour faire en sorte que les sessions s'appuient sur divers serveurs de nœuds dans le grappe,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.