一、HttpSession的实现流程
-
当用户访问服务器端时,服务器端会判断请求是否携带包含JSESSIONID的Cookie。如果没有携带,服务器端会创建一个Cookie,key为JSESSIONID,value是长字符串(唯一字符串)。同时会实例化一个Session对象。把Session对象放入到全局Map中,Map的key是Cookie的value,Map的value就是Session对象。同时设置Session对象属性的值,记录creationTime创建实现、id是JSESSIONID对应值、lastAccessedTime最后一次访问时间、maxInactiveInterval 最大存活时间
-
服务器响应给客户端结果,响应对象中包含Cookie内容,Cookie就会存储在客户端。
-
客户端再次请求服务器端时会自动携带Cookie内容。
-
服务器端再次接收请求后发现请求中Cookie带有JSESSIONID,根据JSESSIONID的值进行从Map中取出Session对象,会判断lastAccessedTime和maxActiveInterval属性,判断Session是否失效,如果失效执行a)步骤重新创建Session对象。如果没有失效修改lastAccessedTime为当前访问时间。
二、Tomcat中的HttpSession实现
当向Session作用域存储值时执行上面Session原理,把Session对象取出后,Session作用域的值就存储在全局Map属性(此Map属性是Session对象的全局属性)
既然HttpSession存储值时是一个全局Map,所以依然可以使用Redis这种键值对NoSQL数据库来替代这个Map,也就是存自定义实现时用Redis存储以前放在Session中值。
三、使用
(1)导入依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
(2)编辑配置文件
server:
port: 8000
spring:
redis:
host: 192.168.8.128
(3)编辑启动类
-
/**
-
* EnableRedisHttpSession - 让Spring Session分布式会话共享技术生效。
-
*/
-
@SpringBootApplication
-
@EnableRedisHttpSession
-
public
class
Web1App{
-
public
static
void
main
(String[] args){
-
SpringApplication.run(Web1App.class, args);
-
}
-
}
(4)编辑控制器
-
@RestController
-
public
class
Web1Controller {
-
@RequestMapping("/set")
-
public String
demo
(HttpSession session, String attName, String attValue){
-
session.setAttribute(attName, attValue);
-
return
"WEB1工程:已设置' " + attName +
" = " + attValue +
" '到会话变量作用域";
-
}
-
@RequestMapping("/get")
-
public String
demo
(HttpSession session, String attName){
-
Object
attValue
= session.getAttribute(attName);
-
System.out.println(
"从会话中获取" + attName +
"变量,值是:" + attValue);
-
return
"WEB1工程:从会话中获取" + attName +
"变量,值是:" + attValue;
-
}
-
}
四、@EnableRedisHttpSession注解属性
-
@SpringBootApplication
-
@EnableRedisHttpSession(redisNamespace = "bjsxt:session", maxInactiveIntervalInSeconds = 3600,
-
flushMode = FlushMode.ON_SAVE, saveMode = SaveMode.ON_SET_ATTRIBUTE,
-
cleanupCron = "0 * * * * *"
-
)
-
public
class
Web1App {
-
public
static
void
main
(String[] args) {
-
SpringApplication.run(Web1App.class, args);
-
}
-
}
(1)redisNamespace
保存在redis中的数据的key前缀。默认spring:session。
(2)maxInactiveIntervalInSeconds
会话生命周期。默认1800秒。
(3)flushMode
刷新redis数据的模式。默认ON_SAVE。在保存时才刷新。另一个取值FlushMode.IMMEDIATE,不刷新。
(4)saveMode
保存模式。默认值SaveMode.ON_SET_ATTRIBUTE:在设置session属性时保存。可选值如下:
-
SaveMode.ALWAYS:实时保存。
-
SaveMode.ON_GET_ATTRIBUTE:获取值时才进行保存到Redis。
(5)cleanupCron
清除Redis中数据的表达式。默认”0 * * * * *”
五、Spring Session保存在Redis中的数据
(1)spring:session:sessions:唯一值
value的类型是Hash类型。表示整个Session对象。包括:
-
creationTime :创建会话的时间
-
lastAccessedTime :最后一次访问时间
-
maxInactiveInterval :有效生命周期,默认30分钟
-
sessionAttr:xxx :会话中的attribute值。field中的xxx代表会话中attribute的名字,会话中每个attribute,对应一个field-value对。
(2)spring:session:sessions:expires:唯一值
value的类型是String类型。没有什么特殊内容。表示当前session过期状态。如果没有该属性说明,当前Session已过期。
(3)spring:session:erxpirations:时间戳
value的类型是Set类型。里面存储了这个时间戳是哪个session的。如果过期了,该键值对也会被删除掉。
六、基于Header的Spring Session或改变Cookie名称
(1)修改Cookie名称
添加配置类修改Spring Session 中的Cookie名称。
-
@Configuration
-
public
class
MyConfiguration {
-
@Bean
-
public HttpSessionIdResolver
httpSessionIdResolver
(){
-
// 创建cookie转换器
-
CookieHttpSessionIdResolver
httpSessionIdResolver
=
new
CookieHttpSessionIdResolver();
-
-
// 设置Cookie序列化方案
-
DefaultCookieSerializer
cookieSerializer
=
new
DefaultCookieSerializer();
-
// 设置Cookie的名字
-
cookieSerializer.setCookieName(
"BJSXT");
-
-
httpSessionIdResolver.setCookieSerializer(cookieSerializer);
-
-
return httpSessionIdResolver;
-
}
-
}
(2)设置Header
添加配置类修改Spring Session 是基于Header指定名称请求头,代替Cookie。
-
@Configuration
-
public
class
MyConfiguration {
-
@Bean
-
public HttpSessionIdResolver
httpSessionIdResolver
(){
-
HttpSessionIdResolver
httpSessionIdResolver
=
new
HeaderHttpSessionIdResolver(
"MY-SESSION");
-
return httpSessionIdResolver;
-
}
-
}
转载:https://blog.csdn.net/weixin_53455615/article/details/128587358