【SpringBoot集成Redis + Session持久化存储到Redis】

news2024/11/28 16:32:53

目录

SpringBoot集成Redis 

1.添加 redis 依赖  

2.配置 redis 

3.手动操作 redis   

Session持久化存储到Redis 

1.添加依赖

2.修改redis配置

3.存储和读取String类型的代码  

4.存储和读取对象类型的代码  

5.序列化细节


SpringBoot集成Redis 

1.添加 redis 依赖  

或将以下配置添加到 pom.xml 中:   

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

2.配置 redis 

#redis地址
spring.redis.host=8.130.30.95
#端口号
spring.redis.port=6379
spring.redis.password=
#DB[0-15]
spring.redis.database=0 
# 可省略
spring.redis.lettuce.pool.min-idle=5
spring.redis.lettuce.pool.max-idle=10
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=1ms
spring.redis.lettuce.shutdown-timeout=100ms 

3.手动操作 redis   

@RestController
public class RedisController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    // 在 redis 存储数据  30s之后自动失效
    @RequestMapping("/set")
    public String set(String name, String value) {
        stringRedisTemplate.opsForValue().set(name, value, 30, TimeUnit.SECONDS);
        return "Set redis success.";
    }
    // 读取 redis 中的数据
    @RequestMapping("/get")
    public String get(String name) {
        Object valObj = stringRedisTemplate.opsForValue().get(name);
        if (valObj != null) {
            return valObj.toString();
        }
        return "Null";
    }
}

通过postman发送请求测试: 

下面测试存入字典(Hash)类型: 

    // 在 redis 存储数据
    @RequestMapping("/set2")
    public String set2() {
        stringRedisTemplate.opsForHash().put("myhash","name","ws");
        return "Set redis success.";
    }
    // 读取 redis 中的数据
    @RequestMapping("/get2")
    public String get2() {
        Object valObj = stringRedisTemplate.opsForHash().get("myhash", "name");
        if (valObj != null) {
            return valObj.toString();
        }
        return "Null";
    }

Session持久化存储到Redis 

1.添加依赖

或者在pom.xml中引入: 


<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2.修改redis配置

# 设置连接的Redis数据库的索引。默认情况下,索引为0,即连接到默认的数据库。
# 如果设置多个Redis实例,可以通过此项进行区分。
spring.redis.database=0
# 设置连接的Redis服务器的主机名或IP地址
spring.redis.host=8.130.30.95
spring.redis.password=
# 设置连接的Redis服务器的端口号。在此,服务器的端口号为6379,这是Redis默认的端口号,默认的话可以省略不写。
spring.redis.port=6379
# 设置会话存储类型为Redis
spring.session.store-type=redis
# 设置服务器上所有Servlet的会话超时时间为1800秒,即30分钟。
# Spring Boot默认的会话超时时间为30分钟,但在这里,它被明确地设定为1800秒
server.servlet.session.timeout=1800
# 设置Redis的flush mode为'on_save'。flush mode决定了何时将数据写入磁盘。
# 'on_save'意味着每次数据被保存时都会立即写入磁盘,这可以保证数据的持久性,但可能会影响性能。
spring.session.redis.flush-mode=on_save
# 设置Spring Session在Redis中的命名空间为'spring:session'。
# 这是为了防止不同的应用在同一Redis实例中产生数据冲突。每个应用都可以使用不同的命名空间来保存自己的会话数据。
spring.session.redis.namespace=spring:session

3.存储和读取String类型的代码  

@RestController
@RequestMapping("/user")
public class UserController {
    // user session key
    private static final String SESSION_KEY_USERINFO = "SESSION_KEY_USERINFO";
    @RequestMapping("/set")
    public String set(HttpSession session) {
        session.setAttribute(SESSION_KEY_USERINFO, "ws");
        return "ok";
    }
    @RequestMapping("/get")
    public String get(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        Object userObj = null;
        if (session != null && (userObj = session.getAttribute(SESSION_KEY_USERINFO)) != null) {
            return (String) userObj;
        }
        return "Null";
    }
}

通过postman进行测试:

4.存储和读取对象类型的代码  

实体类:

@Data
public class UserInfo {
    private int id;
    private String username;
    private int age;
}

controller类:

@RestController
@RequestMapping("/user")
public class UserController {
    // user session key
    private static final String SESSION_KEY_USERINFO = "SESSION_KEY_USERINFO";
    @RequestMapping("/set")
    public String set(HttpSession session) {
        //...经过一系列的判断
        UserInfo userInfo = new UserInfo();
        userInfo.setId(1);
        userInfo.setUsername("ws");
        userInfo.setAge(18);
        session.setAttribute(SESSION_KEY_USERINFO, userInfo);
        return "ok";
    }
    @RequestMapping("/get")
    public UserInfo get(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        Object userObj = null;
        if (session != null && (userObj = session.getAttribute(SESSION_KEY_USERINFO)) != null) {
            return (UserInfo) userObj;
        }
        return null;
    }
}

