激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - 如何使用Spring+redis實(shí)現(xiàn)對(duì)session的分布式管理

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

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

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

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

本文主要是在spring中實(shí)現(xiàn)分布式session,采用redis對(duì)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里面配置

加入攔截器:

?
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對(duì)應(yīng)為bean,格式為bean:key。2字符串,格式如:afffrfgv-->
      <param-name>key</param-name>
      <param-value>xxxxxxxx</param-value>
    </init-param>
    <init-param>
      <!-- 必填,redis對(duì)應(yīng)的bean,格式為bean:xx-->
      <param-name>cachebean</param-name>
      <param-value>bean:redispersistent</param-value>//distributedbaseinterface,對(duì)應(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:

?
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;
 
  //主要是對(duì)session進(jìn)行管理的操作
  private distributedsessionmanager distributedsessionmanager;
 
  private string key;
}

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

?
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對(duì)應(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í)際的請(qǐng)求攔截:

?
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 {
    //請(qǐng)求處理
    distreq = createdistributedrequest(servletrequest, servletresponse);
    filterchain.dofilter(distreq, servletresponse);
  } catch (throwable e) {
    //省略。。。
  } finally {
    if (distreq != null) {
      try {
        //處理完成request后,處理session(主要是保存session會(huì)話)
        dealsessionafterrequest(distreq.getsession());
      } catch (throwable e2) {
        //省略。。。
      }
    }
  }
}
 
//分布式請(qǐng)求
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)證不通過(guò)", usersid);
    }
    // 寫(xiě)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,核心代碼:

?
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的接口,自己根據(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包裝,核心代碼:

?
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 實(shí)現(xiàn)了 httpservletrequestwrapper,包裝處理過(guò)的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接口,用來(lái)處理session入redis進(jìn)行持久化操作:

?
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 {
 
  /**
   * 根據(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è)置過(guò)期數(shù)據(jù)
   * @param key
   * @param seconds
   */
  public void expire(string key,int seconds);

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 毛片在线免费观看网址 | 99一区二区三区 | 国产精品久久久久网站 | 91一区二区三区久久久久国产乱 | 一级电影免费看 | 福利免费观看 | 2021国产精品 | 国产合集91合集久久日 | 91精品国产91 | 免费小毛片 | 欧美成人午夜一区二区三区 | 91久久久久久久久久 | 在火车上摸两乳爽的大叫 | 亚洲小视频在线 | 久久sp| 被日视频 | 蜜桃一本色道久久综合亚洲精品冫 | 久久综合九色 | 欧美一级片免费在线观看 | 在线观看日本中文字幕 | 黄色特级毛片 | 国产精品久久久久无码av | 99最新网址| 亚洲一区二区三区在线免费观看 | 媚药按摩痉挛w中文字幕 | 成人亚洲 | 康妮卡特欧美精品一区 | 91丨九色丨国产在线观看 | 国产88久久久国产精品免费二区 | 国产精品久久久久久久久久久久久久久 | 亚洲免费资源 | 鲁丝片一区二区三区免费入口 | 精品久久久久久久久久久aⅴ | 欧美精品久久天天躁 | 久久精品一二三区 | 亚洲免费网站 | 国产亚洲欧美在线视频 | 性色av一区二区三区在线播放亚… | 亚洲一区二区中文 | 免费在线观看毛片视频 | 国产日产精品一区二区三区四区 |