SpringBoot2使用@Cacheable注解时,Redis中保存的Value为java序列化乱码问题的解决办法及源码分析

避坑指南:OpenWebUI+SearXNG联网搜索的5个常见配置错误及解决方法 本文详细解析了OpenWebUI与SearXNG整合过程中常见的5个配置错误及解决方案,包括JSON格式配置陷阱、国内搜索引擎缺失、连续搜索失效等问题。通过实战验证的优化策略,帮助开发者避免性能下降和功能异常,提升大模型与搜索引擎的协同效率。 阅读详情

说明:SpringBoot版本为2.1.6.RELEASE

看了许多同学的博客都是通过自定义RedisCacheManager组件的方式来解决,我这里换一种方式,采用自定义org.springframework.data.redis.cache.RedisCacheConfiguration组件的方式来解决,并附上源码分析过程:

首先要明确SpringBoot Data在整合Redis作为Cache的实现方式后,组件之间的依赖关系变为:

CacheAutoConfiguration-->RedisCacheConfiguration(autoconfigure.cache)-->RedisCacheManager-->RedisCache-->RedisCacheConfiguration(redis.cache)

为什么使用@Cacheable注解后,保存的Value在Redis中是乱码,首先想到的是从RedisCache类中的put()方法入手。

put方法的逻辑如下图:

进入createAndConvertCacheKey(key)、serializeCacheValue(cacheValue)方法中,这里不贴代码了,可以知道对key和value的序列化规则都是从当前类的成员变量cacheConfig中获取配置的,而此成员变量cacheConfig对应的类型是org.springframework.data.redis.cache.RedisCacheConfiguration类:

进入org.springframework.data.redis.cache.RedisCacheConfiguration类中:

发现该类类头没有注解,推测它并不是容器中的一个组件,且对两个成员变量keySerializationPair、valueSerializationPair并没有赋予初始值,且唯一的构造器还是private私有的。

但此类中有两个static静态方法对keySerializationPair和valueSerializationPair成员变量进行了赋值,且返回一个实例对象:

分析到这里,我们就要知道是谁调用了此静态方法:

Ctrl+单击此defaultCacheConfig静态方法,发现是org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration配置类在向IOC容器中注入组件RedisCacheManager时,调用了此静态方法,见下图:

上图说明:在调用RedisCacheManager.builder方法创建RedisCacheManagerBuilder对象后,调用determineConfiguration方法进行装配RedisCacheConfiguration时调用的此defaultCacheConfig静态方法。

而在determineConfiguration方法中,调用此静态方法之前的前提条件是:this.redisCacheConfiguration不为空。否则就按照后面的逻辑对value实行Java序列化规则:JdkSerializationRedisSerializer。

现在就分析当前类的成员变量this.redisCacheConfiguration的赋值逻辑,如下图:

发现在当前类的有参构造器中,它会从IOC容器中获取org.springframework.data.redis.cache.RedisCacheConfiguration组件并赋值给此成员变量。只不过IOC容器中并没有该可用组件,可以打断点看到:

解决办法:

通过以上的分析,那我们就可以自己手动向IOC容器中注册一个类型为org.springframework.data.redis.cache.RedisCacheConfiguration的组件,并参照determineConfiguration方法:调用serializeValuesWith方法对value的序列化规则改为json类型:

/**
     * 注册自定义RedisCacheConfiguration组件,解决@Cacheable @Cacheput注解在向Redis中保存的Value是java序列化乱码的问题
     */
    @Bean
    public RedisCacheConfiguration redisCacheConfiguration() {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        config=config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
        return config;
    }

再次打断点观察RedisCacheManager组件的注册逻辑:就可以看到this.redisCacheConfiguration不为null,且对Value的序列化规则已经改成我们自定义的了。

原创不易,转载请指明出处,谢谢!

