—— 目录 ——

  • 0. Spring Session 简介
  • 1. 所需的依赖包
  • 2. 配置文件
  • 3. 同域名不同项目的 session 共享
  • 4. 同域名不同二级域名的 session 共享
  • 5. 完全不同域名的 session 共享(单点登录,还不会)

0. Spring Session 简介

解决 session 共享问题,将 session 存入到 Redis 之中
spring-session 代替的时原本的 httpSession,相当于做代理

下面的操作是基于已经搭建完成 SSM 环境的

1. 所需的依赖包

Spring Session 和 Redis 整合需要的包

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
    <version>2.5.1</version>
</dependency>

Redis 自身需要的包

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.6.3</version>
</dependency>

2. 配置文件

spring-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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 支持注解 -->
    <context:annotation-config/>

    <!-- 用于配置 SpringSession 的 bean 标签 -->
    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <!-- session 的最大生命周期,单位是秒,默认是 1800,也就是 30 分钟 -->
        <property name="maxInactiveIntervalInSeconds" value="1800"/>
    </bean>

</beans>

记得将它导入 applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="classpath:spring-*.xml"/>
</beans>

然后需要再 web.xml 中配置过滤器

<!-- 配置过滤器 -->
<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>

这样就初步配置好了,使用 session 的方法没有变
还是和以前一样 request.getSession().setAttributerequest.getSession().getAttribute

3. 同域名不同项目的 session 共享

但以上只能实现 同域名 同项目 的 session 共享,注意需要同时满足两个”同“
如果是不同项目,那 session 将无法共享

原因是 cookie 存放的位置在各自的项目路径下,不同项目的 cookie 路径各不相同
所以两个 cookie 在不同的路径下,都无法访问到对方的 session (不能跨路径)

所以,想要做到不同项目的 session 共享,需要改变 cookie 存放的位置
spring-sessio.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 支持注解 -->
    <context:annotation-config/>

    <!-- 用于配置 SpringSession 的 bean 标签 -->
    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <!-- session 的最大生命周期,单位是秒,默认是 1800,也就是 30 分钟 -->
        <property name="maxInactiveIntervalInSeconds" value="1800"/>

        <!-- 注入一个 Cookie 的序列化规则对象 -->
        <property name="cookieSerializer" ref="defaultCookieSerializer"/>
    </bean>

    <!-- 配置 Cookie 序列化规则,用于改变 Cookie 的存放规则 -->
    <bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer">
        <!-- 设置 SpringSession 的 SessionId 存放在域名的根路径下,实现同域名不同项目的 Session 共享 -->
        <property name="cookiePath" value="/"/>
    </bean>
</beans>

其实就是修改了 cookie 的存放路径,放在了域名的根目录下,这样所有项目的 cookie 放在一个相同的路径下,就实现了不同项目共享 session 了


4. 同域名不同二级域名的 session 共享

上面已经基本上能达成大部分要求了
但如果是同一域名不同二级域名呢?那就还是不行

原因就是 cookie 虽然存放在域名的根路径下了,但如果二级域名不同,就相当于是存放在不同域名的根路径下,这就又导致了 cookie 没在一起,无法共享 session

那么既然路径可以设置为根路径,那域名同理,也可以设置根域名
所以解决方法就是指定 cookie 存放在根域名下,这样所有 cookie 都存放在根域名下的根路径,就都可以共享 session 啦!

修改配置如下(值修改序列化规则):

<!-- 配置 Cookie 序列化规则,用于改变 Cookie 的存放规则 -->
<bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer">
    <!-- 设置 SpringSession 的 SessionId 存放在域名的根路径下,实现同域名不同项目的 Session 共享 -->
    <property name="cookiePath" value="/"/>

    <!-- 设置 SpringSession 的 SessionId 存放在根域名下(改为自己的域名就行了) -->
    <property name="domainName" value="localhost"/>
</bean>

5. 完全不同域名的 session 共享(单点登录,还不会)

完毕,以上已经基本上解决了现在的我们能遇到的情况
但我们又会想,如果是完全不同的两个域名呢?

完全不同的两个域名的 session 共享,有一个功能我们可能听说过
那就是 单点登录 (Single Sign On 简称 SSO)
要实现单点登录,就相当于实现完全不同的两个域名之间的 session 共享

但这个功能已经不是 SpringSession 能完成的了,需要额外写一个系统来完成这个功能(还不会)

期待日后的学习咯~


仰望星空,何尝不是凝视深渊,所以哇星星也在看着你(IceClean)