文档章节

Spring Boot 解决方案 - 会话

o
 osc_w9s1w4o0
发布于 2019/03/29 22:32
字数 1088
阅读 0
收藏 0

精选30+云产品,助力企业轻松上云!>>>

连接无状态

使用 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() 手动使会话失效并清理会话数据

会话监听器

会话的生命周期分别为创建、失效和创建与失效之间,而会话监听器是为了满足会话生命周期中触发相应事件的需要,HttpSessionListenerHttpSessionAttributeListener 两个监听器接口分别满足了会话的各个生命周期。使用监听器只需实现这些接口然后标注 @WebListener 注解即可,下面会有实现的例子。

针对会话的监听器

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

@WebListener
public class SessionListener implements HttpSessionListener {
	public void sessionCreated(HttpSessionEvent event) {
		// ...
    }
	public void sessionDestroyed(HttpSessionEvent event) {
		// ...
    }
}

针对会话属性的监听器

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

@WebListener
public class SessionListener implements HttpSessionBindingListener {
	public void attributeAdded(HttpSessionBindingEvent event) {
		// ...
	}
	
	public void attributeRemoved(HttpSessionBindingEvent event) {
		// ...
    }
    
    public void attributeReplaced(HttpSessionBindingEvent event) {
		// ...
    }
}

使监听器生效

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

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

分布式会话

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

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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.session</groupId>
	<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

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

spring:
  session:
    store-type: redis
  redis:
    host: 127.0.0.1
    port: 6379

会话安全问题

关于会话安全问题,由于了解知识尚浅,暂且不做探讨,后续会补充该部分。

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
SpringCloud微服务(一)之什么是微服务

文章目录 什么是微服务 SpringCloud spring boot与spring cloud的关系 dubbo和spring cloud 什么是微服务 微服务架构是一种架构模式,他提倡将单一的应用程序划分成一组小的服务,每个服务运...

Xiao爱好
05/18
0
0
集群化部署,Spring Security 要如何处理 session 共享?

前面和大家聊了 Spring Security 如何像 QQ 一样,自动踢掉已登录用户(Spring Boot + Vue 前后端分离项目,如何踢掉已登录用户?),但是前面我们是基于单体应用的,如果我们的项目是集群化...

江南一点雨
05/18
2
0
(转)Spring Boot(三):Spring Boot 中 Redis 的使用

http://www.ityouknow.com/springboot/2016/03/06/spring-boot-redis.html Spring Boot 对常用的数据库支持外,对 Nosql 数据库也进行了封装自动化。 Redis 介绍 Redis 是目前业界使用最广泛...

osc_chydd7b8
2019/04/13
21
0
一次子线程事务回滚实践笔记-编程式事务

(一)问题的引出、主要解决手段 在线程中使用 batchupdate ,中的每一条记录都会自动的commit(但仍使用一个数据库连接会话,有点像hibernate一级缓存的概念,多个事务,一个会话),如果有...

osc_h3robkrt
2018/02/26
2
0
22.Spring-Boot中Spring Session介绍

官方文档:https://docs.spring.io/spring-session/docs/2.0.2.RELEASE/reference/html5/ 在单应用中我们的session来保存用户信息,通常会保存在服务器中(如tomcat),但是我们把应用搭建成...

osc_y8w65yuq
01/15
3
0

没有更多内容

加载失败,请刷新页面

加载更多

百度技术沙龙第67期 百度开源专场

本文作者:HelloDeveloper 具体的产品案例,分享百度开源技术最新实践经验。目前这些项目都已经在 github/baidu 上开源。 什么是 PaddlePaddle 深度学习平台? 首先做个简单的介绍,PaddleP...

百度开发者中心
2019/07/23
0
0
Hacker News 简讯 2020-07-10

更新时间: 2020-07-10 01:15 US Supreme Court deems half of Oklahoma a Native American Reservation - (reuters.com) 美国最高法院认为俄克拉荷马州的一半是印第安人保留地 得分:131 | 评...

FalconChen
今天
26
0
OSChina 周五乱弹 —— 求求你吃了我吧,不要再玩弄食物的感情了

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @巴拉迪维 :张喆的单曲《陷阱 》 这首歌已经在网易找不到原唱了,不知道被哪家买了版权。#今日歌曲推荐# 《陷阱 》- 张喆 手机党少年们想听歌...

小小编辑
今天
26
1
清华陈文光教授:AI 超算基准测试的最新探索和实践。

道翰天琼认知智能平台为您揭秘新一代人工智能。 无规矩不成方圆。放在超级计算机的研发领域,没有一个大家普遍接受的算力评测指标,便难以推动超算迅猛发展。 而现在伴随着人工智能的发展,大...

jackli2020
今天
7
0
@RequestMapping, consumes 提交简单有意思的测试

getParm @GetMapping("getParm")public Result getParm(String id){ System.out.println(); return ResultFactory.success(id);} 等同于 == bodyParm @PostMapping("bodyParm......

莫库什勒
今天
25
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部