SpringBoot @SessionScope注解和Session的用法解释

news2024/11/16 4:16:42

参考资料

  1. JSESSIONID是什么
  2. @SessionScope 解决了不同session下如何生成不同服务实例

目录

  • 一. 前期准备
  • 二. 被@SessionScope作用的类
  • 三. 使用被@SessionScope作用类的Service
  • 四. 效果
    • 4.1 用Edge浏览器进入页面
    • 4.2 然后用Edge浏览器进入页面
    • 4.3 若将CacheHolder类上的@SessionScope注解去掉
  • 五. session
    • 5.1 JSESSIONID的发送和判定
    • 5.2 清空cookie中的JSESSIONID
    • 5.3 恢复cookie中的JSESSIONID,再发送ajax请求
    • 5.4 使用过错误的JSESSIONID,再发送ajax请求


一. 前期准备

⏹前台

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <button id="btn">获取缓存信息</button><br>
    <button id="clear">清空缓存消息</button>
</div>
<script th:src="@{/js/public/jquery-3.6.0.min.js}"></script>
<script th:inline="javascript">
	
	// 发送获取缓存的请求
    $("#btn").click(function() {
        $.ajax({
            url: "/test19/getCacheValue",
            type: 'POST',
            data: null,
            contentType : 'application/json;charset=utf-8',
            dataType: 'json',
            success: function (data, status, xhr) {
                console.log(data);
            }
        });
    });

    $("#clear").click(function() {
        $.get('/test19/clear');
    });
</script>
</body>
</html>

⏹后台-Controller

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;

@Controller
@RequestMapping("/test19")
public class Test19Controller {

    @Resource
    private Test19Service service;

    @GetMapping("/init")
    public ModelAndView init() {

        // 页面初始化
        service.init();

        // 指定跳转的页面
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("test19");

        return modelAndView;
    }

    @PostMapping("/getCacheValue")
    @ResponseBody
    public void getCacheValue() {
        service.getCacheValue();
    }

    @GetMapping("/clear")
    @ResponseBody
    public void clear() {
        service.clear();
    }
}

二. 被@SessionScope作用的类

  • SpringBoot默认是单例模式,也就是说每个用户访问的CacheHolder都是同一个对象
  • 被@SessionScope作用的类,每一次会话会生成一个新的对象
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.SessionScope;

import java.util.HashMap;
import java.util.Map;

@Component
@SessionScope
public class CacheHolder {

    // 用于缓存的map
    private Map<String, Object> cacheMap = new HashMap<>();

    // 根据画面id获取缓存
    public <T> T getCacheByViewId(String viewId) {
        Object o = cacheMap.get(viewId);
        return (T)o;
    }

    // 根据画面id设置缓存
    public void setCacheByViewId(String viewId, Object value) {
        cacheMap.put(viewId, value);
    }

    // 根据画面id清空缓存
    public void clearCacheByViewId(String viewId) {
        cacheMap.remove(viewId);
    }

    // 清空所有的缓存
    public void clearAllCache() {
        cacheMap.clear();
    }
}

三. 使用被@SessionScope作用类的Service

  • InitializingBean接口用于Bean初始化的时候,做一些操作
  • HttpSession用于使用session对象
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

@Service
public class Test19Service implements InitializingBean {
    
    // session对象
    @Resource
    private HttpSession session;
    
    // 自定义缓存类
    @Resource
    private CacheHolder cacheHolder;
	
	// 为缓存准备的数据
    private static Map<String, String> dbMap;

    // Bean初始化时,模拟从数据库获取数据
    @Override
    public void afterPropertiesSet() throws Exception {

        // 模拟从数据库查询数据,将查询到的数据放入缓存中
        dbMap = new HashMap<String, String>() {{
            put("name", "贾飞天" + UUID.randomUUID().toString());
            put("num", UUID.randomUUID().toString());
        }};
    }

