學習Spring Session和Redis解決分布式Session跨域共享問題

學習Spring Session和Redis解決分布式Session跨域共享問題

使用spring Sessionredis解決分布式session跨域共享問題?

現象闡述:

?在項目中前后端代碼未做分離,在兩臺實例的情況下服務正常運行偶爾會彈出類似需要重新登錄的提示,后臺報錯信息

學習Spring Session和Redis解決分布式Session跨域共享問題

這是處理器異常? 原因并不明顯

增加機器實例后,在訪問前端頁面的時候,一直重復訪問登錄頁面,導致頁面302,種種跡象表明是登錄配置的問題引起的。

相關專題推薦:php session (包含圖文、視頻、案例)

問題引入:Session不能共享導致不同機器之間輪詢要求登錄導致最終的服務異常

解決方案:使用Spring Session和redis解決分布式Session跨域共享問題

解決配置:

1 )添加依賴? ? ??

<dependency> ??<groupid>org.springframework.session</groupid> ??<artifactid>spring-session-data-redis</artifactid> ??<version>1.2.0.RELEASE</version></dependency><dependency> ??<groupid>org.apache.velocity</groupid> ??<artifactid>velocity</artifactid> ??<version>1.7</version></dependency>

2?)web.xml配置文件添加:

<!-- 分布式Session共享Filter --> <filter> ??<filter-name>springSessionRepositoryFilter</filter-name> ??<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping> ??<filter-name>springSessionRepositoryFilter</filter-name> ??<url-pattern>/*</url-pattern></filter-mapping>

3) Spring.xml的配置

<!-- 將session放入redis --> <annotation-config></annotation-config><bean> ???<property></property></bean><bean> ???<!-- redis 配置 --> ???<property></property> ???<property></property></bean>

解析:

1、web中DelegatingFilterProxy 類:屬于代理fiter,它會在tomcat啟動后開始加載web.xml中的filter時將filter的管理交給spring中的bean? 也就是第三步的配置 引入RedishttpSessionConfiguration

2、RedisHttpSessionConfiguration繼承了SpringHttpSessionConfiguration這個類,這個類很重要,SpringHttpSessionConfiguration通過@Bean的方式將springSessionRepositoryFilter注入到容器中

學習Spring Session和Redis解決分布式Session跨域共享問題

學習Spring Session和Redis解決分布式Session跨域共享問題

3、SessionRepositoryFilter這個過濾器就是前邊DelegatingFilterProxy查找的過濾器SessionRepositoryFilter是關鍵,具體怎么關聯起來的呢?

如果未指定init-param參數的話,DelegatingFilterProxy就會把filter-name作為要查找的Bean對象,這也是DelegatingFilterProxy類的作用。可以看出每一個請求都會經過該filter,經過該filter的請求也會相應的經過springSessionRepositoryFilter這個過濾器,那么我們就接著看一下springSessionRepositoryFilter這個過濾器?

4、SessionRepositoryFilter的作用就是替換容器默認的javax.servlet.http.HttpSession支持為org.springframework.session.Session。

SessionRepositoryFilter的主要方法和屬性如下:?

學習Spring Session和Redis解決分布式Session跨域共享問題

5、其中SessionRepositoryResponseWrapper、SessionRepositoryRequestWrapper、HttpSessionWrapper為內部類,這個也是很關鍵的。例如SessionRepositoryRequestWrapper類?

學習Spring Session和Redis解決分布式Session跨域共享問題

可以看出SessionRepositoryRequestWrapper繼承了javax.servlet.http.HttpServletRequestWrapper這個類,我們知道HttpServletRequest接口的默認實現是有HttpServletRequestWrapper的,如下?

學習Spring Session和Redis解決分布式Session跨域共享問題

6、因為SessionRepositoryRequestWrapper繼承了HttpServletRequestWrapper,而HttpServletRequestWrapper實現了HttpServletRequest接口,在SessionRepositoryRequestWrapper又重寫了HttpServletRequest接口中的一些方法,所以才會有:getSession、changeSessionId等這些方法。 到此,我們應該大致明白了,原有的request請求和response都被重新進行了包裝。我們也就明白了原有的HttpSeesion是如何被Spring Session替換掉的。

學習Spring Session和Redis解決分布式Session跨域共享問題

學習Spring Session和Redis解決分布式Session跨域共享問題

我們通過快捷鍵查看request.getSession() 的具體實現,就可以看出已經有了SessionRepositoryRequestWrapper 重寫的方法。 上述有兩個默認的實現,一個是原始的,一個是Spring Session實現的,具體選用哪一種作為實現,這就是我們上邊說的DelegatingFilterProxy 代理的作用了,他會將每一個請求過濾,經過DelegatingFilterProxy的每一個請求也會經過springSessionRepositoryFilter過濾器,springSessionRepositoryFilter過濾器就實現了將原有request到SessionRepositoryRequestWrapper的轉換,這就是實現了具體的流程!

request.getSession().setAttribute(name, value)的實現: 追蹤代碼,可以到達下邊內容

學習Spring Session和Redis解決分布式Session跨域共享問題可以看到有Redis相關的操作! 至此,我們應該清楚了,Spring Session的工作原理了!雖然下邊的過程沒有再去介紹,但是已經很清楚的理解了。

相關學習推薦:redis視頻教程

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享