FPGA实战:手把手教你用Verilog实现Modbus CRC16校验(附完整代码) 本文详细介绍了在FPGA中实现Modbus RTU协议CRC16校验模块的完整实战方案。针对硬件设计中的时序、资源与性能挑战,文章从算法原理出发,提供了清晰的Verilog模块接口、状态机设计、查表ROM实现及优化策略,并附带了完整的可综合代码与测试平台,帮助工程师高效构建稳定可靠的工业通信系统。 阅读详情

相关推荐

Linux安装Oracle sqlplus客户端工具

Linux安装Oracle sqlplus客户端工具

优快云_Nan_Jiang_Li的博客 2776

springboot cache 数据缓存到redis中的value是乱码问题(包含日期格式转换)

springboot 解决 @Cacheable写入乱码的问题

Jackson_hushisan的博客 1270

PIVlab软件入门:从GUI操作到2D2C粒子测速实战

本文详细介绍了PIVlab软件在2D2C粒子测速中的入门与实战应用。从GUI操作到环境搭建,再到图像预处理和核心参数设置,帮助用户快速掌握这一基于MATLAB的开源工具。通过实际案例和技巧分享,展示了PIVlab在流体力学实验中的高效性和实用性。

weixin_42547431的博客 226

spring @Cacheable @CachePut... 使用redis缓存详细步骤

spring @Cacheable @CachePut... 使用redis缓存详细步骤本文以一个spring的maven工程,整理记录使用注解缓存的问题,基本不需要自己写过多的封装的代码,很多人都实现Cache接口重新定义自己的缓存操作。其实不用也可以,Spring已经做了很多了。预期目标查询:如果缓存中存在,直接从缓存中取,不查数据库。如果缓存中没有,从数据库查询并存入缓存,并设置超时时间。修...

alwaysBrother的博客 9505

右腿驱动电路设计:从共模干扰原理到生物电采集实战

在生物电信号采集领域,共模干扰是影响测量精度的核心挑战之一,其本质源于环境电磁场通过容性耦合在人体表面产生的感应电流。根据欧姆定律,由于人体组织阻抗的不均衡性,共模电流会在不同测量点产生差异化的压降,从而转化为难以滤除的差分噪声。为解决这一问题,右腿驱动技术应运而生,它通过负反馈原理主动抵消干扰,显著提升系统的共模抑制比。该技术广泛应用于心电图、脑电图等医疗电子设备中,是确保微弱生理信号质量的关键环节。本文结合工程实践,深入剖析了右腿驱动电路中的仪表放大器选型、反馈环路稳定性设计以及PCB布局布线要点,为高

weixin_31476015的博客 440

uni-app 实现高德 / 百度 / 腾讯地图多端导航跳转(H5最全方案)

本文介绍了一套生产级可复用的多地图导航Hook封装方案。针对开发中常见的经纬度顺序混乱、中文乱码、参数不统一等问题,提供了统一解决方案。方案支持高德、百度、腾讯三大地图平台,封装了各平台的URI参数处理逻辑,包括坐标顺序转换、名称编码、导航模式适配等核心功能。通过组合式API设计,开发者只需调用统一入口即可实现多地图导航跳转,同时保留单独调用各平台的能力。文中还总结了6大常见坑点,并推荐默认使用高德地图作为最稳定的导航方案。该方案适用于车辆定位、物流配送等多种业务场景,可封装为可复用的Hooks组件。

专注于前端开发与实战技巧,记录从零到一的学习与项目经验。分享 Vue3 / JavaScript / TypeScript / Flutter /Uniapp等前端技术,以及 性能优化、工程化、最佳实践。 537

源码剖析SpringBoot集成Redis中的序列化问题

源码剖析SpringBoot集成Redis中的序列化问题前言SpringBoot集成Redis@EnableCaching注解RedisCacheConfigurationRedis的put缓存流程Cache的put操作总结 前言 在之前SpringBoot1.x的版本中,集成Redis实现自定义的序列化都是通过定制RedisTemplate来实现的,但是最近在SpringBoot2.x的版本中发...

Futile的博客 591

LVGL core disp显示设计(lv_disp.c)

