Spring Boot 解决方案 - 会话

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Spring Boot 解决方案 - 会话连接无状态使用 HTTP 的连接是无状态的,因此为了应对需要状态的服务例如用户登录,诞生了适合保存状态的设计-会话(session),本文就来探讨一下会话。会话的使用Spring Mvc 中使用会话很简单,在控制器类的方法参数列表中,直接编写 HttpSession 类型的参数,或者参数列表中编写 HttpServletRequest 类,然后使用 getSession() 方法获取会话。

Spring Boot 解决方案 - 会话
连接无状态
使用 HTTP 的连接是无状态的,因此为了应对需要状态的服务例如用户登录,诞生了适合保存状态的设计-会话(session),本文就来探讨一下会话。

会话的使用
Spring Mvc 中使用会话很简单,在控制器类的方法参数列表中,直接编写 HttpSession 类型的参数,或者参数列表中编写 HttpServletRequest 类,然后使用 getSession() 方法获取会话。

下面是使用会话的简单例子,第一次访问时会创建一个无数据的会话,因此获取到的 access 属性为 null ,而当不是第一次访问时,由于属性不为 null 会得到 "NOT THE FIRST TIME ACCESS" 。

@RestController
public class DemoController {

private static final String ACCESS = "access";
@RequestMapping("/")
public String index(HttpSession session) { // or `index(HttpServletRequest req)`
    // then `HttpSession session = request.getSession();`
    if (session.getAttribute(ACCESS) == null) {
        session.setAttribute(ACCESS, true);
        return "FIRST TIME ACCESS";
    }
    return "NOT THE FIRST TIME ACCESS";
}

}
注意:由于用 Mock Mvc 测试获取不到第一次请求 Cookies,因此无法模拟得到正确结果,请使用浏览器或者请求工具测试。

常用方法
上面例子展示了会话的简单使用,其中 HttpSession 接口是 servlet 的标准,而 Spring Mvc 中的会话默认使用 Tomcat 的实现。下面来介绍几个常用方法,更多方法使用请参考这篇文章。

Object getAttribute(String) 方法用来获取会话的属性,若不存在则返回 null
void setAttribute(String, Object) 方法用来设置会话的属性
void removeAttribute(String) 方法用来删除会话的属性
void setMaxInactiveInterval(int) 方法用来设置会话失效时间,单位为秒,设置小于等于零的数则会话永不过期
void invalidate() 手动使会话失效并清理会话数据
会话监听器
会话的生命周期分别为创建、失效和创建与失效之间,而会话监听器是为了满足会话生命周期中触发相应事件的需要,HttpSessionListener 和 HttpSessionBindingListener 两个监听器接口分别满足了会话的各个生命周期。使用监听器只需实现这些接口然后标注 @WebListener 注解即可,下面会有实现的例子。

针对会话的监听器
HttpSessionListener 接口可以算是针对会话的监听器接口,因为它的两个方法分别在会话创建和失效时调用,下面为一个简单的例子,参数列表中 HttpSessionEvent 类可以用 getSession 获取会话。

@WebListener
public class SessionListener implements HttpSessionListener {

public void sessionCreated(HttpSessionEvent event) {
    // ...
}
public void sessionDestroyed(HttpSessionEvent event) {
    // ...
}

}
针对会话属性的监听器
与 HttpSessionListener 监听器接口接管会话生命周期的创建与失效不同,HttpSessionBindingListener 监听器接口负责会话属性的创建与销毁,下面为该监听器的简单例子,参数列表中 HttpSessionBindingEvent 类除了可以用 getSession 获取会话,最主要的是可用 getName 和 getValue 分别获取属性的名字和值。

@WebListener
public class SessionListener implements HttpSessionBindingListener {

public void valueBound(HttpSessionBindingEvent event) {
    // ...
}

public void valueUnbound(HttpSessionBindingEvent event) {
    // ...
}

}
使监听器生效
上面的例子只是编写了监听器的实现,为了使得监听器在项目里生效,还必须在启动类或者配置类上标注 @ServletComponentScan 来扫描这些属于 servlet 组件的监听器,例如下面在配置类上启动 servlet 组件扫描。

@Configuration
@ServletComponentScan // enable scan servlet component
public class ApplicationConf {

// ...

}
分布式会话
若是有多台 Web 服务器提供不同的服务,且要求属于同一会话,上面的单机会话例子就无法满足要求,于是就有了分布式会话即可以共享会话数据。

利用 Spring Session 就可以实现分布式会话,而 Spring Session 的实现可依赖关系数据库或内存数据库,下面例子为 Spring Boot 中导入基于 Redis 实现的 Spring Session 的依赖。

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>


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


<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>


接着在 Spring Boot 的属性配置文件中,添加如下的属性即可,而对于会话的使用和单机会话操作是一样的。

spring:
session:

store-type: redis

redis:

host: 127.0.0.1
port: 6379

会话安全问题
关于会话安全问题,由于了解知识尚浅,暂且不做探讨,后续会补充该部分。
原文地址https://www.cnblogs.com/linzhehuang/p/10624634.html

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
21天前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
38 0
|
6月前
|
缓存 Java Go
解决Spring Data JPA查询存在缓存问题及解决方案
解决Spring Data JPA查询存在缓存问题及解决方案
328 0
|
6月前
|
Java Go Nacos
Spring Cloud Alibaba Nacos配置导入问题解决方案
Spring Cloud Alibaba Nacos配置导入问题解决方案
467 0
|
4月前
|
缓存 前端开发 Java
13:SpringBoot跨域解决方案-Java Spring
13:SpringBoot跨域解决方案-Java Spring
70 0
|
2月前
|
消息中间件 NoSQL Java
Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】
Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】
186 1
|
2天前
|
XML Java C++
【Spring系列】Sping VS Sping Boot区别与联系
【4月更文挑战第2天】Spring系列第一课:Spring Boot 能力介绍及简单实践
23 0
【Spring系列】Sping VS Sping Boot区别与联系
|
4月前
|
安全 前端开发 Java
Spring Security 自定义异常失效?从源码分析到解决方案
Spring Security 自定义异常失效?从源码分析到解决方案
|
2月前
|
XML 监控 druid
【Java专题_02】springboot+mybatis+pagehelper分页插件+druid数据源详细教程
【Java专题_02】springboot+mybatis+pagehelper分页插件+druid数据源详细教程
|
3月前
|
Java Spring
Spring中循环依赖解决方案
Spring中循环依赖解决方案
|
3月前
|
缓存 Java Spring
面试题 : Spring循环依赖问题及其解决方案
面试题 : Spring循环依赖问题及其解决方案