SpringSession

第一章 Session会话管理

1.1 Session机制

由于http协议是无状态的协议,每一次对话完成,会话就结束了。服务器不能记住这个人,下次再对话时,服务器会把对话的人当作一个完全的陌生人来对待。

所以需要某种机制来识别具体的用户,这个机制就是session。

1.2 cookie

服务器端需要使用cookie来识别客户。每次http请求时,客户端都会发送相应的cookie信息到服务端。

第一次创建Session时,服务器端会在http协议中向客户端的cookie中记录一个sessionID,以后每次请求把这个会话ID发送到服务器端,这样服务器端就知道客户端是谁了。

1.3 url重写

如果客户端浏览器禁用了cookie,就会使用url重写的技术来进行session会话跟踪,即每次http交互,url后面都会被附加上一个注入sessionId=xxxxxxxx这样的参数,服务端据此来识别客户端是谁。

1.4 session存放机制

Session容器对象中key是sessionid,value是session对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-33beiDLn-1666596165518)(C:\Users\ADMINI~1\AppData\Local\Temp\WeChat Files\e3819f39968460098f9e8f2f25aed90.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F4EXjAMI-1666596165519)(C:\Users\ADMINI~1\AppData\Local\Temp\WeChat Files\a79ce0ebe08c8e5feb12963cc407eba.jpg)]

1.5 集群丢失session原因

session容器不共享

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T2jPyc9f-1666596165519)(C:\Users\ADMINI~1\AppData\Local\Temp\WeChat Files\5b835ec0f9d31ada68c8addcfc790b8.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wd24xE0M-1666596165520)(C:\Users\ADMINI~1\AppData\Local\Temp\WeChat Files\aee564468cfc63ee54a7c11dfcd00df.jpg)]

1.6 session会话共享方案

第一种:使用容器扩展插件来实现,比如基于tomcat的tomcat-redis-session-manager插件,基于jetty的jetty-session-redis插件,memcached-session-manager插件。

其底层是,复制session到其他服务器,所以会有一定延迟,也不能部署太多服务器。

第二种:使用Nginx负载均衡的ip_hash策略实现用户每次访问都绑定到同一台具体的后台tomcat服务器实现session。但ip不能变,如果手机换了基站,ip就会变,导致session丢失。

第三种:自己写一套session会话管理的工具类,在需要使用会话的时候都从自己的工具类中获取,而工具类后端存储可以放到redis中。

第四种:使用框架的会话管理工具,也就是springsession。

第二章 Springsession简介

springsession把servlet容器实现的httpsession替换为springsession专注于解决session管理问题,session信息存储在redis中,可简单快速且无缝的集成到应用中。

springsession的特性:

  • 提供用户session管理的API和实现
  • 提供httpsession,一种里的方式取代为把容器的session,比如tomcat中的session
  • 支持集群的session处理,不必绑定到具体的web容器去解决集群下的session共享问题。

2.1 同域名下,同项目下的session共享

<!--要使用springsession,需要引入依赖包-->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>	<!--这里需要redis用来存储sessionId-->
    <version>1.3.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>

<!--依赖加完后,就需要配置applicationContext.xml和springsession.xml-->
applicationContext.xml
	<import resource="springsession.xml">
springsession.xml
    <!--
        启动spring的注解支持,因为springsession中使用到了spring的相关注解,因此需要启动spring的注解这一步可以省略
        通常工作时我们会使用<context:component-scan base-package="com"/>来进行包扫描,这个标签中的功能就包含了
        <context:annotation-config/>的功能,因此实际工作时,这个步骤可以省略。
    -->
    <context:annotation-config/>
    <!--配置一个用于专门配置springsession的bean标签配置-->
    <bean id="redisHttpSessionConfiguration" 	class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">

    </bean>
    <!--配置redis,这是可选的配置步骤,如果当前工程已经配置过redis那么这个配置可以省略-->
    <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="192.168.213.133"/>
        <property name="port" value="6379"/>
    </bean>
   
<!--最后配置web.xml-->
        <!--添加filter,固定的,不能自定义name,引入了springsession-->
    <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>
    <!--这段配置是可选的,实际工作使用springmvc来开发web工程,而web工程不需要启动监听器-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

2.2 同域名下,不同项目下的session共享

<!--只需要修改springsession.xml文件即可-->

 <!--配置一个用于专门配置springsession的bean标签配置-->
    <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <!--注入一个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>

2.3 同根域名,不同二级子域名下的session共享

<!--只需要修改springsession.xml文件即可-->

 <!--配置一个用于专门配置springsession的bean标签配置-->
    <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <!--注入一个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="/"/>
    <property name="domainName" value="myweb.com"/>
</bean>

2.4 单点登陆(完全不同域名session共享)

例如www.taobao.com和www.tmall.com,域名完全不同,但是登录信息确一致
对于不同根域名的场景,要实现一处登录,处处登录,springsession不支持这样的功能。
单点登录(single sign on ,sso)

第三章 springboot整合springsession

<!--加入依赖-->
<!--springboot集成redis起步依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--springsession 将数据存入redis依赖-->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
    <version>1.3.1.RELEASE</version>
</dependency>
#配置文件

#连接redis
spring.redis.port=6379
spring.redis.host=192.168.213.133
#设置session生命周期
server.reactive.session.timeout=30m

#指定Cookie的存放路径为根路径,用于实现同域名不同项目的session共享
server.servlet.session.cookie.path=/

#指定cookie的存放路径为根域名,用于实现同根域名,不同二级子域名的session共享
server.servlet.session.cookie.domain=myweb.com

#如果上面两个都没有,则就是同域名同项目下的session共享

放路径为根路径,用于实现同域名不同项目的session共享
server.servlet.session.cookie.path=/

#指定cookie的存放路径为根域名,用于实现同根域名,不同二级子域名的session共享
server.servlet.session.cookie.domain=myweb.com

#如果上面两个都没有,则就是同域名同项目下的session共享


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值