一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 如何使用Spring+redis實現對session的分布式管理

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

2021-05-12 15:06幢一幢 Java教程

本篇文章主要介紹了如何使用Spring+redis實現對session的分布式管理,本文主要是在Spring中實現分布式session,采用redis對session進行持久化管理,感興趣的小伙伴們可以參考一下

在spring中實現分布式 session管理

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

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

加入攔截器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- 分布式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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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;
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@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);
 
    //異常處理省略。。。
  }

進行實際的請求攔截:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
@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,核心代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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包裝,核心代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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,核心代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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進行持久化操作:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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公司主要就是采用此方式。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/u014263388/article/details/56020889

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 免费视频精品一区二区三区 | 日韩在线观看免费 | 校花的第一次好紧好爽 | 国产大胆歌舞团网站 | 免费看麻豆视频 | 青青草高清视频 | 女性性色生活片免费观看 | 精品日韩一区 | 女被男啪到哭 | 国产喂奶300部 | 奇米影视在线观看 | 亚洲 欧美 中文 日韩欧美 | 日本一区二区免费在线观看 | 国内久久婷婷综合欲色啪 | 国产精品视频在线观看 | 私人影院在线播放 | 91aaa免费免费国产在线观看 | 国产欧美日韩精品高清二区综合区 | 四虎成人免费观看在线网址 | 九九热在线免费观看 | 黑人与老女人做受 | 国产综合欧美日韩视频一区 | 九九九国产视频 | 色色色色色色网 | 火影忍者小南裸羞羞漫画 | 禁忌高h| 香蕉久久ac一区二区三区 | 日本美女动态图片 | 亚洲第一区欧美日韩精品 | 日本艳鉧动漫1~6在线观看 | 欧美最猛性xxxxx动态图 | 不卡视频一区二区 | 日本草草视频 | 我与恶魔的h生活ova | 婷婷天天 | 国产午夜精品久久理论片 | 美女扒开粉嫩尿口漫画 | 国产精品一区久久精品 | 非洲黑女人性xxxx | 日本亚洲娇小与黑人tube | 91手机看片国产永久免费 |