傳統的session是維護在內存中的,如果部署多個服務,通過ngix轉發,用戶登錄完成後的請求可能轉發到另外一個服務上去,內存中就沒有用戶的session,就會判定爲用戶沒有登錄,spring-session項目可以把session維護到redis等數據庫中,這樣多個服務可以共用session,就可以解決上面遇到的問題。下面就用redis保存session示例。
需要添加的依賴
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<!-- 緩存 -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>${redisson.version}</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>4.0.2</version>
</dependency>
配置連接redis
文件名爲applicationContext-cache-single.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:redisson="http://redisson.org/schema/redisson"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://redisson.org/schema/redisson http://redisson.org/schema/redisson/redisson.xsd">
<!--使用kryo序列化方式-->
<bean id="kryoCodec" class="org.redisson.codec.KryoCodec"/>
<redisson:client id="redissonClient" codec-ref="kryoCodec">
<redisson:single-server address="redis://127.0.0.1:6379"/>
</redisson:client>
</beans>
配置相關bean
<import resource="classpath:applicationContext-cache-single.xml"/>
<!-- session交給redis管理 -->
<bean id="redissonHttpSessionConfiguration"
class="org.redisson.spring.session.config.RedissonHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="1800"/>
</bean>
<!--這個是設置cookie保存的位置,需要不同服務指定成一樣的,不然無法公用cookie-->
<bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer">
<property name="cookieName" value="GARDPAY_SESSION_ID"/>
<property name="cookiePath" value="/"/>
</bean>
這裏只是初始化了一些相關配置,真正能夠把session,從請求中找出,保存到數據庫中需要通過過濾器實現
過濾器配置
<!-- spring-session過濾器 -->
<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>
這裏的DelegatingFilterProxy是一個代理過濾器,真正的過濾器是springSessionRepositoryFilter,這個過濾器是我們創建redissonHttpSessionConfiguration這個bean的時候這個bean內部生產的。
測試
@GetMapping("/put.pub")
public Map<String, String> put(HttpServletRequest request) {
request.getSession().setAttribute("aaa", "佔旭鵬");
Map<String, String> map = new HashMap<>();
map.put("success", "成功");
return map;
}
@GetMapping("/get.pub")
public Map<String, Object> get(HttpServletRequest request) {
Object result = request.getSession().getAttribute("aaa");
Map<String, Object> map = new HashMap<>();
map.put("aaa", result);
return map;
}
把項目放在兩個端口下跑起來,一個端口put數據,兩個端口下都可以取到,說明已經session共享成功了