Spring Session:入门案例

Spring Session provides an API and implementations for managing a user’s session information.

Spring Session提供了一种用于管理用户session信息管理的API。

Spring Session特点

         传统的Servlet应用中,Session是存储在服务端的,即:Session信息与特定的Web服务相互绑定。Spring Session提供了一种支持分布式session的解决方案,而无需与特定应用容器相绑定。

  • HttpSession:支持以应用容器中立的方式替换HttpSession,支持在Http请求头中提供session IDs,以便与Restful API配合使用。
  • WebSocket:提供了WebSocket消息通信中保持HttpSession会话的能力。
  • WebSession:允许以应用容器中立的方式替换 Spring WebFlux 的 WebSession。

核心模块

        Spring Session由以下模块组成,

  • Spring Session Core:提供Spring Session 核心功能和 API
  • Spring Session Data Redis:提供由 Redis 支持的 SessionRepository 和 ReactiveSessionRepository 实现,以及配置支持
  • Spring Session JDBC:提供由关系型数据库支持的SessionRepository实现,以及配置支持
  • Spring Session Hazelcast:提供由Hazelcast支持的SessionRepository实现,以及配置支持
  • Spring Session MongoDB:提供由MongoDB支持的SessionRepository实现,以及配置支持

Spring Session解决的问题

        当用户和web应用交互时,服务端创建一个Session去追踪用户的操作。这个Session可以存储与用户相关的信息,例如:用户行为,登录状态,购物车内容等等。但是,Session在集群环境中存在问题,因为session被存储在服务内存中。

        如上如所示,假定:Spring App#2接收到了session #3,该服务端应用无法获取到session数据,因为Spring App#1和Spring App#2的session信息是独立存储在各自的应用内存中的。这对集群环境是一个问题。

        为了解决这个问题,我们必须想办法实现session共享,

         如上图所示,通过session共享,可以使得每个应用都能访问到session存储信息。Spring Session正是在应用和session管理之间提供了一个抽象层,将session数据存储在各种持久化存储中,例如:关系型/非关系型数据库中。

        通过SpringSession,你可以使用相同的API去管理session,而无需例会session是如何进行持久化存储的,同时也可以无痛的切换持久化存储方案且无需改动任何代码。

        此外,SpringSession也提供了session过期和不同web应用之间的跨上下文通信机制。

Spring Session简化了web应用的session管理,使得开发者可以专注于构建应用程序的核心功能。

Spring Session的应用场景

        以下是Spring Session的一些应用案例:

  • 分布式web应用:如果网络应用程序分布在多个服务器上,那么管理用户会话可能会很困难。Spring Session 可以将会话数据存储在共享数据库或 Redis 中,让所有服务器都能访问和更新会话数据。
  • 会话拓展能力:在用户并发量较高的大型web应用中,将会话信息存储在服务器内存中会导致可拓展性问题。Spring Session 可以将会话数据存储在持久化存储中,从而提高可扩展性并降低内存溢出的风险。
  • session备份和恢复:将会话数据存储在持久性存储中,还能在服务器出现故障或停机时提供备份和恢复会话数据的机制。

Quick Start

        官网文档:Samples and Guides (Start Here) :: Spring Session。

        以下使用Spring Session Data Redis核心模块,实现一个Spring Session快速入门案例。

引入依赖

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

        可以看到Spring session data redis内置了spring data redis依赖,

配置session存储类型

        在application.proeprties文件中,配置session数据存储类型为Redis,

#session store type
spring.session.store-type=redis

        相当于为SpringBoot应用添加了@EnableRedisHttpSession注解,

        得益于SpringBoot autoConfigure自动装配的特点,我们可以进行少量的配置即可。此处我们可以去查看一下spring session自动装配的类为SessionAutoConfiguration

org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,

        点进去看一下自动装配生效的条件是:Session接口存在,

        我们已经引入了Spring Session相关的依赖,那么Session接口自然是存在的。

其它配置

        此外,我们还可以配置如下信息,会话过期时间、Session刷新模式、redis-session命名空间,

server.port=8080

#session store type
spring.session.store-type=redis
# Session timeout(单位为秒s). If a duration suffix is not specified, seconds is used.(默认为30min)
server.servlet.session.timeout=3600
# Sessions flush mode.(默认为ON_SAVE)
spring.session.redis.flush-mode=on_save
# Namespace for keys used to store sessions.(默认为spring:session)
spring.session.redis.namespace=spring:session

Redis连接配置

        Spring Boot自动创建了RedisConnectionFactory用于将spring Session连接到端口为6379的Redis Server。在生产环境中,建议更新Redis服务的配置端点信息。

# redis
spring.redis.host=localhost
spring.redis.password=
spring.redis.port=6379

