springboot集成@Cacheable緩存亂碼的問(wèn)題解決
一、問(wèn)題及現(xiàn)象
會(huì)把被標(biāo)注的方法的返回值緩存到 Redis 中,相同的操作不會(huì)查數(shù)據(jù)庫(kù)而是從緩存中獲取數(shù)據(jù)。
Springboot 集成 Redis,使用 @Cacheable 注解之后,把數(shù)據(jù)緩存到 Redis 中,數(shù)據(jù)是保存在Redis 中了,但是,通過(guò) Redis 的可視化管理工具查看緩存的數(shù)據(jù)時(shí),卻發(fā)現(xiàn) redis 中的 key 正常,但是 value 是亂碼。如下圖所示的亂碼:

修改過(guò)后,可以正常顯示,如下圖:

二、原因分析
其實(shí)出現(xiàn)上述亂碼,一般情況都是沒(méi)有配置 redis 序列化值導(dǎo)致的,而源碼里的配置又沒(méi)有默認(rèn),需要自己去實(shí)現(xiàn)。
在網(wǎng)上有很多種寫法,我搜索了很多都不適合自己,只有下面這一種可以正常。
三、解決方案
添加一個(gè) Redis 的配置類即可。如下代碼是我在項(xiàng)目中的代碼,加上重啟項(xiàng)目 Redis 緩存中的 value 即可正常顯示。
package com.iot.back.message.process.config;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
/**
* <p>RedisConfig 此類用于:Redis相關(guān)配置,用于解決存入Redis中值亂碼問(wèn)題 </p>
* <p>@author:hujm</p>
* <p>@date:2022年08月18日 18:04</p>
* <p>@remark:</p>
*/
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
CacheProperties.Redis redisProperties = cacheProperties.getRedis();
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
// 序列化值
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer()));
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixKeysWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}
使用 @Cacheable 注解的類
package com.iot.back.message.process.rpc;
import com.iot.back.message.process.convert.DeviceBasicInfoConvert;
import com.iot.back.message.process.dto.DeviceBasicInfoDTO;
import com.iot.basic.iotsmarthome.api.client.device.DeviceCloudClient;
import com.iot.basic.iotsmarthome.api.response.device.DeviceBasicInfoResponse;
import com.iot.framework.core.response.CommResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>DeviceBasicInfoRpc 此類用于:設(shè)備基本信息遠(yuǎn)程調(diào)用 </p>
* <p>@author:hujm</p>
* <p>@date:2022年05月23日 15:07</p>
* <p>@remark:</p>
*/
@Slf4j
@Component
public class DeviceBasicInfoRpc {
@Resource
private DeviceCloudClient deviceCloudClient;
@Cacheable(cacheNames = "back-process-service:cache", key = "#sn+':'+#deviceId", sync = true)
public DeviceBasicInfoDTO getDeviceBasicInfo(String sn, Integer deviceId) {
CommResponse<DeviceBasicInfoResponse> deviceBasicInfoCommResponse = deviceCloudClient.getDeviceBasicInfo(sn, deviceId);
if (deviceBasicInfoCommResponse == null || deviceBasicInfoCommResponse.isFail()) {
log.error("P0|DeviceBasicInfoRpc|getDeviceBasicInfo|調(diào)用設(shè)備云服務(wù)時(shí),根據(jù)sn和deviceId獲取設(shè)備基礎(chǔ)信息失?。?);
return null;
}
DeviceBasicInfoResponse deviceBasicInfoResponse = deviceBasicInfoCommResponse.getData();
return DeviceBasicInfoConvert.INSTANCE.convert2DeviceBasicInfoDTO(deviceBasicInfoResponse);
}
}
到此這篇關(guān)于springboot集成@Cacheable緩存亂碼的問(wèn)題解決的文章就介紹到這了,更多相關(guān)springboot集成@Cacheable緩存亂碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring?boot項(xiàng)目使用@Async注解的坑
這篇文章主要為大家介紹了spring?boot項(xiàng)目中使用@Async注解遇到的坑示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Hutool開(kāi)發(fā)利器MapProxy類使用技巧詳解
這篇文章主要為大家介紹了Hutool開(kāi)發(fā)利器MapProxy類使用技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
swagger的請(qǐng)求參數(shù)不顯示,@Apimodel的坑點(diǎn)及解決
這篇文章主要介紹了swagger的請(qǐng)求參數(shù)不顯示,@Apimodel的坑點(diǎn)及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
java編譯后的文件出現(xiàn)xx$1.class的原因及解決方式
這篇文章主要介紹了java編譯后的文件出現(xiàn)xx$1.class的原因及解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
IDEA配置和啟動(dòng)maven項(xiàng)目詳細(xì)步驟
本文介紹了從SVN檢出Web項(xiàng)目并進(jìn)行Maven化、JDK和項(xiàng)目結(jié)構(gòu)配置、Spring和Tomcat環(huán)境搭建的詳細(xì)步驟,幫助讀者順利完成Java Web項(xiàng)目的開(kāi)發(fā)環(huán)境搭建2025-10-10
Java SpringBoot+vue+實(shí)戰(zhàn)項(xiàng)目詳解
這篇文章主要介紹了SpringBoot+VUE實(shí)現(xiàn)前后端分離的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-09-09
Java使用位運(yùn)算實(shí)現(xiàn)權(quán)限管理的示例詳解
在開(kāi)發(fā)中,權(quán)限管理是一個(gè)非常常見(jiàn)的需求,本文將詳細(xì)講解如何使用 Java 中的 位運(yùn)算 實(shí)現(xiàn)一個(gè)輕量級(jí)、高效的權(quán)限管理系統(tǒng),并提供完整的代碼示例和解釋,感興趣的小伙伴可以了解下2025-06-06
一文掌握J(rèn)ava開(kāi)發(fā)工具M(jìn)aven(簡(jiǎn)單上手)
掌握maven的相關(guān)知識(shí)是Java開(kāi)發(fā)必備的技能,今天通過(guò)本文從入門安裝開(kāi)始,逐步深入講解maven的相關(guān)知識(shí),包括maven的安裝到簡(jiǎn)單上手maven項(xiàng)目開(kāi)發(fā),感興趣的朋友跟隨小編一起看看吧2021-06-06

