0
点赞
收藏
分享

微信扫一扫

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

以沫的窝 2022-08-20 阅读 40

本文目录

一、问题及现象

二、原因分析

三、解决方案


一、问题及现象

会把被标注的方法的返回值缓存到 Redis 中,相同的操作不会查数据库而是从缓存中获取数据。

Springboot 集成 Redis,使用 @Cacheable 注解之后,把数据缓存到 Redis 中,数据是保存在Redis 中了,但是,通过 Redis 的可视化管理工具查看缓存的数据时,却发现 redis 中的 key 正常,但是 value 是乱码。如下图所示的乱码:

修改过后,可以正常显示,如下图:

二、原因分析

其实出现上述乱码,一般情况都是没有配置 redis 序列化值导致的,而源码里的配置又没有默认,需要自己去实现。

在网上有很多种写法,我搜索了很多都不适合自己,只有下面这一种可以正常。

三、解决方案

添加一个 Redis 的配置类即可。如下代码是我在项目中的代码,加上重启项目 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相关配置,用于解决存入Redis中值乱码问题 </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 此类用于:设备基本信息远程调用 </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|调用设备云服务时,根据sn和deviceId获取设备基础信息失败!");
return null;
}

DeviceBasicInfoResponse deviceBasicInfoResponse = deviceBasicInfoCommResponse.getData();

return DeviceBasicInfoConvert.INSTANCE.convert2DeviceBasicInfoDTO(deviceBasicInfoResponse);
}
}

完结!

举报

相关推荐

0 条评论