lv_disp.c当前显示页面的配置scr_act在原始的LVGL是以screen的概念存在,但我们还是习惯叫它为一个页面提供获取top_layer、sys_layer、prev_scr图层接口配置主题管理默认的主题管理是递归查找的,实际项目中因此页面的复杂性,虽然也兼容了此主题管理的方案,但还是推荐使用单页面自行管理主题的方案壁纸设置多页面切换的动画支持计算无用户操作时间清理显示缓存。

Bigan(安)的博客 2330

SpringBoot2使用@Cacheable注解时,Redis中保存的Value为java序列化乱码问题

SpringBoot2使用@Cacheable注解时,Redis中保存的Value为java序列化乱码问题 解决办法: 采用自定义RedisCacheConfiguration组件的方式,向IOC容器中注册一个类型为org.springframework.data.redis.cache.RedisCacheConfiguration的组件,调用serializeValuesWith方法对value的序列化规则改为json类型: /** * 新建一个配置类,通过注册自定义RedisCacheConfig

冲冲冲的博客 763

YOLO11-Seg优化:注意力魔改 | 具有切片操作的SimAM注意力,魔改SimAM

问题点:SimAM计算整张特征图的像素差平均值时加权可能会忽略小目标的重要性,同时与整体平均值相比可能和背景信息相似,导致加权增强较弱;

会AI的学姐 457

ardupilot 方向余弦矩阵/旋转矩阵的理解

本节主要记录自己对ardupilot中用到的方向余弦矩阵/旋转矩阵的理解,欢迎批评指正,有些资料参考网上写的比较好的资料,免得查找资料麻烦。旋转矩阵的坐标理解:表示从旋转矩阵的下标的坐标系的坐标变换到上标表示的坐标系坐标下。旋转矩阵的坐标系理解:表示从旋转矩阵的上标的坐标系变换到下标表示的坐标系下。从旋转矩阵的投影更好理解,比如下面旋转矩阵的第一行是左边坐标系的第一维分量在右边坐标系的投影。

陌城烟雨 612

当使用@cacheable缓存数据遇到的序列化问题

1.问题:使用@cacheable注解报错信息如下,很明显是jackson序列化时出的错误 Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_ARRAY token[["com.xxx.xxx.xxxxxxx.response.SummaryLeftResponse",{"mainpNam

Yangyg_0818的博客 5170

30. 用GPT-4自动生成测试用例的完整流程

利用GPT - 4生成测试用例面临的主要问题包括:如何准确地将软件需求转化为GPT - 4能够理解的输入提示,以确保生成的测试用例覆盖所有关键功能;如何评估生成的测试用例的有效性和充分性;如何处理生成的测试用例中的错误或不合理之处;以及如何将生成的测试用例集成到现有的测试框架中。

AGI×大数据,开启智能时代的认知跃迁;解码AGI,赋能数据驱动的智能革命。 472

【异常】springboot集成@Cacheable缓存乱码的问题解决方案

在网上有很多种写法,我搜索了很多都不适合自己,只有下面这一种可以正常。序列化值导致的,而源码里的配置又没有默认,需要自己去实现。如下代码是我在项目中的代码,加上重启项目。中,相同的操作不会查数据库而是从缓存中获取数据。的可视化管理工具查看缓存的数据时,却发现。其实出现上述乱码,一般情况都是没有配置。会把被标注的方法的返回值缓存到。注解之后,把数据缓存到。

No8g攻城狮的博客 2377

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

redis取值的序列化问题

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springfr

xuanuxan的博客 1313

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

解决Redis存储数据中的双引号问题:序列化的实践技巧

关于Redis里面存储数据,value有双引号的解决办法

数据与算法架构提升之路专栏 3309

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Redis的key和value被序列化为特殊字符串或乱码问题解决

使用redis存入key为a,value为a的键值对时,通过redis的桌面管理器查看到的结果如下: 可以发现key和value值都不是单纯的a,都包含了一些特殊的字符串,或者redis的桌面管理器换一种显示方式还会乱码,如下: 通过修改RedisTemplate的序列化器来解决以上问题,写一个配置类RedisConfig,如下: import org.springframework.beans.factory.annotation.Autowired; import org.springframewo

硅脂味咖啡的博客 4831

SpringBoot使用@Cacheable出现预览工具乱码问题解决

SpringBoot使用@Cacheable出现预览工具乱码问题解决

qq_41939901的博客 403

java读取缓存乱码_@Cacheable 缓存值乱码如何解决?

时隔两年 我遇到了这个问题 搜到了楼主的帖子 最后发现太监了贴一下我找到的解决办法把`//这里序列化解决@Cacheable 存值后value 显示字节码问题@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer redisSerializer = new StringRedisS...

weixin_42528090的博客 1147

关于使用@Cacheable注解时配置RedisTemplate并自定义序列化失效的问题

一、发现问题 如图在serviceImpl中使用@Cacheable 并且自定义了Jackson2JsonRedisSerializer序列化 但是通过查看redis中缓存的数据发现仍然采用的是JDK的序列化方式 二、问题原因 由于采用的是spring的Cache缓存并且配置的缓存方式为redis,而Cache采取的是直接获取RedisCacheManager,并不是RedisTemplate,所以当我们自定义RedisTemplate的序列化时,并不会被Cache采用,如果我们采用的是RedisTe

weixin_45390688的博客 2141

springboot集成redis序列化问题汇总

    spring中使用redis目前接触的到的有两种方式,一种是使用封装的RedisTemplate工具类;另一种是使用Spring Cache,cache实现方式选择RedisCache.两种方案中都需要对序列化方式进行设置,否则会出现二进制格式的数据(不论是Redis desktop manager工具还是redis自带客户端黑窗口打开),如果需要查看数据则会影响观感,关于序列化方式设置底层都是对RedisSerializer接口进行设置,现分别说明为何出现此

weixin_43401380的博客 5758

Spring Boot学习(四):缓存

九、SpringBoot与缓存 1、JSR107 Java Caching定义了5个核心接口 CachingProvider 定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可以在运行期访问多个CachingProvicer。 CacheManager 定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。 Cache 一个类似Map的数

骑着蜗牛行天下 1312

springcache中@Cacheable注解中只用value属性,造成缓存不正确

场景还原 springcache集成redis做缓存的时候, 使用@cacheable(value="cacheName"), 标注一个getA(id)方法和getB(id)方法,那么在默认生成Key的策略SimpleKeyGenerator中,key的生成方式就是用传递的参数拼接生成的 那么id来作为缓存的key,但是id肯定有重复的情况; 我本来以为value属性就是用来区分不同业务...

a1035434631的博客 1万+

springboot 解决 @Cacheable写入乱码的情况

1、在redis 集成管理中 @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { //MyRedisCacheManager 是自定义的 @Bean public CacheManager cacheManager() { RedisSerializer<String> redisSerializer = new StringRedis

strom_xu 922

redis缓存神器:@Cacheable注解

这样,当第一次调用getUserById方法时,会将返回结果缓存起来,下次再调用该方法时,直接从缓存中获取结果,而不是执行方法体。在上述代码中,使用了 PageHelper 插件进行分页查询,并将查询结果缓存到 Redis 中,缓存时间为 1 分钟。在更新数据时,先调用更新方法updateUser,然后再调用查询方法getUserById,此时会更新缓存中的数据。需要注意的是,在使用@Cacheable注解时,被缓存的方法不能抛出异常,否则会导致缓存失效。

java小白翻身 2963

springboot2.2.5自定义RedisCacheManager实现json序列化

在springboot1.x时自定义RedisCacheManager是使用RestTemplate作为参数注入的: @Bean public CacheManager cacheManager(RedisTemplate redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(re...

qq_41534573的博客 2036
上一篇: GetResponseBodyAsStream()方法读取到的响应体流为中文乱码
下一篇: Gitlab安装不使用自带的Nginx
谢谋仁
博客等级 码龄10年 7粉丝 29原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值