RedisTemplate查询不到redis中的数据问题(序列化)
RedisTemplate查询不到redis中的数据问题(序列化)
一.问题描述
存入Redis中的值取出来却为null,问题根本原因就是RedisTemplate和StringRedisTemplate的序列化问题、代码示例:
@SpringBootTest
class Redis02SpringbootApplicationTests {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid contextLoads() {Object sd = redisTemplate.opsForValue().get("money");//获取redis中key为“money"的值。System.out.println(sd);}
}
执行结果: idea断点看无数据,但是直接连接redis服务器查询,是有值得
二. 原因分析
redisTemplate 与StringRedisTemplate 区别
区别主要在于他们使用的序列化类。
RedisTemplate使用的是 JdkSerializationRedisSerializer
StringRedisTemplate使用的是 StringRedisSerializer
StringRedisTemplate 继承了RedisTemplate,在构造器中,直接设置了序列化方式
当然从Redis获取数据的时候也会默认将数据当做字节数组转化,当数组是正常形式时
RedisTemplate就无法获取到数据,这个时候获取到的值就是NULL
当Redis当中的数据值是以可读的形式显示出来的时候,只能使用StringRedisTemplate才能获取到里面的数据。所以当你使用RedisTemplate获取不到数据的时候请检查一下是不是Redis里面的数据是可读形式而非字节数组。
使用StringRedisTemplate之后:
@SpringBootTest
class Redis02SpringbootApplicationTests {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Testvoid contextLoads() {Object sd = stringRedisTemplate.opsForValue().get("money");System.out.println(sd);}
}
拿到数据
三.总结
1.redisTemplate只能读取字节数组,不能读取字符串形式的。
2.字符串形式的值,只能使用StringRedisTemplate读取。
四.补充
如果Redistemplate设置了值,在redis客户端却获取不到问题,那该怎么办?
首先,我们要明白一点Redistemplate可以保存所有可序列化的类型,是一个庞大的类,下面就是RedisTemplate类,可以看到俩个泛型
1 public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware
因为Template中set值时会先调用序列化器将键和值都序列化为byte字节数组放入redis数据库中,在客户端除非get后的key值是使用同样的序列化器序列化后的值,否则取不到对应的值。
解决:
自定义Template实现序列化
1 import com.fasterxml.jackson.annotation.JsonAutoDetect;2 import com.fasterxml.jackson.annotation.PropertyAccessor;3 import com.fasterxml.jackson.databind.ObjectMapper;4 import org.springframework.context.annotation.Bean;5 import org.springframework.context.annotation.Configuration;6 import org.springframework.data.redis.connection.RedisConnectionFactory;7 import org.springframework.data.redis.core.RedisTemplate;8 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;9 import org.springframework.data.redis.serializer.StringRedisSerializer;
10
11
12
13 @Configuration
14 public class RedisConfig{
15 // 这是写好的一个固定模板,大家在企业中,拿去就可以直接使用!
16 // 自己定义了一个 RedisTemplate
17 @Bean
18 @SuppressWarnings("all")
19 public RedisTemplate<String, Object>redisTemplate(RedisConnectionFactory factory) {
20 // 我们为了自己开发方便,一般直接使用 <String, Object>
21 RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
22 template.setConnectionFactory(factory);
23 // Json序列化配置
24 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
25 ObjectMapper om = new ObjectMapper();
26 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
27 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
28 jackson2JsonRedisSerializer.setObjectMapper(om);
29 // String 的序列化
30 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
31 // key采用String的序列化方式
32 template.setKeySerializer(stringRedisSerializer);
33 // hash的key也采用String的序列化方式
34 template.setHashKeySerializer(stringRedisSerializer);
35 // value序列化方式采用jackson
36 template.setValueSerializer(jackson2JsonRedisSerializer);
37 // hash的value序列化方式采用jackson
38 template.setHashValueSerializer(jackson2JsonRedisSerializer);
39 template.afterPropertiesSet();
40 return template;
41 }//StringRedisTemplate默认使用的序列化方式
44 private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
45 redisTemplate.setKeySerializer(new StringRedisSerializer());
46 redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
47 redisTemplate.setHashKeySerializer(new StringRedisSerializer());
48 redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
49 redisTemplate.setConnectionFactory(factory);
50 }
52 }
五.补RedisTemplate和StringRedisTemplate的区别
RedisTemplate和StringRedisTemplate的区别:
复制代码
- 两者的关系是StringRedisTemplate继承RedisTemplate。
- 两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
- SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
RedisTemplate默认使用的序列类在在操作数据的时候,比如说存入数据会将数据先序列化成字节数组然后在存入Redis数据库,这个时候打开Redis查看的时候,你会看到你的数据不是以可读的形式展现的,而是以字节数组显示
当然从Redis获取数据的时候也会默认将数据当做字节数组转化,这都是根据序列化策略来决定的。
而stringredistemplate,默认存入的数据就是原文,因为stringRedistemplate默认使用的是string序列化策略
造成两者差异的原因是因为在初始化时,两者使用的序列化策略不同导致的,翻开源码可以看到,如下:
// 该方法是重写RedisAccessor的方法 RedisAccessor实现了spring的InitializingBean 也就是在启动时会执行该方法 可以看到该方法默认的序列化为JdkSerializationRedisSerializer
可以看到redistemplate在初始化时是无参构造,通过spring的bean加载机制在项目启动时执行afterPropertiesSet来完成序列化设置,如果需要自定义序列化配置,可以自己写一个redistemplate的bean,来完成配置。
stringredistemplate就比较简单了,直接继承了redistemplate,在初始化时默认使用了string序列化,源码如下:
那么就可以得出一个结论,如果你想使用默认的配置来操作redis,则如果操作的数据是字节数组,就是用redistemplate,如果操作的数据是明文,使用stringredistemplate。
当然在项目中真实使用时,一般是自定义redistemplate的bean实例,来设置具体的序列化策略,说白了就是redistemplate通过自定义bean可以实现和stringredistemplate一样的序列化,使用起来更加灵活。
相关文章:

