问题描述
项目中如果直接通过RedisTemplate
进行redis的操作,我们在redis数据库可以看到,产生了像乱码一样的东西:
问题原因
严格来说不是乱码,这是因为默认序列化器的问题,RedisTemplate加载时会初始化一个默认序列化器(JdkSerializationRedisSerializer ),程序中使用RedisTemplate将对象序列化后存储到 redis 中就会有这样的问题。
断点进redisTemplate.opsForValue().set()
方法查看源码:
查看rawValue(value)
的实现源码:
通过查看实现类可以看到,实现valueSerializer().serialize(value)
的序列化器有好几个,如果没有初始化的话,默认就是用JdkSerializationRedisSerializer
这个序列化器。
RedisSerializer实现类:
继续看JdkSerializationRedisSerializer
序列化器的实现:
最终是通过ObjectOutputStream
来序列化的。
解决方案
自定义 RedisTemplate 配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| package com.demo.redisdemo.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheWriter; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer;
import java.time.Duration;
@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(RedisSerializer.string()); template.setHashKeySerializer(RedisSerializer.json()); template.setValueSerializer(RedisSerializer.json()); template.setHashValueSerializer(RedisSerializer.json());
return template; }
}
|
如果有报错(jackson相关),需要添加 jackson 相关的包依赖,如果项目本身有依赖spring-mvc的话不会报错。
基本实现原理就是以上这样的,网上也可以查找相关:springboot redistemplate 配置
,都大同小异。