    public void init() {
        
        // 页面初始化的时候从自定义的缓存类中获取缓存
        Map<String, Object> map = cacheHolder.getCacheByViewId("test19");
        // 如果获取不到缓存的话
        if (ObjectUtils.isEmpty(map)) {
            // 将模拟数据库查询到的数据放入自定义缓存类中
            cacheHolder.setCacheByViewId("test19", dbMap);
        }
    
        // 页面初始化的时候,从session中获取缓存的数据
        Object sessionData = session.getAttribute("test19");
        if (ObjectUtils.isEmpty(sessionData)) {
            session.setAttribute("test19", dbMap);
        }
        
        // 获取session的id
        String id = session.getId();
        System.out.println("session的id为:" + id);
    }

    public void getCacheValue() {
        
        // 从自定义缓存类中获取缓存并打印
        Map<String, String> cacheMap = cacheHolder.getCacheByViewId("test19");
        if (!ObjectUtils.isEmpty(cacheMap)) {
            System.out.println(cacheMap.get("name"));
            System.out.println(cacheMap.get("num"));
        }
        
        // 从session中获取缓存并打印
        Optional.ofNullable(session.getAttribute("test19")).ifPresent(item -> {
            Map map = (Map)item;
            System.out.println(map);
        });
        System.out.println("");

    }

    public void clear() {
        // 清空该画面中缓存的数据
        cacheHolder.clearCacheByViewId("test19");
    }
}

四. 效果

🧐 @SessionScope作用的类每次会话生成一个对象

4.1 用Edge浏览器进入页面

  • CacheHolder类被@SessionScope注解修饰
  • 可以看到num和name放入了CacheHolder自定义缓存
  • 👉可以看到cacheHolder的对象地址为 @712b4a92

在这里插入图片描述
在这里插入图片描述

4.2 然后用Edge浏览器进入页面

  • 可以看到从CacheHolder自定义缓存中并没有获取到Edge浏览器进入页面时,放入的数据。并且可以看到cacheHolder的对象地址为 @364f9896
  • 因此可以证明被@SessionScope作用的CacheHolder类,每一次会话生成不同的对象

在这里插入图片描述
在这里插入图片描述

4.3 若将CacheHolder类上的@SessionScope注解去掉

⏹通过Edge浏览器进入

在这里插入图片描述

⏹通过Chrome浏览器进入

在这里插入图片描述

由上面两张图可以看到,若CacheHolder类上的@SessionScope注解去掉的话,
CacheHolder类变为单例,地址都是@7889。不同的客户端访问得到的是同一个对象,因此缓存功能无法使用。
只有使用了@SessionScope注解,进行了服务隔离,保证每次会话产生不同的实例对象,缓存才有法使用。


五. session

  • 每一个浏览器访问一个网站的时候,都会产生一个特定的session
  • 当一个网页与服务器建立连接之时,服务器会将生成的sessionID保存到cookie中。key为JSESSIONID,value为生成的sessionID。
  • 在发送网络请求的时候,将cookie中的JSESSIONID发送到后台,后台通过JSESSIONID可以判断访问的客户端

5.1 JSESSIONID的发送和判定

在这里插入图片描述

🧐因为该浏览器并非第一次访问该网页,因此CacheHolder和session中都能获取出缓存值
👉可以看到cookie中存储的JSESSIONID和session对象获取出的id相同

在这里插入图片描述

5.2 清空cookie中的JSESSIONID

⏹清空cookie中的JSESSIONID,然后再发送一次ajax请求

在这里插入图片描述
⏹因为我们发送的ajax请求中并没有携带JSESSIONID,所以后台无法标识此客户端,因此也无法从session和@SessionScope注解作用的缓存来中获取数据。因此获取到的值皆为null

在这里插入图片描述

5.3 恢复cookie中的JSESSIONID,再发送ajax请求

⏹我们可以通过document.cookie='key=value'的形式设置cookie

在这里插入图片描述
⏹因为携带了缓存session和CacheHolder时的正确JSESSIONID,因此从两个缓存中能正确的获取出值

在这里插入图片描述

5.4 使用过错误的JSESSIONID,再发送ajax请求

⏹随便编造一个JSESSIONID,设置到cookie中

在这里插入图片描述

👉可以看到,无法获取到缓存值

在这里插入图片描述

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

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

相关文章

nginx部署next项目访问日志去重小技巧,next项目资源不计入日志,网站日志统计去除资源请求

