亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

如何使用Spring+redis實現對session的分布式管理

2024-07-14 08:41:24
字體:
來源:轉載
供稿:網友

在Spring中實現分布式 session管理

本文主要是在Spring中實現分布式session,采用redis對session進行持久化管理,這樣當應用部署的時候,不需要在Resin、Tomcat等容器里面進行分布式配置,方便加入新的節點服務器進行集群擴容,session不依賴各節點的服務器,可直接從redis獲取。下面是功能的核心代碼:

一、首先在web.xml里面配置

加入攔截器:

<!-- 分布式session start -->  <filter>    <filter-name>distributedSessionFilter</filter-name>    <filter-class>DistributedSessionFilter</filter-class>    <init-param>      <!-- 必填,密鑰.2種方式,1對應為bean,格式為bean:key。2字符串,格式如:afffrfgv-->      <param-name>key</param-name>      <param-value>xxxxxxxx</param-value>    </init-param>    <init-param>      <!-- 必填,redis對應的bean,格式為bean:xx-->      <param-name>cacheBean</param-name>      <param-value>bean:redisPersistent</param-value>//DistributedBaseInterFace,對應于此接口,進行session的持久化操作    </init-param>    <init-param>      <!-- 必填, -->      <param-name>cookieName</param-name>      <param-value>TESTSESSIONID</param-value>    </init-param>  </filter>  <filter-mapping>    <filter-name>distributedSessionFilter</filter-name>    <url-pattern>*.do</url-pattern>  </filter-mapping>  <!-- 分布式session end -->

二、攔截器的實現,核心代碼如下

主要有以下的幾個類:

  1. DistributedSessionFilter,
  2. DistributedSessionManager,
  3. DistributedHttpSessionWrapper,
  4. DistributedHttpServletRequestWrapper

