国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > Java > 正文

如何使用Spring+redis實(shí)現(xiàn)對session的分布式管理

2024-07-14 08:41:24
字體:
供稿:網(wǎng)友

在Spring中實(shí)現(xiàn)分布式 session管理

本文主要是在Spring中實(shí)現(xiàn)分布式session,采用redis對session進(jìn)行持久化管理,這樣當(dāng)應(yīng)用部署的時(shí)候,不需要在Resin、Tomcat等容器里面進(jìn)行分布式配置,方便加入新的節(jié)點(diǎn)服務(wù)器進(jìn)行集群擴(kuò)容,session不依賴各節(jié)點(diǎn)的服務(wù)器,可直接從redis獲取。下面是功能的核心代碼:

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

加入攔截器:

<!-- 分布式session start -->  <filter>    <filter-name>distributedSessionFilter</filter-name>    <filter-class>DistributedSessionFilter</filter-class>    <init-param>      <!-- 必填,密鑰.2種方式,1對應(yīng)為bean,格式為bean:key。2字符串,格式如:afffrfgv-->      <param-name>key</param-name>      <param-value>xxxxxxxx</param-value>    </init-param>    <init-param>      <!-- 必填,redis對應(yīng)的bean,格式為bean:xx-->      <param-name>cacheBean</param-name>      <param-value>bean:redisPersistent</param-value>//DistributedBaseInterFace,對應(yīng)于此接口,進(jìn)行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 -->

二、攔截器的實(shí)現(xiàn),核心代碼如下

主要有以下的幾個(gè)類:

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

1、DistributedSessionFilter實(shí)現(xiàn)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進(jìn)行管理的操作  private DistributedSessionManager distributedSessionManager;  private String key;}

容器啟動(dòng)時(shí)候的初始化方法:

@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對應(yīng)為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);    //異常處理省略。。。  }

進(jìn)行實(shí)際的請求攔截:

  @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[{}]驗(yàn)證不通過", 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) {      // 出錯(cuò),刪掉緩存數(shù)據(jù)      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處理完時(shí)操作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的接口,自己根據(jù)情況實(shí)現(xiàn)  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());  }  /**   * 創(chuàng)建cookie的sid   */  public String[] createUserSid(HttpServletRequest request, String key) {    //...  }  public String getActualSid(String userSid, HttpServletRequest request, String key) {    //...  }}

3、DistributedHttpSessionWrapper 實(shí)現(xiàn)了 HttpSession,進(jìn)行分布式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 實(shí)現(xiàn)了 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進(jìn)行持久化操作:

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

注:本文只是在Spring中采用redis的方式對session進(jìn)行管理,還有其他諸多的實(shí)現(xiàn)方式,比如在容器里面配置等,設(shè)計(jì)路由算法讓session依賴于集群中的各個(gè)節(jié)點(diǎn)服務(wù)器,,,,,,但redis這種方式在實(shí)際應(yīng)用中還是比較廣泛的,LZ公司主要就是采用此方式。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到JAVA教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 寿阳县| 蒙山县| 江安县| 秀山| 临湘市| 上栗县| 深州市| 高平市| 格尔木市| 安龙县| 黄大仙区| 体育| 沧州市| 凌源市| 赤城县| 秀山| 陆丰市| 临桂县| 东乡县| 图片| 昆明市| 上思县| 大埔区| 泸定县| 南汇区| 洞口县| 额敏县| 九江市| 桂东县| 台中县| 瑞安市| 揭阳市| 合作市| 平乡县| 阿城市| 靖边县| 永年县| 油尖旺区| 民县| 太原市| 依兰县|