中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis如何實現Session共享

發布時間:2020-07-30 16:50:18 來源:億速云 閱讀:199 作者:Leah 欄目:關系型數據庫

這篇文章運用簡單易懂的例子給大家介紹Redis如何實現Session共享,代碼非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

Redis實現Session共享

這幾天在做session共享這么一個小模塊,也查了好多資料,給我的感覺,就是太亂了,一直找不到我想要的東西,幾乎全部實現方法都與我的想法不一樣,在這里,我總結一下自己是如何用Redis實現session共享的,方便自己以后查詢,也希望能給有這方面需求的朋友一些幫助。


先說一下我的開發環境:nginx、redis、tomcat,用moven構建項目,jetty服務器運行,所以在這里,下面也會涉及一下如何用maven打war包,部署在tomcat上運行。

redis是一個key-value數據庫,存值取值,全靠這個key了,這里啰嗦一句,因為原創,專業的介紹我就不粘貼了,想了解的官方介紹的可以自行search.

pom.xml中配置:

<!-- redis -->  
<dependency>  
<groupId>redis.clients</groupId>  
<artifactId>jedis</artifactId>  
<version>2.8.1</version>  
</dependency>  
<dependency>  
<groupId>org.springframework.data</groupId>  
<artifactId>spring-data-redis</artifactId>  
<version>1.7.2.RELEASE</version>  
</dependency>

aplicationContext-redis.xml中配置

<!-- redis 客戶端配置 -->  
   <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">  
       <property name="maxTotal" value="${jedisPoolConfig.maxTotal}"/>  
       <property name="maxIdle" value="${jedisPoolConfig.maxIdle}"/>  
       <property name="maxWaitMillis" value="${jedisPoolConfig.maxWaitMillis}"/>  
       <property name="testWhileIdle" value="true"/>  
       <property name="testOnBorrow" value="false"/>  
       <property name="testOnReturn" value="false"/>  
   </bean>  
   <bean id="readJedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
       <property name="hostName" value="${jedis.read.host}" />  
       <property name="port" value="${jedis.read.port}" />  
       <property name="password" value="${jedis.read.password}" />  
       <property name="timeout" value="${jedis.read.timeout}" />  
       <property name="database" value="${jedis.read.database}" />  
       <property name="poolConfig" ref="jedisPoolConfig" />  
   </bean>  
   <bean id="writeJedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
       <property name="hostName" value="${jedis.write.host}" />  
       <property name="port" value="${jedis.write.port}" />  
       <property name="password" value="${jedis.write.password}" />  
       <property name="timeout" value="${jedis.write.timeout}" />  
       <property name="database" value="${jedis.write.database}" />  
       <property name="poolConfig" ref="jedisPoolConfig" />  
   </bean>  
   <bean id="readRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
       <property name="connectionFactory" ref="readJedisConnectionFactory" />  
   </bean>  
   <bean id="writeRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
       <property name="connectionFactory" ref="writeJedisConnectionFactory" />  
   </bean>

配置完畢后,開始代碼實現:

在LoginController里:

第一步,引入RedisTemplate

@Autowired  
@Qualifier("writeRedisTemplate")  
private StringRedisTemplate writeTemplate;

這里只需要引入writeRedisTemplate即可,在登陸的時候,只負責寫,只有在再次刷新的時候,經過過濾器,才需要讀

第二步,正常登陸流程,登陸成功之后,request還要保存session信息

Redis如何實現Session共享

第三步,設置cookie值,把作為保存userSession信息在redis中的key值存入cookie,刷新瀏覽器的時候,過濾器可以從cookie中取到key值,進而去redis取對應的value值,即userSession

String domain = request.getServerName();  
       String cookieId=MD5Util.MD5Encode("uasLoginer", "UTF-8");  
       //生成token,用作session在redis存儲中的key值      
       StringredisSessionKey= UUID.randomUUID().toString();  
       Cookie uasLoginer = new Cookie(cookieId, redisSessionKey);  
       if (domain.startsWith("uas.")) {  
    uasLoginer.setDomain(domain.substring(4,domain.length()));  
}else {  
    uasLoginer.setDomain(domain);  
}  
       uasLoginer.setMaxAge(60000);  
       uasLoginer.setPath("/");  
       response.addCookie(uasLoginer);

這里cookie跨域setDomain和setPath設置

第四步,把userSession信息存入redis中

RedisTemplate中寫入redis的值要為String類型,需要把userSession對象轉成Json字符串

userSessionString = JSON.toJSONString(userSession);

