您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)基于Spring-Session如何實現(xiàn)會話共享,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
前段時間,在對項目權(quán)限框架調(diào)整的時候(SpringSecurity改成Shiro),集成了SpringSession小插件。
由于現(xiàn)今本項目某些特性,暫時無法進行分布式部署,所以對SpringSession并沒有進行深入測試以及生產(chǎn)上部署應(yīng)用,這里只是記錄整合的過程以及一些心得。
網(wǎng)上也看到一些同學(xué)說SpringSession存在一些坑,比如無法實現(xiàn)跨域Session共享,然后通過修改其Cookie生產(chǎn)策略可以進行解決等,因此在生產(chǎn)使用之前,還需進行充分的測試。
學(xué)習(xí)@Configuration、@Bean兩個Spring注解:
Spring中為了減少xml中配置,引入了@Configuration和@Bean注解類。@Configuration注解的類,等價于XML中配置beans,表明這個類是beans定義的源;@Bean注解的方法等價于XML中配置的bean,該方法創(chuàng)建出的實例由Ioc容器管理。
SpringSession核心的配置類為SpringHttpSessionConfiguration(框架也默認提供了Redis、Mongo、Jdbc等實現(xiàn),本項目使用RedisHttpSessionConfiguration)。RedisHttpSessionConfiguration類中最重要的兩個操作就是創(chuàng)建springSessionRepositoryFilter以及sessionRedisTemplate。在創(chuàng)建sessionRedisTemplate時框架會依賴解析RedisConnectionFactory,所以在Spring配置中我們需要定義RedisConnectionFactory;springSessionRepositoryFilter是SpringSession的核心,也是web.xml中Filter代理,整個Session的獲取以及提交都在其里實現(xiàn)。
以下是整個配置的過程:
1、applicationContext-session.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd" default-lazy-init="true"> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.pool.maxTotal}" /> <property name="maxIdle" value="${redis.pool.maxIdle}" /> <property name="minIdle" value="${redis.pool.minIdle}" /> <property name="blockWhenExhausted" value="${redis.pool.blockWhenExhausted}"></property> <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" /> <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> <property name="testOnReturn" value="${redis.pool.testOnReturn}" /> <property name="testWhileIdle" value="${redis.pool.testWhileIdle}" /> <property name="minEvictableIdleTimeMillis" value="${redis.pool.minEvictableIdleTimeMillis}" /> <property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}" /> <property name="numTestsPerEvictionRun" value="${redis.pool.numTestsPerEvictionRun}" /> </bean> <!-- @Important --> <!-- Autowired By Type Of org.springframework.data.redis.connection.RedisConnectionFactory --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="${redis.host}" /> <property name="port" value="${redis.port}" /> <property name="password" value="${redis.password}" /> <property name="database" value="${redis.database}" /> <property name="timeout" value="${redis.timeout}" /> <property name="poolConfig" ref="jedisPoolConfig" /> <property name="usePool" value="true" /> </bean> <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" /> </bean> <bean id="httpSessionMonitorListener" class="com.wuzb.pw.common.session.HttpSessionMonitorListener"></bean> <!-- @Important --> <!-- Cookie strategy is the framework default strategy,But exist cross-domain problem --> <!-- Reason: org.springframework.session.web.http.DefaultCookieSerializer.getCookiePath(HttpServletRequest) --> <bean id="cookieHttpSessionStrategy" class="org.springframework.session.web.http.CookieHttpSessionStrategy"></bean> <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <property name="maxInactiveIntervalInSeconds" value="1800" /> <property name="httpSessionStrategy" ref="cookieHttpSessionStrategy"/> <property name="httpSessionListeners"> <list> <ref bean="httpSessionMonitorListener"/> </list> </property> </bean> </beans>
2、屬性文件config.properties配置如下:
## redis pool config redis.pool.maxTotal=100 redis.pool.maxIdle=20 redis.pool.minIdle=10 redis.pool.blockWhenExhausted=true redis.pool.maxWaitMillis=3000 redis.pool.testOnBorrow=false redis.pool.testOnReturn=false redis.pool.testWhileIdle=true redis.pool.minEvictableIdleTimeMillis=60000 redis.pool.timeBetweenEvictionRunsMillis=30000 redis.pool.numTestsPerEvictionRun=-1 # redis config redis.host=192.168.0.123 redis.port=6379 redis.password=admin-123456 redis.database=0 redis.timeout=3600
3、web.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>editor</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext.xml,classpath:spring/applicationContext-security.xml</param-value> </context-param> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> <!-- CAS 單點退出 --> <filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class>com.wuzb.pw.common.shiro.CustomSingleSignOutFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- POST亂碼處理 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <async-supported>true</async-supported> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <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> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext-mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file></welcome-file> </welcome-file-list> </web-app>
項目中使用的Spring版本4.1.6.RELEASE。其中集成Spring Session所需的Jar如下:
spring-data-commons-1.12.3.RELEASE.jar
spring-data-keyvalue-1.1.3.RELEASE.jar
spring-data-redis-1.7.1.RELEASE.jar
spring-session-1.2.2.RELEASE.jar
spring-session-data-redis-1.2.2.RELEASE.jar
jedis-2.8.1.jar
需要注意的點:
spring-session-data-redis-1.2.2.RELEASE.jar默認依賴spring-data-redis-1.7.1.RELEASE.jar,
若使用spring-data-redis-1.7.3.RELEASE或者更高版本的會出現(xiàn)如下異常:
Caused by: java.lang.NoSuchMethodError: org.springframework.core.serializer.support.DeserializingConverter.<init>(Ljava/lang/ClassLoader;)V at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.<init>(JdkSerializationRedisSerializer.java:53) at org.springframework.data.redis.core.RedisTemplate.afterPropertiesSet(RedisTemplate.java:119) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ... 49 more
在處理分布式Session的案例中,有很多種解決方案。例如基于Tomcat中間件(TomcatRedisSessionManager)基于服務(wù)器基本做會話共享(局限大);基于SpringSession插件實現(xiàn)Session共享;若使用Shiro權(quán)限框架還可以自己實現(xiàn)SessionDao來實現(xiàn)Session共享。這些在后續(xù)時間里,再繼續(xù)探索。
看完上述內(nèi)容,你們對基于Spring-Session如何實現(xiàn)會話共享有進一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。