注解:启用Redis-Session存储

        在启动类上使用@EnableRedisHttpSession注解,其作用是:用于创建一个名为 springSessionRepositoryFilter 的 Spring Bean,它实现了Filter过滤器。该过滤器负责替换 HttpSession 实现,使其由 Spring Session 支持。简单讲:就是

@SpringBootApplication
@EnableRedisHttpSession
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

案例测试

        以上步骤完成之后,启动SpringBoot应用成功,其实就已经整合完成了。但是却感受不到任何效果。以下我们从一个案例感受一下Session存储用户信息的作用。

案例描述

创建两个接口:

①app/addUser?id=XX:创建一个id为指定XX值的用户,并将用户信息存储到Session中

②/app/getUser?id=XX:用于从Session中获取指定id的用户信息

SysUser类

package com.example.demo.model.entity;

import java.io.Serializable;

public class SysUser implements Serializable {
    private static final long serialVersionUID = -1802561599630491376L;
    private Integer id;
    private String name;
    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public SysUser() {
    }

    public SysUser(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "SysUser{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

创建接口

package com.example.demo.web;

import com.example.demo.model.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@Slf4j
@RestController
@RequestMapping(value = "/app")
public class AppController {

    //接收一个id,创建user并返回
    @GetMapping("/addUser")
    public SysUser addUser(HttpSession session,
                           @RequestParam(value = "id")Integer id){
        SysUser user = new SysUser(id, "张三", 18);
        //设置user信息到session中
        session.setAttribute(String.valueOf(id),user);
        log.info("create SysUser:{}",user);
        return user;
    }

    //接收一个id,获取Session中存储的user信息
    @GetMapping("/getUser")
    public SysUser getUser(HttpSession session,
                           @RequestParam(value = "id")Integer id){
        SysUser user = (SysUser) session.getAttribute(String.valueOf(id));
        log.info("get SysUser:{}",user);
        return user;
    }

}

 测试接口

(1)app/addUser?id=1,创建一个用户,

        此时查看redis数据库,会看到对应的信息,

 (2)获取用户信息:/app/getUser?id=1,

        查看请求头和响应头中,会看到cookie中已经产生了SESSION键,

 

分布式案例测试

        以上只是单体应用,我们的访问接口都是8080,我们重新启动一个8001的web应用,然后访问getUser接口,看看能不能访问到session中存储的用户信息。

        启动8001端口的应用,访问接口,可看到成功访问到用户信息,

         另外,我们对比Cookie中的SESSION值,也是相同的,

        加入我们更换浏览器访问呢?可以看到SESSION对应的值变了,接口响应200正常,但是返回接口为null,找不到对应的用户信息,这和我们的预期是一致的。

 

        此时查看Redis数据库,会发现多了一条SESSION会话信息,

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/407253.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

聚道云软件连接器:高科技企业财务自动化,提升效率准确性!

客户介绍&#xff1a; 某互联信息技术有限公司是一家专业从事信息技术服务的高科技企业&#xff0c;在业内享有较高的知名度和影响力。近年来&#xff0c;公司业务快速发展&#xff0c;对信息化建设提出了更高的要求。 客户痛点&#xff1a; 在传统情况下&#xff0c;该公司的…

【探索Linux】—— 强大的命令行工具 P.23(线程池 —— 简单模拟)

阅读导航 引言一、线程池简单介绍二、Linux下线程池代码⭕Makefile文件⭕ . h 头文件✅Task.hpp✅thread.hpp✅threadPool.hpp ⭕ . cpp 文件✅testMain.cpp 三、线程池的优点温馨提示 引言 在Linux下&#xff0c;线程池是一种常见的并发编程模型&#xff0c;它能够有效地管理…

大模型综述总结--第一部分

1 目录 本文是学习https://github.com/le-wei/LLMSurvey/blob/main/assets/LLM_Survey_Chinese.pdf的总结&#xff0c;仅供学习&#xff0c;侵权联系就删 目录如下图 本次只总结一部分&#xff0c;刚学习有错请指出&#xff0c;VX关注晓理紫&#xff0c;关注后续。 2、概述…

字符函数和字符串函数(C语言进阶)(一)

前言 C语言中对字符和字符串的处理是很频繁的&#xff0c;但是c语言本身是没有字符串类型的&#xff0c;字符串通常放在常量字符串中或着字符数组中。 字符串常量适用于哪些对它不做修改的字符串函数。 1、函数介绍 1.1 strlen strlen&#xff1a;计算字符串长度 看一个代码&…

“AI教父”李一舟翻车,中国AI培训路在何方

近日&#xff0c;AIGC领域掀起了一场不小的风波&#xff0c;知名AI博主李一舟在各大平台推出的AI课程突然下架&#xff0c;其账号遭到禁止关注的情况。 这一事件不仅引发了广泛关注和热议&#xff0c;更让许多真正想学习AIGC的用户感到迷茫和困惑&#xff1a;在众多的AIGC课程中…

ONLYOFFICE 桌面编辑器现已更新至v8.0啦

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

一个div最简方法画太极图

一个div最简方法画太极图 直接上代码&#xff0c;一目了然 html <div class"太极图"/>css .太极图 {position: relative;width: 400px;height: 400px;background: linear-gradient(to right,white 50%,black 50%);border-radius: 50%;box-shadow:0 0 12px …

c#高级——插件开发

案例&#xff1a;WinForm计算器插件开发 1.建立插件库&#xff0c;设置各种自己所需的插件组件 如下图所示&#xff1a;进行了计算器的加减法插件计算组件 Calculator_DLL为总插件父类 Calculator_DLL_ADD 为插件子类的控件对象 Calculator_DLL_Sub Calculator_DLL_Factory 为…

Map集合特点、遍历方式、TreeMap排序及Collections和Arrays

目录 ​编辑 一、集合框架 二、 Map集合 特点 遍历方式 HashMap与Hashtable的区别 TreeMap Collections Arrays 一、集合框架 二、 Map集合 Map集合是一种键值对的集合&#xff0c;其中每个键对应一个值。在Java中&#xff0c;Map接口定义了一种将键映射到值的数据结…

【Ubuntu】使用WSL安装Ubuntu

WSL 适用于 Linux 的 Windows 子系统 (WSL) 是 Windows 的一项功能&#xff0c;可用于在 Windows 计算机上运行 Linux 环境&#xff0c;而无需单独的虚拟机或双引导。 WSL 旨在为希望同时使用 Windows 和 Linux 的开发人员提供无缝高效的体验。安装 Linux 发行版时&#xff0c…

喝多少瓶汽水

喝多少瓶汽水 题目描述&#xff1a;解法思路&#xff1a;解法代码&#xff1a;运行结果: 题目描述&#xff1a; 水已知1瓶汽水1元&#xff0c;2个空瓶可以换⼀瓶汽水&#xff0c;输入整数n&#xff08;n>0&#xff09;&#xff0c;表示n元钱&#xff0c;计算可以多少汽水&a…

Unity(第四部)新手组件

暴力解释就是官方给你的功能&#xff1b;作用的对象上面如&#xff1a; 创建一个球体&#xff0c;给这个球体加上重力 所有物体都是一个空物体&#xff0c;加上一些组件才形成了所需要的GameObject。 这是一个空物体&#xff0c;在Scene场景中没有任何外在表现&#xff0c;因为…

通过Colab部署Google最新发布的Gemma模型

Gemma的简单介绍 Gemma 是一系列轻量级、最先进的开放式模型&#xff0c;采用与创建 Gemini 模型相同的研究和技术而构建。 Gemma 由 Google DeepMind 和 Google 的其他团队开发&#xff0c;其灵感来自 Gemini&#xff0c;其名称反映了拉丁语 gemma&#xff0c;意思是“宝石”…

RT-Thread-快速入门-3-内存管理

内存管理 定义与作用 内存池管理 基础定义 内存池是一种管理固定大小内存块的机制&#xff0c;主要用于减少碎片化&#xff0c;提高内存分配效率。在 RT-Thread 中&#xff0c;内存池允许用户预分配一定数量的具有相同大小的内存块&#xff0c;应用程序可以从中快速分配和释放内…

【Java程序设计】【C00287】基于Springboot的疫情防控期间某村外出务工人员管理系统(有论文)

基于Springboot的疫情防控期间某村外出务工人员管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的疫情防控期间某村外出务工人员信息管理系统 本系统分为系统功能模块、管理员功能模块、用户功能模块、采集…

第三百六十五回

文章目录 1. 概念介绍2. 方法与信息2.1 获取方法2.2 详细信息 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何获取设备信息"相关的内容&#xff0c;本章回中将介绍如何获取App自身的信息.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本…

C++的vector容器->基本概念、构造函数、赋值操作、容量和大小、插入和删除、数据存取、互换容器、预留空间

#include<iostream> using namespace std; #include <vector> //vector容器构造 void printVector(vector<int>& v) { for (vector<int>::iterator it v.begin(); it ! v.end(); it) { cout << *it << " "…

Redis中的rdb和aof

Redis中的rdb和aof 持久化流程RDB机制redis.conf中rdb的配置save bgsave 自动化 rdb触发的三种方式save 命令bgsave命令自动触发 rdb的优势劣势 AOFaof原理aof配置文件重写原理aof的三种触发机制 appendfsyncaof fix工具 redis-check-aof练习aofaof的优缺点 redis是一个内存数据…

GEE必须会教程—Map工具的使用

一个星期的时间&#xff0c;跟着小编的角度&#xff0c;我们已经学习了数值、字符串、字典、列表、日期、矩阵等基本的编程数据类型&#xff0c;这些是学习任何一门编程语言都需要掌握的知识&#xff0c;还有不懂得赶紧关注小编&#xff0c;进行主页查看过往文章&#xff01;! …