在轉Json的時候,遇到問題,導入import com.alibaba.fastjson.JSON;一直失敗,發現pom中沒有依賴Json的關系,如果有遇到相同的問題,可以檢查下在pom.xml中是否有關于json的依賴關系,沒的話,在pom.xml中導入json的依賴關系,如下:

<dependency>  
    <groupId>net.sf.json-lib</groupId>  
    <artifactId>json-lib</artifactId>  
    <version>2.3</version>  
    <classifier>jdk15</classifier>  
</dependency>

寫入redis的代碼如下:

writeTemplate.opsForHash().put(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey,redisSessionKey, userSessionString);  
writeTemplate.expire(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey, 1800L, TimeUnit.SECONDS);//設置redis中值的有效期

完成這一操作,用戶的session信息已經存入到redis中,可在redis中查看是否存入。

第五步:進入頁面后,刷新頁面,請求會經過過濾器,在Filter.Java中讀取redis的值并進行一些處理

在過濾器這里,就無法通過注解的方式引入redisTemplate,可以通過如下的方式引入:

BeanFactory beans = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());  
     StringRedisTemplate readTemplate = (StringRedisTemplate) beans.getBean("readRedisTemplate");  
     StringRedisTemplate writeTemplate = (StringRedisTemplate) beans.getBean("writeRedisTemplate");

過濾器從cookie中取出redis的key值,用readTemplate讀出value值

String cookid=MD5Util.MD5Encode("uasLoginer", "UTF-8");  
Cookie[] cookies = req.getCookies();  
String redisSessionKey = "";  
if(cookies != null){  
    for (Cookie cookie : cookies) {  
        if(cookie.getName().equals(cookid)){  
            redisSessionKey = cookie.getValue() ;  
        }  
    }  
}  
UserSession userSession = null;  
String userSessionString = (String) readTemplate.boundHashOps(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey).get(redisSessionKey);  
if(null != userSessionString ){  
    @SuppressWarnings("static-access")  
    JSONObject obj = new JSONObject().fromObject(userSessionString);//將json字符串轉換為json對象  
    userSession = (UserSession)JSONObject.toBean(obj,UserSession.class);  
    writeTemplate.expire(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey, 1800L, TimeUnit.SECONDS);  
    request.getSession().setAttribute(UasContants.USER_SESSION, userSession);  
}  
if (userSession != null) {  
    chain.doFilter(req, res);  
    return;  
}else {  
    res.sendRedirect(UasContants.LOGIN_URL);  
    return;  
}

在這里,另外附上關于web.xml關于LoginFilter的配置,有需要的可以參考下:

<!-- Spring監聽器 -->  
<listener>  
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
</listener>  
<filter>  
    <filter-name>loginFilter</filter-name>  
    <filter-class>com.sfbest.uas.filter.LoginFilter</filter-class>  
    <init-param>  
        <param-name>excludePaths</param-name>  
        <param-value>/login,/user/login,/user/auth</param-value>  
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>loginFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>

按照上面的配置,就可以用redis實現session共享的功能,但我在開發的時候,遇到一個蛋疼的問題,在測試環境上,

把項目部署在兩臺tomcat服務器上的時候,cookie里一直存不進去redis的key值,單臺可以存進去,經過長期的檢測,

終于發現是nginx配置出的問題,引以為戒,深深的陰影。下面我貼出我正常運行時nginx的配置代碼

upstream uassessiontest.d.com {  
        server 10.103.16.226:8088;  
        server 10.103.16.226:8089;  
        }  
       server {  
                 log_format  sf_uastest  '$remote_addr - $remote_user [$time_local] "$request" '  
                                        '$status $body_bytes_sent "$http_referer" '  
                                        '"$http_user_agent" $http_cookie';  
                listen 80;  
                server_name uassessiontest.d.com;  
                access_log /var/log/nginx/uassessiontest.log sf_uastest; 
  
                location / {  
                        rewrite ^/$ /uas/ break;  
                        proxy_pass http://uassessiontest.d.com;  
                }  
        }

紅色的為當初少配的部分,這些部分是的作用是往瀏覽器端寫入cookie值。


關于Redis如何實現Session共享就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

微博| 凤阳县| 湖口县| 灵丘县| 北宁市| 赣榆县| 秦皇岛市| 龙川县| 精河县| 谷城县| 潜山县| 嘉义县| 南溪县| 白山市| 洪雅县| 眉山市| 泉州市| 镇康县| 舒兰市| 梧州市| 曲阜市| 阳泉市| 宁津县| 温宿县| 宁都县| 宜黄县| 武冈市| 惠来县| 沂源县| 镇赉县| 南平市| 中西区| 图木舒克市| 怀柔区| 棋牌| 祁连县| 天等县| 双鸭山市| 双城市| 岑溪市| 长治县|