通过postman测试:发现是序列化的问题 

解决方案: 

让UserInfo类实现序列化接口,同时生成序列化版本号。
ps:凡是实现Serializable接口(标识接口)的类都有一个表示序列化版本标识符的静态常量:
private static final long serialVersionUID;
serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序加化时是否兼容。
如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。
简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

设置生成序列化版本号: 

在类上面ALT+ENTER: 

再次测试: 

5.序列化细节

(1)被序列化的类的内部的所有属性,必须是可序列化的 (基本数据类型都是可序列化的
(2)static,transient修饰的属性 不可以被序列化

再测试下: 

什么时候用static和transient?

static类共享的时候
transient:比如说银行卡的密码,不想被持久化(序列化),写到文件中假如被别人窃取了,别人可以通过反序列化把密码读出来(破解),需要保护的东西就可以用transient来修饰 

 

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

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

相关文章

运算放大器学习笔记

目录 一、基本定理二、基本定义三、负反馈电路四、同向放大电路五、反向放大电路六、差分放大电路 一、基本定理 【电路示意图】 开环放大公式 VOAvo(V-V-) 开环放大倍数&#xff08;增益&#xff09;非常大&#xff0c;105 或 106 输入阻抗超级大&#xff08;可以理解为电…

辅助驾驶功能开发-控制篇(03)-基于PID的请求角度转扭矩算法

1 文档概述 本文档主要描述请求角度转扭矩的功能、性能要求、算法程序设计,后续可作为程序编程和功能及性能测试参考文档。 2 功能要求 转角扭矩管理(SteeringTorqueManager)将方向盘请求转角转换为电机叠加扭矩,进行横向路径跟踪,并与驾驶员方向盘手感交互,实现自适应调整…

2023年五一杯数学建模B题快递需求分析问题求解全过程论文及程序

2023年五一杯数学建模 B题 快递需求分析问题 原题再现&#xff1a; 网络购物作为一种重要的消费方式&#xff0c;带动着快递服务需求飞速增长&#xff0c;为我国经济发展做出了重要贡献。准确地预测快递运输需求数量对于快递公司布局仓库站点、节约存储成本、规划运输线路等具…

红魔8SPro强解BL+完美ROOT权限-刷MIUI14系统-修复指纹丢失/内存等问题

早前我们刷过红魔8pro手机&#xff0c;该手机支持解锁BL刷入MIU14系统&#xff0c;红魔8Pro由于官方并没有修改解锁BL指令&#xff0c;所以我们的解锁BL非常简单&#xff0c;只需要在fastboot下一键完成。随着红魔8SPro的上架&#xff0c;红魔UI6.0的发布&#xff0c;官方解锁指…

【数据仓库设计基础1】关系数据模型理论与数据仓库Inmon方法论

文章目录 一. 关系数据模型中的结构1&#xff0e;关系2&#xff0e;属性3&#xff0e;属性域4&#xff0e;元组5. 关系数据库6&#xff0e;关系表的属性7&#xff0e;关系数据模型中的键 二. 关系完整性1&#xff0e;空值&#xff08;NULL&#xff09;2&#xff0e;关系完整性规…

2022/9/13总结

Vue 路由的封装抽离 为了便于维护 &#xff0c;我们通常需要将路由模块抽离出来 在vue中&#xff0c;如果要写路径&#xff0c;可以写绝对路径 使用 代表从src目录下去寻找&#xff0c;能避免出现很多错误 声明式导航 -- 导航链接 vue-router提供了一个全局组件router-l…

nodejs系列-使用nodejs链接MongoDB数据库问题总结

参考文档 mongodbMongoose 问题1. 不支持preferredcms_db_name、cms_db_collection选项 throw new error_1.MongoParseError(${optionWord} ${Array.from(unsupportedOptions).join(, )} ${isOrAre} not supported);^MongoParseError: options preferredcms_db_name, cms_db…

SVN 和 GIT 命令对比

参考 https://blog.csdn.net/justry_deng/article/details/82259470 # TortoiseSVN打分支、合并分支、切换分支 https://www.huliujia.com/blog/802a64152bbbe877c95c84ef2fdf3857a056b536/ # 版本控制&#xff1a;Git与Svn的命令对应关系 TortoiseSVN打分支、合并分支、切换…

Qt应用开发(基础篇)——菜单栏 QMenuBar

一、前言 QMenuBar类继承于QWidget&#xff0c;该类提供了一个水平菜单栏。 菜单栏使用 QMenuBar菜单栏&#xff0c;顾名思义是菜单QMenu和动作QAction的容器&#xff0c;一般在软件的顶部经常会见到它。菜单栏包含了一系列下拉的菜单&#xff0c;使用addMenu()函数添加QMenu菜…

【ICASSP 2023】ST-MVDNET++论文阅读分析与总结

主要是数据增强的提点方式。并不能带来idea启发&#xff0c;但对模型性能有帮助 Challenge&#xff1a; 少有作品应用一些全局数据增强&#xff0c;利用ST-MVDNet自训练的师生框架&#xff0c;集成了更常见的数据增强&#xff0c;如全局旋转、平移、缩放和翻转。 Contributi…

leetcode 673. 最长递增子序列的个数

2023.9.13 做本题之前先复习一下 最长递增子序列 &#xff0c;在此基础上还要加个count数组&#xff0c;用于记录当前下标 最长递增子序列的个数。 本题还是有些难度&#xff0c;日后再来二刷。

lv4 嵌入式开发-7 文件IO(概念、打开、关闭、读、写)

目录 1 文件I/O 介绍 2 文件I/O – 文件描述符fd&#xff08;File Descriptor&#xff09; 3 文件I/O – open 4 文件I/O – close 5 文件I/O – read 6 文件I/O – write 7 文件IO – lseek 8 标准I/O – 思考和练习 掌握文件描述符的含义 1 文件I/O 介绍 什么是文件…

php 实现stripe支付流程

1.申请账号获取密钥key 2.申请创建商品&#xff0c;创建价格&#xff0c;创建支付&#xff0c; //创建商品 public function create_product(){ $_key self::STRIPE_KEY;$stripe new \Stripe\StripeClient($_key);$arr $stripe->products->create([name > $good…

Arcgis多值提取至点所有波段数值一样

Arcgis多值提取至点所有波段数值一样 问题描述 进行多值提取多波段后的结果&#xff0c;所有波段数值都是一样的。 原因 操作流程问题&#xff0c;输入栅格只选择了一个栅格文件 解决方案 实际上&#xff0c;每个波段都会对应一个栅格文件&#xff0c;要把这些添加进去 这…

【网络编程】深入理解TCP协议二(连接管理机制、WAIT_TIME、滑动窗口、流量控制、拥塞控制)

TCP协议 1.连接管理机制2.再谈WAIT_TIME状态2.1理解WAIT_TIME状态2.2解决TIME_WAIT状态引起的bind失败的方法2.3监听套接字listen第二个参数介绍 3.滑动窗口3.1介绍3.2丢包情况分析 4.流量控制5.拥塞控制5.1介绍5.2慢启动 1.连接管理机制 正常情况下&#xff0c;TCP需要经过三…

淘宝/天猫获取商品销量详情 API 返回值说明

item_get_sales-获取商品销量详情 API测试工具 taobao.item_get_sales 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_…

SEO优化排名的技巧与注意点(百度SEO排名的五大注意点)

关键词排名是指在搜索引擎中&#xff0c;用户搜索相关关键词时&#xff0c;网站出现的顺序。SEO优化是提高网站排名的一种方法。优化关键词排名的目的是提高网站流量和知名度。但是要注意遵循百度SEO排名的规则。 下面介绍一下百度SEO排名的五大注意点和优化关键词的六种方式。…

Arcgis提取每个像元的多波段反射率值

Arcgis提取每个像元的多波段反射率值 数据预处理 数据预处理阶段需要对遥感图像进行编辑传感器参数、辐射定标、大气校正、正射校正&#xff0c;具体流程见该文章 裁剪研究区 对于ENVI处理得到的tiff影像&#xff0c;虽然是经过裁剪了&#xff0c;但是还存在黑色的背景值&a…

JDK、eclipse软件的安装

一、打开JDK安装包 二、复制路径 三、点击我的电脑&#xff0c;找到环境变量 四、新建环境 变量名&#xff1a;JAVA_HOME 变量值就是刚刚复制的路径 五、在path中建立新变量 双击path 打印以下文字 最后一直双击确定&#xff0c;安装环境完成。 六、双击eclipse 选择好安装…

Sentinel控制台配置 持久化到nacos

sentinel控制台&#xff0c;使用方便&#xff0c;功能强大。使用官方的jar包&#xff0c;配置不会持久化&#xff0c;sentinel重启后会导致&#xff0c;之前的规则全部丢失&#xff0c;下面一起改造源码实现规则数据的持久化 sentinel源码地址 &#xff08;github访问太慢&am…