next项目访问日志去重小技巧需求提出具体解决方案配置代码需求提出 之前在跟SEO做网站日志分析的时候受到了一部分资源请求数据的影响&#xff0c;统计出来的ip访问次数远远大于实际值&#xff0c;从日志中或者网站控制台看到每个页面都会发送十几个请求&#xff0c;而这些请求…

Qt中使用QWebEngine加载百度离线地图,在特定地点加载个圣诞树

一、前言 2022年圣诞节到来啦&#xff0c;很高兴这次我们又能一起度过~ 遇上圣诞节&#xff0c;正好最近研究了QT中加载百度离线地图&#xff0c;用百度地图API加载个圣诞树&#xff08;主要我想要那个圣诞节特制勋章&#xff09;。 二、创意名 在百度离线地图加载个圣诞树。…

演化博弈、复制动态方程与仿真

本文只整理和总结一下我的理解&#xff0c;文末列出了可供参考的更详细完整的资料。建议先看参考资料[1]&#xff08;博弈论公开课&#xff09;的博弈论课程&#xff0c;可以直接从第11讲开始看。   参考链接[2]是关于演化博弈非常经典的一本书。   参考链接[5]涵盖内容比较…

CSDN文章质量检测系统

想知道你的文章在CSDN中质量如何吗&#xff1f; 你想知道你的CSDN文章到底写得怎么样吗&#xff1f; 你想要获得一个你的系统的CSDN文章评分吗&#xff1f; CSDN质量分数帮你解决这个问题&#xff0c;网址如下&#xff1a; https://www.csdn.net/qc 界面在如下&#xff0c;如果…

XGBoost模型的python实现

文章目录函数介绍实例二分类问题多分类问题作者&#xff1a;李雪茸函数介绍 实现 XGBoost 分类算法使用的是 xgboost 库的 XGBClassifier&#xff0c;具体参数如下&#xff1a; 1、max_depth&#xff1a;给定树的深度&#xff0c;默认为3 2、learning_rate&#xff1a;每一步…

SpringBoot整合TKMyBatis实现增删改查

文章目录什么是TKMybatis&#xff1f;SpringBoot整合TKMybatis实体类注解TKMapper接口如何使用基本增删改操作批量查询和删除批量添加自定义查询条件ExampleExample 条件设置Example 使用什么是TKMybatis&#xff1f; TKMybatis 是基于Mybatis 框架开发的一个工具&#xff0c;…

[4]MQTT协议基础--下

1.QoS服务质量等级 MQTT服务质量(Quality of Service 缩写 QoS)正是用于告知物联网系统&#xff0c;哪些信息是重要信息需要准确无误的传输&#xff0c;而哪些信息不那么重要&#xff0c;即使丢失也没有问题。 MQTT协议有三种服务质量级别&#xff1a; QoS 0 – 最多发一次…

公司jmeter分享

一、数据库压测组件功能说明 1.JDBC Connection Configuration:jdbc连接配置(一个测试计划可以有多个 JDBC Connection) 2.Variable Name for created pool: 创建池的变量名 连接绑定的变量名,JMeter可以使用多个连接,每个连接绑定到不同的变量;通过引用不同的绑定变量…

安全防范语音通知实现方案

语音通知作为一种强提醒的信息通知方式&#xff0c;非常适合使用在安全防范语音通知场景中&#xff0c;可以有效避免用户错过重要信息。那安全防范语音通知怎么实现&#xff1f;这里互亿无线小编为大家做个详细介绍&#xff1a; 一、如何发送安全防范语音通知信息 互亿无线语…

本地事务、分布式事务、CAP 定理与 BASE 理论、分布式事务几种方案、Linux 安装 Seata、Seata的使用-56

一&#xff1a;本地事务 1.1 事务的基本性质 1.数据库事务的几个特性&#xff1a;原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily)&#xff0c;简称就是 ACID&#xff1b; 原子性&#xff1a;一系列的操作整体不可拆分&#xf…

LVGL学习笔记8 - 字体

