Spring Session Data Redis 配置中遇到的坑

說道Session共享,從網上搜索,有幾種實現方式,比較普遍的 Tomcat Session Redis,這種是需要在tomcat容器裏增加幾個jar包,並修改Tomcat裏的content.xml增加一條語句,實現session共享,此方法依賴於 tomcat.
還有一種是 Spring-Session-Data-Redis,此方法對servlet容器都有效,不侷限於tomcat,也是比較普遍的一種方法,具體可自行百度瞭解
今天要說的是在配置SpringSessionDataRedis過程中遇到的坑
基本配置方式也比較簡單
第一步:pom.xml中引入依賴
首先要引入依賴,此依賴並不是jar,而是一個空包裏面還有對spring-session,redis等幾個必要組件的依賴
<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-redis -->
<dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
            <version>1.3.1.RELEASE</version>
</dependency>
注意:此地方有一個比較坑爹地方,當打開Maven倉庫,可以看到有一個對Spring版本的依賴的要求,對於1.3.1的SpringSession,對Spring的依賴最低4.3.4,如果依賴低於這個版本,則會報錯Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.session.SessionRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}, 特別注意,引入不同的版本時,可能會引起原有jar包版本不兼容
第二步:Spring-mvc.xml中增加 redisHttpSessionConfiguration
    <!-- Spring Session Redis 共享 http://www.cnblogs.com/andyfengzp/p/6434287.html -->
     <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="1800"/>
    </bean>
注意:由於使用了這裏的配置,由redis負責接管Session,原來web.xml裏配置的Session超時時間就會失效了
    <session-config>
        <session-timeout>60</session-timeout>
        <cookie-config>
            <http-only>true</http-only>
        </cookie-config>
    </session-config>

第三步:Web.xml中配置filter

    <!-- Spring Session Redis 共享 需要放在filter的第一個  http://www.cnblogs.com/andyfengzp/p/6434287.html -->
    <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>
注意:這個filter要寫在比較靠前的第一個的位置

以上這幾步配置完成後,基本就可以實現Session的共享了。
但是這裏還有一個情況,項目啓動後,左右的靜態資源都無法訪問了,這個是和原來的版本有不一樣的地方,
Spring4.3,這裏需要注意,所有Spring的xml的配置文件裏標籤要變爲  -4.3.xsd
<!-- 靜態文件資源訪問配置 --> 要注意這裏的靜態文件不要放到WEB-INF裏,要放到項目內,例如項目下的resources
<mvc:resources mapping="/**" location="/resources/" />這樣就可以放行靜態文件的訪問


還有一個比較大的坑,使用Spring Session實際是Spring加入了一個Filter,其本質是:對每一個請求的request都會被DelegatingFilterProxy進行了一次封裝。那麼,在Controller裏面拿出的request實際上是封裝後的request,因爲Session要存在Session,所以調用request.getSession()的時候,實際上拿到是Spring封裝後的session ,因此對於request實際上拿到是Spring封裝後的request。那麼可能會導致Request.getInputStream無法獲取到流數據,對於使用raw格式,即非Key,Value參數的提交 會被Spring-Session獲取,contentTypeapplication/x-www-form-urlencoded時,就會被解析成Paramater,從而導致request.getInputStream的數據再獲取時爲空了。還有就是Controller裏如果用到了request.setCharacterEncoding("GBK"); 設置字符集,這樣的請求也無法生效,因爲request.setCharacterEncoding只有在request.getSession或者request.getParamater之前使用有效,而由於使用Spring Session加入了filter,所以Controller裏的request.setCharacterEncoding這種方式轉編碼就失效了,解決辦法,可以是new String(request.getParameter(key).getBytes(), "GBK"),獲取到參數後轉碼

相關連接





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章