安装完redis, spring端只要下面这两个bean配置上就可以用了
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?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:context=
"http://www.springframework.org/schema/context"
xmlns:p=
"http://www.springframework.org/schema/p"
xsi:schemaLocation="http:
//www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http:
//www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean
class
=
"org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"
/>
<bean id=
"jedisConnectionFactory"
class
=
"org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
>
<property name=
"port"
value=
"${redis_port}"
/>
<property name=
"hostName"
value=
"${redis_url}"
/>
</bean>
|
官方示例都是零配置的写法,画风变的太大以至于在AbstractHttpSessionApplicationInitializer这里浪费了 很久。其实用上面这种方式,是完全不需要再写AbstractHttpSessionApplicationInitializer的,他们干的是一件 事。
关于子域的坑
发现spring session在获取sessionid时,在CookieHttpSessionStrategy中并没有做跨子域的处理...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
private
Cookie createSessionCookie(HttpServletRequest request,
Map<String, String> sessionIds) {
Cookie sessionCookie =
new
Cookie(cookieName,
""
);
if
(isServlet3Plus) {
sessionCookie.setHttpOnly(
true
);
}
sessionCookie.setSecure(request.isSecure());
sessionCookie.setPath(cookiePath(request));
// TODO set domain?
...
private
static
String cookiePath(HttpServletRequest request) {
return
request.getContextPath() +
"/"
;
}
|
其实这里只要把cookiePath的返回值设置为统一的根路径就能让session id从根域获取了,这样同根下的所有web应用就可以轻松实现单点登录共享session了。既然找到了问题,解决就容易多了,下面列几种解决方案:
- 改spring session源码,并重新打包
- 代码复用CookieHttpSessionStrategy,改cookiePath,并在spring注入时指定自己写的这份Strategy
搭建spring session源码的开发环境太麻烦了,我用的方案2
1
2
3
|
private
static
String cookiePath(HttpServletRequest request) {
return
"/"
;
}
|
并在spring redis中加入如下配置
1
2
3
4
5
6
7
8
|
<bean id=
"redisRepository"
class
=
"org.springframework.session.data.redis.RedisOperationsSessionRepository"
>
<constructor-arg ref=
"jedisConnectionFactory"
/>
</bean>
<bean id=
"cookieHttpSessionStrategy"
class
=
"reyo.sdk.utils.spring.CookieHttpSessionStrategy"
/>
<bean
class
=
"org.springframework.session.web.http.SessionRepositoryFilter"
>
<constructor-arg ref=
"redisRepository"
/>
<property name=
"httpSessionStrategy"
ref=
"cookieHttpSessionStrategy"
/>
</bean>
|
搞定(spring 4.3.0不支持)