Spring Session:入门案例

news2024/11/15 15:37:55

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会话信息,

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RapidJson开源库使用

1.下载 GitHub - Tencent/rapidjson: A fast JSON parser/generator for C with both SAX/DOM style APIA fast JSON parser/generator for C with both SAX/DOM style API - Tencent/rapidjsonhttps://github.com/Tencent/rapidjson 官方使用手册&#xff1a;RapidJSON: 首页…

码上飞:免费制作自己的ChatBot

今天为大家介绍一款可以免费制作ChatBot的软件开发平台&#xff0c;码上飞CodeFlying&#xff0c;只需几步&#xff0c;即可完成ChatBot的开发&#xff0c;并且支持自定义添加自己的知识库&#xff01; 第一步&#xff1a;访问官网&#xff1a;码上飞 CodeFlying | AI 智能软件…

SpringMVC 学习(一)之 SpringMVC 介绍

目录 1 MVC 介绍 2 SpringMVC 介绍 2.1 SpringMVC 特点 2.2 SpringMVC 的核心组件 2.3 SpringMVC 执行流程 3 参考文档 1 MVC 介绍 MVC (Model View Controller) 是一种设计思想&#xff0c;它将应用程序分为三大组件&#xff1a;模型 (Model)、视图 (View)、控制器 (Con…

群晖NAS DSM7.2.1安装宝塔之后无法登陆账号密码问题解决

宝塔的安装就不在这赘述了&#xff0c;只说下&#xff0c;启动之后默认账号密码无法登陆的问题。 按照上面给出的账号密码&#xff0c;无法登陆 然后点忘记密码&#xff0c;由于是docker安装的&#xff0c;根目录下没有/www/server/panel 。 也没有bt命令 要怎么修改呢。 既然…

go使用trpc案例

1.go下载trpc go install trpc.group/trpc-go/trpc-cmdline/trpclatest 有报错的话尝试配置一些代理&#xff08;选一个&#xff09; go env -w GOPROXYhttps://goproxy.cn,direct go env -w GOPROXYhttps://goproxy.io,direct go env -w GOPROXYhttps://goproxy.baidu.com/…

[面试] 如何保证Redis和MySQL数据一致性?

为什么要在Redis存数据 Redis 用来实现应用和数据库之间读操作的缓存层&#xff0c;主要目的是减少数据 库 IO&#xff0c;还可以提升数据的 IO 性能。 因为Redis基于内存, 查询效率比MySQL快很多, 所以有限查询Redis中的数据,如果Redis没有就查询数据库然后同步到Redis 出…

算法-两两交换链表中的节点

1、题目来源 24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 2、题目描述 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交…

【C++】内存分配 | 内存管理 | new和delete | 内存泄漏

目录 1. C/C内存分布 2. C语言中动态内存管理方式 3. C内存管理方式 3.1 new操作内置类型 3.2 new自定义类型 4. operator new函数 5. new和delete的实现原理 5.1 内置类型 5.2 自定义类型 6. 定位new表达式 7. 常见面试题 7.1 malloc/free和new/delete的区别 7.2…

【C++STL】STL容器详解

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

JVM(1)

JVM简介 JVM是Java Virtual Machine的简称,意为Java虚拟机. 在java中,它归属于jre(java运行时环境), 而jre归属于jdk(java开发工具包). 虚拟机是指通过软件模拟的具有完整硬件功能的,运行在一个完全隔离的环境中的完整计算机系统. 常见的虚拟机:JVM, VMwave, VirtualBox. J…

什么是SSD型云服务器?

​  SSD云服务器是一种使用固态硬盘代替传统HDD进行存储的虚拟机。SDD 使用闪存单元来存储数据&#xff0c;与云计算技术相结合&#xff0c;形成强大且高效的存储解决方案&#xff0c;可以随时随地访问。 SSD云服务器如何工作? SSD云服务器是利用虚拟化和云计算技术创建的。…

抖音数据抓取工具|视频内容提取软件

引言部分&#xff1a; 介绍针对抖音视频下载需求开发的强大工具突出解决用户获取抖音视频繁琐问题的初衷 工具功能介绍&#xff1a; 详细描述工具功能&#xff0c;包括关键词搜索、自动批量抓取、选择性批量下载等提及基于C#开发的优势以及支持通过分享链接进行单个视频抓取…

eureka 简介和基本使用

Eureka 是Netflix开发的服务发现框架&#xff0c;是Spring Cloud微服务架构中的一部分。它主要用于微服务架构中的服务注册与发现。Eureka由两部分组成&#xff1a;Eureka Server 和 Eureka Client。获取更详细的信息可以访问官网&#xff0c;如下图&#xff1a; Eureka Server…

使用uniapp实现小程序获取wifi并连接

一、背景 因业务需求&#xff0c;需要在小程序实现发现wifi和连接wifi。但由于Andriod和IOS有差异&#xff0c;所以实现起来有所区别。 先看官方文档 https://developers.weixin.qq.com/miniprogram/dev/framework/device/wifi.html 把连接基础流程了解后&#xff0c;发现二者…

EasyRecovery2024高级完整个人版免费下载使用

该软件的高级功能和功能选项主要包括以下几个方面&#xff1a; 恢复删除的磁盘分区&#xff1a;EasyRecovery能够快速扫描磁盘&#xff0c;寻找并恢复删除的磁盘分区&#xff0c;无需检索完整磁盘扇区。支持主流的MBR和GPT分区类型&#xff0c;实现安全可靠的分区恢复。恢复格…

pythonJax小记(五):python: 使用Jax深度图像(正交投影和透视投影之间的转换)(持续更新,评论区可以补充)

python: 使用Jax深度图像&#xff08;正交投影和透视投影之间的转换&#xff09; 前言问题描述1. 透视投影2. 正交投影 直接上代码解释1. compute_projection_parameters 函数a. 参数解释b. 函数计算 2. ortho_to_persp 函数a. 计算投影参数&#xff1a;b. 生成像素坐标网格&am…

《Python 语音转换简易速速上手小册》第10章 未来趋势和发展方向(2024 最新版)

文章目录 10.1 语音技术的未来展望10.1.1 基础知识10.1.2 主要案例:语音驱动的虚拟助理案例介绍案例 Demo案例分析10.1.3 扩展案例 1:情感敏感的客服机器人案例介绍案例 Demo案例分析10.1.4 扩展案例 2:多模态智能会议系统案例介绍案例 Demo

Linux-用户和权限(黑马学习笔记)

认识root用户 root用户&#xff08;超级管理员&#xff09; 无论是Windows、MacOS、Linux均采用多用户的管理模式进行权限管理。 ● 在Linux系统中&#xff0c;拥有最大权限的账户名为&#xff1a;root&#xff08;超级管理员&#xff09; ● 而在前期&#xff0c;我们一直…

SpringBoot 3 新特性

目录 1. GraalVM2. 支持虚拟线程3. HTTP Interface 1. GraalVM 使用GraalVM将SpringBoot应用程序编译成本地可执行的镜像文件&#xff0c;可以显著提升启动速度、峰值性能以及减少内存应用。传统的应用都是编译成字节码&#xff0c;然后通过JVM解释并最终编译成机器码来运行&a…

报错:org.springframework.jdbc.BadSqlGrammarException:

//报错 2024-02-24 19:44:10.814 ERROR 6184 --- [nio-9090-exec-5] c.e.exception.GlobalExceptionHandler : 异常信息&#xff1a; org.springframework.jdbc.BadSqlGrammarException: GPT&#xff1a; 根据异常信息&#xff0c;这是一个Spring框架抛出的BadSqlGrammar…