1、DistributedSessionFilter實現Filter:

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.ServletRequest;import 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 implements Filter {  private static final Logger log = LoggerFactory.getLogger(DistributedSessionFilter.class);  private String cookieName;  //主要是對session進行管理的操作  private DistributedSessionManager distributedSessionManager;  private String key;}

容器啟動時候的初始化方法:

@Override  public void init(FilterConfig config) throws ServletException {    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(config        .getServletContext());    String key = config.getInitParameter("key");    String cookieName = config.getInitParameter("cookieName");    String cacheBean = config.getInitParameter("cacheBean");    // 獲取bean的名稱,配置是"bean:"    String redisBeanStr = cacheBean.substring(5);    DistributedBaseInterFace distributedCache = (DistributedBaseInterFace) wac.getBean(redisBeanStr);    // 獲取key,有2種配置方式,1對應為bean,格式為bean:key。2字符串    if (key.startsWith("bean:")) {      this.key = (String) wac.getBean(key.substring(5));    } else {      this.key = key;    }    this.cookieName = cookieName;    this.distributedSessionManager = DistributedSessionManager.getInstance(distributedCache);    //異常處理省略。。。  }

進行實際的請求攔截:

  @Override  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)      throws ServletException, IOException {    DistributedHttpServletRequestWrapper distReq = null;    try {      //請求處理      distReq = createDistributedRequest(servletRequest, servletResponse);      filterChain.doFilter(distReq, servletResponse);    } catch (Throwable e) {      //省略。。。    } finally {      if (distReq != null) {        try {          //處理完成request后,處理session(主要是保存session會話)          dealSessionAfterRequest(distReq.getSession());        } catch (Throwable e2) {          //省略。。。        }      }    }  }  //分布式請求  private DistributedHttpServletRequestWrapper createDistributedRequest(ServletRequest servletRequest,      ServletResponse servletResponse) throws IOException, ServletException {    HttpServletRequest request = (HttpServletRequest) servletRequest;    HttpServletResponse response = (HttpServletResponse) servletResponse;    String userSid = CookieUtil.getCookie(cookieName, request);    String actualSid = distributedSessionManager.getActualSid(userSid, request, key);    if (StringUtil.isBlank(actualSid)) {      if (StringUtil.isNotBlank(userSid)) {        log.info("userSid[{}]驗證不通過", userSid);      }      // 寫cookie      String[] userSidArr = distributedSessionManager.createUserSid(request, key);      userSid = userSidArr[0];      CookieUtil.setCookie(cookieName, userSid, request, response);      actualSid = userSidArr[1];    }    actualSid = "sid:" + actualSid;    DistributedHttpSessionWrapper distSession = null;    try {      Map<String, Object> allAttribute = distributedSessionManager.getSession(actualSid, request.getSession()          .getMaxInactiveInterval());      distSession = new DistributedHttpSessionWrapper(actualSid, request.getSession(), allAttribute);    } catch (Throwable e) {      // 出錯,刪掉緩存數據      log.error(e.getMessage(), e);      Map<String, Object> allAttribute = new HashMap<String, Object>();      distSession = new DistributedHttpSessionWrapper(actualSid, request.getSession(), allAttribute);      distributedSessionManager.removeSession(distSession);    }    DistributedHttpServletRequestWrapper requestWrapper = new DistributedHttpServletRequestWrapper(request,        distSession);    return requestWrapper;  }  // request處理完時操作session  private void dealSessionAfterRequest(DistributedHttpSessionWrapper session) {    if (session == null) {      return;    }    if (session.changed) {      distributedSessionManager.saveSession(session);    } else if (session.invalidated) {      distributedSessionManager.removeSession(session);    } else {      distributedSessionManager.expire(session);    }  }

 2、DistributedSessionManager,主要處理分布式session,核心代碼:

class DistributedSessionManager {  protected static final Logger log = LoggerFactory.getLogger(DistributedSessionManager.class);  private static DistributedSessionManager instance = null;  //redis處理session的接口,自己根據情況實現  private DistributedBaseInterFace distributedBaseInterFace;  private static byte[] lock = new byte[1];  private DistributedSessionManager(DistributedBaseInterFace distributedBaseInterFace) {    this.distributedBaseInterFace = distributedBaseInterFace;  }  public static DistributedSessionManager getInstance(DistributedBaseInterFace redis) {    if (instance == null) {      synchronized (lock) {        if (instance == null) {          instance = new DistributedSessionManager(redis);        }      }    }    return instance;  }  //獲取session  public Map<String, Object> getSession(String sid,int second) {    String json = this.distributedBaseInterFace.get(sid,second);    if (StringUtil.isNotBlank(json)) {      return JsonUtil.unserializeMap(json);    }    return new HashMap<String, Object>(1);  }  //保存session  public 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());  }  //刪除session  public void removeSession(DistributedHttpSessionWrapper session) {    distributedBaseInterFace.del(session.getId());  }  public void expire(DistributedHttpSessionWrapper session) {    distributedBaseInterFace.expire(session.getId(), session.getMaxInactiveInterval());  }  /**   * 創建cookie的sid   */  public String[] createUserSid(HttpServletRequest request, String key) {    //...  }  public String getActualSid(String userSid, HttpServletRequest request, String key) {    //...  }}

3、DistributedHttpSessionWrapper 實現了 HttpSession,進行分布式session包裝,核心代碼:

public class DistributedHttpSessionWrapper implements HttpSession {  private HttpSession orgiSession;  private String sid;  boolean changed = false;  boolean invalidated = false;  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(String name, Object value) {    changed = true;    allAttribute.put(name, value);  }  @Override  public Object getAttribute(String name) {    return allAttribute.get(name);  }  @Override  public Enumeration<String> getAttributeNames() {    Set<String> set = allAttribute.keySet();    Iterator<String> iterator = set.iterator();    return new MyEnumeration<String>(iterator);  }  private class MyEnumeration<T> implements Enumeration<T> {    Iterator<T> iterator;    public MyEnumeration(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(String name) {    changed = true;    allAttribute.remove(name);  }  @Override  public long getCreationTime() {    return orgiSession.getCreationTime();  }  @Override  public long getLastAccessedTime() {    return orgiSession.getLastAccessedTime();  }  @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.getValueNames();  }  @Override  public boolean isNew() {    return orgiSession.isNew();  }  @Override  public void putValue(String arg0, Object arg1) {    orgiSession.putValue(arg0, arg1);  }  @Override  public void removeValue(String arg0) {    orgiSession.removeValue(arg0);  }  @Override  public void setMaxInactiveInterval(int arg0) {    orgiSession.setMaxInactiveInterval(arg0);  }  @Override  public HttpSessionContext getSessionContext() {    return orgiSession.getSessionContext();  }

4、DistributedHttpServletRequestWrapper 實現了 HttpServletRequestWrapper,包裝處理過的session和原始request,核心代碼:

public class DistributedHttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper {  private HttpServletRequest orgiRequest;  private DistributedHttpSessionWrapper session;  public DistributedHttpServletRequestWrapper(HttpServletRequest request, DistributedHttpSessionWrapper session) {    super(request);    if (session == null){      //異常處理。。    }    if (request == null){      //異常處理。。    }    this.orgiRequest = request;    this.session = session;  }  public DistributedHttpSessionWrapper getSession(boolean create) {    orgiRequest.getSession(create);    return session;  }  public DistributedHttpSessionWrapper getSession() {    return session;  }}

5、另外,定義DistributedBaseInterFace接口,用來處理session入redis進行持久化操作:

public interface DistributedBaseInterFace {  /**   * 根據key獲取緩存數據   * @param key     * @param seconds     */  public String get(String key,int seconds);  /**   * 更新緩存數據   * @param key     * @param json   * @param seconds   */  public void set(String key, String json,int seconds);  /**   * 刪除緩存   * @param key   */  public void del(String key);  /**   * 設置過期數據   * @param key   * @param seconds   */  public void expire(String key,int seconds);

注:本文只是在Spring中采用redis的方式對session進行管理,還有其他諸多的實現方式,比如在容器里面配置等,設計路由算法讓session依賴于集群中的各個節點服務器,,,,,,但redis這種方式在實際應用中還是比較廣泛的,LZ公司主要就是采用此方式。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕免费精品一区| 在线精品91av| xxxx欧美18另类的高清| 日韩视频在线免费| 日韩精品在线观看一区| 日韩毛片在线观看| 欧美肥臀大乳一区二区免费视频| 成人精品网站在线观看| 亚洲欧美一区二区三区久久| 国产精品99一区| 亚洲欧洲xxxx| 久久天天躁夜夜躁狠狠躁2022| 国产精品极品美女在线观看免费| 亚洲高清久久久久久| 亚洲欧美日韩国产成人| 久久久精品2019中文字幕神马| 国产精品福利在线观看| 亚洲精品福利在线观看| 欧美在线免费视频| 亚洲欧美激情四射在线日| 欧美激情视频在线观看| 成人羞羞国产免费| 伊人久久综合97精品| 欧美性xxxx极品高清hd直播| 亚洲伦理中文字幕| 北条麻妃一区二区在线观看| 中文字幕亚洲综合久久| 欧美—级a级欧美特级ar全黄| 91精品国产成人www| 国产欧美一区二区三区久久人妖| 亚洲激情视频在线| 亚洲国产精品免费| 欧美激情一区二区三区成人| 欧美日韩激情视频8区| 国产欧亚日韩视频| 国产精品激情av电影在线观看| 欧美激情国产高清| 精品成人av一区| www.久久久久| 国产欧美精品一区二区三区介绍| www.日韩视频| 国产精品综合网站| 欧美电影院免费观看| 亚洲一区二区中文字幕| 伊人久久大香线蕉av一区二区| 国产91精品久久久久久久| 国产精品男人爽免费视频1| 4438全国亚洲精品在线观看视频| 欧美黑人极品猛少妇色xxxxx| 国产成人涩涩涩视频在线观看| 国产美女精品免费电影| 国产日产亚洲精品| 丝袜美腿亚洲一区二区| 日韩福利视频在线观看| 欧美日韩国产色| www.日韩不卡电影av| 日韩免费在线观看视频| 国产精品女人久久久久久| 国产成人高清激情视频在线观看| 日韩福利伦理影院免费| 国产成人精彩在线视频九色| 国产亚洲视频在线| 97国产suv精品一区二区62| 国产欧美亚洲视频| 精品无人区太爽高潮在线播放| 国产精品91久久久久久| 亚洲成人aaa| 韩日精品中文字幕| 精品福利视频导航| 国产欧亚日韩视频| 久久资源免费视频| 中文字幕亚洲无线码a| 欧美综合在线观看| 亚洲欧美制服丝袜| 亚洲free性xxxx护士hd| 精品日韩美女的视频高清| 日韩在线欧美在线国产在线| 少妇激情综合网| 成人黄色在线观看| 成人激情视频小说免费下载| 国产精品人成电影| 欧美肥臀大乳一区二区免费视频| 精品国偷自产在线视频99| 欧美视频在线免费| 97免费在线视频| 欧美日韩午夜激情| 久久久久久91香蕉国产| 日韩av理论片| 中文国产成人精品久久一| 久久国内精品一国内精品| 亚洲欧美精品伊人久久| 国产精品777| 欧美第一黄色网| 久久激情视频久久| 日韩av免费观影| 尤物精品国产第一福利三区| 亚洲精品久久久久中文字幕二区| 欧美一级黄色网| 久久精品亚洲精品| 亚洲国产精品成人va在线观看| 亚洲国产精品女人久久久| 欧美午夜美女看片| 91视频免费网站| 亚洲欧美综合区自拍另类| 国产精品男人爽免费视频1| 亚洲美女中文字幕| 九九久久久久99精品| 97色在线观看免费视频| 国产精品久久久久久久久借妻| 国产视频一区在线| 91po在线观看91精品国产性色| 国产香蕉一区二区三区在线视频| 国内精品伊人久久| 亚洲欧洲视频在线| 国产999在线观看| 国产精品视频永久免费播放| 欧美视频中文在线看| 岛国av一区二区三区| 精品视频—区二区三区免费| 欧美性一区二区三区| 97av在线视频| 精品人伦一区二区三区蜜桃免费| 日韩欧美在线视频| 26uuu亚洲伊人春色| 国产久一一精品| 国产视频丨精品|在线观看| 日韩av毛片网| 国产成人精品一区二区三区| 亚洲美女又黄又爽在线观看| 国产精品久久久久影院日本| 精品无人国产偷自产在线| 欧美老少配视频| 日韩av在线看| 成人黄在线观看| 精品久久久久久久久久久久久久| 欧美大片在线看| 亚洲伦理中文字幕| 欧美激情一二三| 久久成年人视频| 热re99久久精品国产66热| 亚洲精品白浆高清久久久久久| 国产一区二区三区在线免费观看| 中国人与牲禽动交精品| 日本一区二区三区在线播放| 亚洲成人网av| 亚洲伊人第一页| 欧美在线播放视频| 亚洲国产高清福利视频| 在线看日韩欧美| 一区二区三区国产视频| 国产精品99免视看9| 亚洲最大的av网站| 亚洲第一二三四五区| 欧美在线观看一区二区三区| 黑人巨大精品欧美一区免费视频| 性日韩欧美在线视频| 久久久中精品2020中文| 中国人与牲禽动交精品| 久久伊人免费视频| 国产精品久久久久免费a∨| 日本欧美一二三区| 亚洲va久久久噜噜噜| 中文字幕欧美日韩在线| 久久97精品久久久久久久不卡|