连接无状态

使用 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

会话安全问题

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

Spring Boot 解决方案 - 会话的更多相关文章

  1. Spring Boot 解决方案 - 配置

    习惯优于配置 Spring Boot 项目的重要思想就是"习惯优于配置",这也是为什么该项目诞生的原因,让开发者免于 Spring 生态中各种项目的配置.尽管如此,但项目中完全零配 ...

  2. Spring Boot 解决方案 - JUnit 测试

    简单的 JUnit 项目 回顾一下创建并运行简单的 JUnit 测试项目,先添加 JUnit 依赖然后编写类似如下模板的测试类,使用 IDE 的话直接用插件运行就行, 使用 Maven 的话运行命令 ...

  3. Failed to bind properties under '' to com.zaxxer.hikari.Hikari DataSource Spring Boot解决方案

    Description: Failed to bind properties under '' to com.zaxxer.hikari.HikariDataSource: Property: dri ...

  4. spring boot(七):springboot+mybatis多数据源最简解决方案

    说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务.我们项目是后者的模式,网上找了很多,大都是根据jpa来做多数据源解决方案,要不就是老的spring多数据源解 ...

  5. 基于Spring Boot/Spring Session/Redis的分布式Session共享解决方案

    分布式Web网站一般都会碰到集群session共享问题,之前也做过一些Spring3的项目,当时解决这个问题做过两种方案,一是利用nginx,session交给nginx控制,但是这个需要额外工作较多 ...

  6. Spring Boot : Whitelabel Error Page解决方案

    楼主最近爱上了一个新框架--Spring Boot, 搭建快还不用写一堆xml,最重要的是自带Tomcat 真是好 pom.xml <?xml version="1.0" e ...

  7. Spring Boot 添加jersey-mvc-freemarker依赖后内置tomcat启动不了解决方案

    我在我的Spring Boot 项目的pom.xml中添加了jersey-mvc-freemarker依赖后,内置tomcat启动不了. 报错信息如下: org.springframework.con ...

  8. Spring Boot 中文乱码问题解决方案汇总

    使用 Spring Boot 开发,对外开发接口供调用,传入参数中有中文,出现中文乱码,查了好多资料,总结解决方法如下: 第一步,约定传参编码格式 不管是使用httpclient,还是okhttp,都 ...

  9. (转)Spring Boot(七):Mybatis 多数据源最简解决方案

    http://www.ityouknow.com/springboot/2016/11/25/spring-boot-multi-mybatis.html 说起多数据源,一般都来解决那些问题呢,主从模 ...

随机推荐

  1. 二、putty的下载安装和基本使用方法教程

    转载自:https://baijiahao.baidu.com/s?id=1597811787635071952&wfr=spider&for=pc PuTTY是一款开源(Open S ...

  2. POST application/json 适用于传递多层的json

    本来以为自己写了那么多post请求,ajax已经难不住了呢, 结果现实无比的残酷, 后台换成了java,发多层级的json,后台就取不到了, 虽然到最后还是配置正确了,..记录下来,引以为戒, axi ...

  3. linux下部署monogoDB服务(以及安装php mogodb扩展)

    这两天网站转移到新的服务器后,登录时出现一个问题,会等待几分钟服务器才响应. 开始以为是nginx服务器的问题,后面经过排查发现是php一个登陆验证的函数的问题,每次跑到这个函数就会迟钝几分钟. 经过 ...

  4. background-clip 和 background-origin 的区别

    background-origin:指定绘制背景图片的起点. background-clip:是对背景图片的剪裁,指定背景图片的显示范围. 1.background-origin:padding  | ...

  5. MFC停靠窗口实现(CDockablePane)

    工作中编写MFC界面程序时用到了停靠窗口,为了避免之后用到时再去查询,这里记录下. 步骤 1.定义一个继承自CDockablePane的类 Class CDockableTest : public C ...

  6. Django基础—1

    一. Django的安装1. 查看已安装的Django的版本     进入到终端以及Python的交互模式    python3/ ipython32. 交互模式中输入import django    ...

  7. 利用foo函数的Bof漏洞攻击:构造攻击字符串

    利用foo函数的Bof漏洞攻击:构造攻击字符串 一.基础知识储备 objdump反汇编指令.gdb函数调试运行.Perl语言.|管道符 二.实验步骤 1. 通过反汇编了解程序功能及代码 ①反汇编查看文 ...

  8. Docker集群管理工具 - Kubernetes 部署记录 (运维小结)

    一.  Kubernetes 介绍 Kubernetes是一个全新的基于容器技术的分布式架构领先方案, 它是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,Kubernete ...

  9. MVC笔记之一:MVC编程模型

    MVC是ASPX.NET用于构造Web应用的一种框架,和传统的ASPX.NET开发模式(Web Form)在架构上相同,同样采用三层框架实现,但相比传输开的模式,各层架构更加规范. 传统三层架构: V ...

  10. JQuery Mobile - 动态修改select选择框的选中项

    <label for="day">选择天</label> <select name="day" id="day" ...