目录 1. 修改默认字体 2. 修改字体 3. 特殊字体 3.1 SUBPX字体 3.2 28像素压缩字体 3.3 16像素希伯来语/阿拉伯语/Perisan字母 3.4 16像素中文字体 3.5 8像素Ascii字体 3.6 16像素Ascii字体 3.7 内置图标 4. 超大字体 5. 编码方式 6. 添加字体 6.1 在线字体转换器 …

【微服务笔记01】微服务组件之Eureka注册中心的介绍及其基础环境的搭建

这篇文章&#xff0c;主要介绍微服务中的注册中心Eureka及其基础环境的搭建【源代码地址】。 目录 一、Eureka注册中心 1.1、什么是注册中心 1.2、注册中心原理 二、搭建Eureka注册中心环境 2.1、创建父工程&#xff0c;引入微服务依赖 2.2、创建Eureka服务端工程 &…

全球公开的DEM数据产品

1 简介 全球公开版地形数据包括&#xff1a;GTOPO30-DEM、ASTER-GDEM、SRTM90、ALOS-AW3D30等&#xff0c;其他的诸如World DEM及ALOS-AW3D (5m分辨率&#xff09;等全球地形数据不能免费获得。 SRTM&#xff1a;由NASA 及国家地理空间情报局NGA采用2000年2月发射的“奋进号”…

word文件损坏打不开如何修复?文件丢失怎么办?

我们日常办公中&#xff0c;经常用到Word文档。但是有时会遇到word文件损坏、无法打开的情况。这时该怎么办&#xff1f;接着往下看&#xff0c;小编在这里就给大家带来Word文件修复的方法&#xff0c;以及Word文件丢失如何恢复的方法&#xff01; 一、Word文件损坏怎么办 部分…

【vsan数据恢复】磁盘离线导致分布式存储瘫痪的数据恢复案例

vsan数据恢复环境&#xff1a; 一组4台服务器搭建vsan集群&#xff1b; 每台服务器配置有2组分别由6块硬盘组成的磁盘阵列&#xff0c;上层是虚拟机文件。 vsan故障&#xff1a; 在运行过程中&#xff0c;某一个节点的一块硬盘离线&#xff0c;vsan安全机制启动&#xff0c;开始…

梦想云图Node.JS服务 ( 最近更新时间:2022-12-30 10:04:50 )

说明 后台提供梦想Node.JS服务&#xff0c;方便调用控件后台功能&#xff0c;Windows服务程序所在目录:Bin\MxDrawServer\Windows&#xff0c;Linux服务程序所在目录:Bin\Linux\MxDrawServer 梦想云图Node.JS服务 &#xff08; 最近更新时间&#xff1a;2022-12-30 10:04:50 …

第三个脚本——时间加速and视频倍速

目录 本文主要内容 granr属性介绍 run-at属性 时间加速原理 视频倍速原理 完整示例 本文主要内容 介绍grant属性&#xff0c;run-at属性以及时间加速&#xff0c;视频倍速原理 granr属性介绍 相关函数四个&#xff1a; GM_setValue GM_getValue GM_listValues GM_del…

json基本使用与简介

一、简介 二、json两种构造结构 三、js解析JSON 1、JSON2解析JSON 2.用eval()方法把JSON字符串转化成JSON对象. 3&#xff0e;使用JSON2中的JSON对象的parser()方法解析JSON字符串 4. 使用JSON2中的JSON对象的stringify ()方法把JSON对象转换成字符串 5、案例 四、Java解…

【模型部署】人脸检测模型DBFace C++ ONNXRuntime推理部署(1)

系列文章目录 【模型部署】人脸检测模型DBFace C ONNXRuntime推理部署&#xff08;0&#xff09; 【模型部署】人脸检测模型DBFace C ONNXRuntime推理部署&#xff08;1&#xff09; 【模型部署】人脸检测模型DBFace C ONNXRuntime推理部署&#xff08;2&#xff09; 文章目录…

深度学习训练营之灵笼人物识别

深度学习训练营之灵笼人物识别原文链接环境介绍前置工作设置GPU导入数据数据查看数据预处理加载数据可视化数据检查数据配置数据集prefetch()功能详细介绍&#xff1a;归一化查看归一化后的数据构建VGG-19网络VGG优点VGG缺点利用官方给到的网络网络结构编译模型训练结果可视化预…