RedisTemplate查询不到redis中的数据问题(序列化)
RedisTemplate查询不到redis中的数据问题(序列化) 一.问题描述 存入Redis中的值取出来却为null,问题根本原因就是RedisTemplate和StringRedisTemplate的序列化问题、代码示例: SpringBootTest class Redis02SpringbootApplicationTests {Autowiredprivate RedisTe…...
如何利用乐维网管进行IP管理
IP管理是网络管理中的关键环节,对于保障网络的正常运行、提升资源利用效率以及保障网络安全等方面都具有不可忽视的重要性。乐维网管在IP管理方面具有多种实用功能,以下从IP规划与分配、IP状态监测、IP冲突处理、IP审计与报表生成四个方面,介…...
unix/linux,sudo,其历史争议、兼容性、生态、未来展望
sudo作为一个广泛应用的系统工具,在其发展历程中,自然也伴随着一些讨论、挑战和对未来的展望。 一、 历史争议与讨论 (Historical Controversies and Discussions) 虽然sudo被广泛认为是成功的,但也存在一些历史上的讨论点或潜在的争议: 复杂性 vs. 简洁性 (sudoers语法)…...
git stash命令用法
git stash 是 Git 中一个非常有用的命令,它可以临时保存当前工作区的修改,让你可以切换到其他分支或者处理其他任务,而不需要提交这些还未完成的修改。 一、基本用法 1. 保存当前修改(包括暂存区和工作区的内容) git…...

SkyWalking如何实现跨线程Trace传递
一、概述 SkyWalking 的中构建 Trace 信息时会借助 ThreadLocal来存储一些上下文信息,当遇到跨线程的时候,如果 Trace 的上下文信息没有传递到新线程的ThreadLocal 中,那么链路就断开了。那么SkyWalking是如何解决这个问题的呢? …...
软件工程专业的本科生应该具备哪些技能
软件工程专业的本科生需要具备扎实的技术基础、良好的开发流程认知和一定的软技能,以适应软件开发行业的需求。以下从技术技能、开发流程与工具、软技能、实践能力等维度整理核心技能清单,供参考: 一、核心技术技能 1. 编程语言 - 必学基础语…...

使用 Spring Boot 3.3 和 JdbcTemplate 操作 MySQL 数据库
在现代的 Java 应用开发中,Spring Boot 提供了强大的工具来简化数据库操作。JdbcTemplate 是 Spring 提供的一个核心类,用于简化 JDBC 操作,减少样板代码。本文将介绍如何在 Spring Boot 3.3 项目中使用 JdbcTemplate 来操作 MySQL 数据库&am…...
CentOS 7 修改为静态 IP 地址完整指南
在企业网络环境中,服务器通常需要配置静态 IP 地址以确保网络连接的稳定性和可管理性。以下是使用 NetworkManager 工具在 CentOS 7 系统中将动态 IP 配置修改为静态 IP 的完整指南: 一、检查当前网络配置 查看网络连接状态: 使用 nmcli connection show 命令列出所有网络连…...
企业级高防CDN选型指南
#!/bin/bash # 高防CDN性能压测工具 # 使用方法:./stress_test.sh <防护域名>DOMAIN$1 TEST_IP$(dig short $DOMAIN | head -n1) # 获取CDN节点IPecho "[压力测试] 目标: $DOMAIN ($TEST_IP)" echo "----------------------------------"…...
Redis-6.2.9 cluster集群部署和扩容缩容
目录 1 操作系统信息和redis软件版本 2 redis集群架构 3 redis软件安装 4 cluster创建 6 Redis集群节点扩容 7 redis集群节点缩容节点 1 操作系统信息和redis软件版本 rootu24-redis-120:~# cat /etc/issue Ubuntu 24.04.2 LTS \n \l rootu24-redis-120:~# redis-server…...
Java求职者面试指南:DevOps技术栈深度解析
Java求职者面试指南:DevOps技术栈深度解析 一、基础概念问题 1. 请解释什么是Docker? Docker是一个开源的应用容器引擎,它允许开发者将应用程序及其依赖打包到一个可移植的容器中,然后在任何支持Docker的环境中运行。Docker的核…...
生产环境中安装和配置 Nginx 以部署 Flask 应用的详细指南
在生产环境中部署 Flask 应用时,Nginx 常被用作反向代理服务器,与 WSGI 服务器(如 Gunicorn)协同工作。Nginx 可以处理静态文件、提供 SSL/TLS 加密、实现负载均衡等功能。本文将详细介绍如何在 Ubuntu/Debian 系统上安装 Nginx&a…...

Axure高保真LayUI框架 V2.6.8元件库
点击下载《Axure高保真LayUI框架 V2.6.8元件库》 原型效果:https://axhub.im/ax9/bf36e6dd89bc4c9f/#g1 摘要 本文详细阐述了在 Axure 环境下打造的一套高度还原 LayUI 框架的组件元件集。通过对 LayUI 框架组件的深入剖析,结合 Axure 的强大功能&…...

通讯录实现(Linux+Cpp)
通讯录实现(LinuxCpp) 产品底层思考: 人员如何存储 -> 链表 (增删改 但是排序不适合) 文件存储 -> 人员数据的格式 name:xxx,phone:xxx 人员信息 -> 姓名、电话 引出2 name: xxx,phone: xxx,age: xxx,addr…...
K8S主机漏洞扫描时检测到kube-服务目标SSL证书已过期漏洞的一种永久性修复方法
1、背景 PaaS平台102xx、102xx端口检测到目标SSL证书已过期漏洞,分别对应kube-controller-manager证书、kube-scheduler证书。 2、系统版本 1.0、2.0版本均涉及。 k8s 1.19、1.23版本均涉及。 3、故障现象 PaaS平台部署1年以后,在主机漏洞扫描时&a…...

质检 LIMS 系统数据防护指南 三级等保认证与金融级加密方案设计
面对频发的数据泄露事件,企业亟需构建一套 “防得住、追得回、打得赢” 的防护体系。质检 LIMS 系统通过三级等保认证与金融级加密的结合,为这一目标提供了可行路径。 一、金融级加密:构建数据防护的 “铜墙铁壁” 金融级加密技术通过协议加密…...

Spring Boot 从Socket 到Netty网络编程(上):SOCKET 基本开发(BIO)与改进(NIO)
前言 无论是软件还是硬件的本质都是要解决IO问题(输入、输出),再说回网络编程本质上都是基于TCP/UP的开发,socket是在此基础上做的扩展与封装,而Netty又是对socket做的封装。本文旨在通过相关案例对socket进行探讨。 一…...

79. Word Search
题目描述 79. Word Search 回溯 代码一,使用used数组 class Solution {vector<pair<int,int>> directions{{0,1},{0,-1},{1,0},{-1,0}};vector<vector<bool>> used; public:bool exist(vector<vector<char>>& board, st…...

结构性设计模式之Facade(外观)设计模式
结构性设计模式之Facade(外观)设计模式 前言: 外观模式:用自己的话理解就是用户看到是一个总体页面,比如xx报名系统页面。里面有历年真题模块、报名模块、教程模块、首页模块… 做了一个各个模块的合并,对…...

ICML 2025 Spotlight | 机器人界的「Sora」!让机器人实时进行未来预测和动作执行!
标题:Video Prediction Policy: A Generalist Robot Policy with Predictive Visual Representations 作者:Yucheng Hu, Yanjiang Guo, Pengchao Wang, Xiaoyu Chen, Yen-Jen Wang, Jianke Zhang, Koushil Sreenath, Chaochao Lu, Jianyu Chen 机构&am…...
CSP严格模式返回不存在的爬虫相关文件
文章目录 说明示例(返回404)示例(创建CSP例外) 说明 日期:2025年6月4日。 CSP严格模式是default-src none,但有些web应用中,在爬虫相关文件不存在的情况下,依旧返回了对应文件&…...
https(SSL)证书危机和可行的解决方案
证书危机 20250411,CAB 论坛服务器证书工作组( SCWG )投票通过一项重大提案《 SC-081v3: 引入缩短有效期和数据重复使用期的时间表》,最终决定:从 2026 年起 SSL/TLS 证书的最大有效期将从 398 天逐步缩短至 47 天,并…...
C#获取磁盘容量:代码实现与应用场景解析
C#获取磁盘容量:代码实现与应用场景解析 在软件开发过程中,尤其是涉及文件存储、数据备份等功能时,获取磁盘容量信息是常见的需求。通过获取磁盘的可用空间和总大小,程序可以更好地进行资源管理、预警提示等操作。在 C# 语言中&a…...
2359. 找到离给定两个节点最近的节点
2359. 找到离给定两个节点最近的节点 题目链接:2359. 找到离给定两个节点最近的节点 代码如下: class Solution { public:int closestMeetingNode(vector<int>& edges, int node1, int node2) {auto calc_dis [&](int x) {vector<in…...
前端导入Excel表格
前端如何在 Vue 3 中导入 Excel 文件(.xls 和 .xlsx)? 在日常开发中,我们经常需要处理 Excel 文件,比如导入数据表格、分析数据等。文章将在 Vue 3 中实现导入 .xls 和 .xlsx 格式的文件,并解析其中的数据…...

AI生态警报:MCP协议风险与应对指南(下)——MCP Host安全
AI生态警报:MCP协议风险与应对指南(上)——架构与供应链风险https://blog.csdn.net/WangsuSecurity/article/details/148335401?sharetypeblogdetail&sharerId148335401&sharereferPC&sharesourceWangsuSecurity&spm1011.24…...

基于VLC的Unity视频播放器(四)
上篇文章中提到的问题 播放某个m3u8地址时会嘎掉,想办法解决了一下,很粗暴的,先SetFormat,再Stop,最后再Play,能用…… if (player ! null && player.GetSize() 0) {player.GetSize((w, h) >…...

pixel刷入Android15 userdebug版本
最近入手一个pixel7,想着刷个userdebug版本,就不用模拟器调试开发了,结果按照网上的教程,每次刷机后都是卡在goole logo界面,卡了一天多我才找到问题所在,想着记录下,给自己做个备份。 1. 前期准备&#x…...
【Go-补充】ioReader + ioWriter + bufio
一、io.Reader 和 io.Writer 接口介绍 在 Go 语言中,io 包定义了两个最基础和最重要的接口:io.Reader 和 io.Writer。它们是 Go 语言中进行输入/输出操作的核心抽象,实现了极大的灵活性和可组合性。 io.Reader 接口 io.Reader 接口定义了一…...
leetcode 3403. 从盒子中找出字典序最大的字符串 I 中等
给你一个字符串 word 和一个整数 numFriends。 Alice 正在为她的 numFriends 位朋友组织一个游戏。游戏分为多个回合,在每一回合中: word 被分割成 numFriends 个 非空 字符串,且该分割方式与之前的任意回合所采用的都 不完全相同 。所有分…...