spring session
前言
官网地址:https://docs.spring.io/spring-session/docs/current/reference/html5/guides/java-redis.html
目的:将session持久化,实现session共享,HttpSession的实现被Spring Session替换,操作HttpSession等同于操作redis中的数据。
1、session认识
1.1 Session 与cookie 基础
由于Http 协议是无状态协议,为了记住请求状态, 因此引入了Session和 Cookie 机制。 Session 存在于服务端, Cookie 存在于客户端。 维系客户端与服务端的桥梁, Session 相关的sessionId
1.2 关于HttpServletRequest,HttpSession
HttpSession是存在于HttpServletRequest的一个对象
当服务端往HttpSession中保存一些数据时,HttpServletRequest中自动添加了一个Cookie:JSESSIONID:xxxx,再后续的请求中, 浏览器也是自动的带上了这个Cookie,服务端根据Cookie中的JSESSIONID取到了对应的session。 服务端根据cookie中 的JSESSIONID来辨别身份。
2、spring session
2.1 pom.xml中添加依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--pool-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.2.0</version>
</dependency>
2.2 application.yml 配置
spring:
redis:
timeout: 20s
host: localhost
port: 6379
database: 3
lettuce:
pool:
max-active: 20
max-idle: 10
max-wait: 20s
min-idle: 5
shutdown-timeout: 5000ms
2.3 配置文件
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 300) //session过期时间,否则默认为1800s
public class SessionConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
2.4 验证
@RestController
public class CookieController
{
@Autowired
private StringRedisTemplate stringRedisTemplate;
@RequestMapping("/query")
String query(HttpServletRequest req) {
HttpSession session = req.getSession();
Object value = session.getAttribute("testKey");
System.out.println ("query session");
String sessionId = session.getId ();
System.out.println ("sessionId="+ sessionId);
Cookie[] cookies = req.getCookies ();
if (cookies != null && cookies.length > 0){
for (Cookie cookie: cookies){
System.out.println (cookie.getName ()+":"+cookie.getValue ());
//网页端获取到的sessionID 是经过base64加密的,解密之后与存在redis上是一致的
byte[] decodedCookieBytes = Base64.getDecoder().decode(cookie.getValue ());
String decodeSeesionId = new String(decodedCookieBytes);
System.out.println (cookie.getName ()+":"+ decodeSeesionId);
}
}
return "query Session:\"testKey\"=" + value;
}
}
cookie中的sessionId 与 session.getId() 不一致
原因是cookie中sessionID 经过Base64 加密