【日常踩坑】SpringBoot使用RedisTemplate保存Map时key、value都出现乱码

本文解析了SpringBoot使用RedisTemplate保存Map时出现乱码的原因,包括redis key中存在二进制字符及未指定过期时间类型导致的问题,并提供了解决方案:自定义序列化类及明确指定过期时间单位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringBoot使用RedisTemplate保存Map时key、value都出现乱码,类似于(\x00\x00\x00)

原因

redis key存在二进制字符

是因为redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码,所以需要自定义序列化类来对redis key进行序列化

redis value(Map对象存在乱码)

是因为是因为使用redisTemplate 保存时,指定了过期时间,但是没有指定过期时间的类型,即缺少(TimeUnit.SECONDS)

redisTemplate.opsForValue().set(MonitorConstants.DOMAIN_WEBSITE_NUM_STATISTIC, parseList(result),10*60, TimeUnit.SECONDS);

解决方法

redis key存在二进制字符

创建配置类,自定义redisTemplate序列化类

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    /**
     * redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }

redis value(Map对象存在乱码)

指定过期时间的时间类型即可

redisTemplate.opsForValue().set(MonitorConstants.DOMAIN_WEBSITE_NUM_STATISTIC, parseList(result),10*60);

改为

redisTemplate.opsForValue().set(MonitorConstants.DOMAIN_WEBSITE_NUM_STATISTIC, parseList(result),10*60, TimeUnit.SECONDS);
<think>好的,我现在需要帮助用户了解如何在Java Spring中使用RedisTemplate进行数据缓存操作。用户明确提到了示例,所以我要确保提供具体的代码片段,并且覆盖不同的数据结构,比如String、List、Hash等。 首先,我应该回忆一下用户提供的引用内容。引用[1]提到RedisTemplate可以操作String、List、Set、Hash、Zset,其中List和Hash会被重点介绍。引用[2]给出了使用RedisTemplate进行基本设置的示例,但用户可能需要更全面的例子。引用[3]说明RedisTemplate提供了各种方法,所以需要详细解释主要功能。 接下来,我需要组织回答的结构。用户需要使用方法示例,所以分点讲解不同的数据结构操作比较清晰。比如,先配置RedisTemplate,然后分别讲解String、List、Hash的操作,每个部分给出代码示例。同,用户可能关心常见问题和易错点,比如序列化问题、键的设计、事务管理等,这部分也需要包含进去。 在配置部分,要提到配置类中使用@Bean创建RedisTemplate实例,并设置连接工厂和序列化方式。这里需要注意,默认的序列化可能使用JdkSerializationRedisSerializer,导致键有乱码,所以建议使用StringRedisSerializer,这点在引用[2]中也提到了序列化问题,需要强调。 对于String类型操作,使用opsForValue()方法,示例中的set和get方法要展示出来。List类型使用opsForList(),展示左右推入、范围获取等操作。Hash类型使用opsForHash(),展示put、get、entries等方法。 在常见问题部分,需要列举序列化问题、键设计、事务管理、连接泄漏和过期间设置。这些都是用户在实际使用中可能遇到的,比如忘记配置序列化导致存储异常,或者键设计不合理引发冲突,这些都需要提醒用户注意。 最后,生成相关问题,帮助用户进一步学习。问题可以涉及更深入的操作,比如Set和Zset的使用、性能优化、集群配置等,以及与其他缓存方案的比较。 检查是否所有代码示例都正确使用RedisTemplate的方法,比如opsForValue()、opsForList()是否正确调用。确保所有步骤符合Spring Data Redis的最佳实践,并且示例代码没有语法错误。同,确保引用的标注正确,引用[1]、[2]、[3]在适当的位置被提及,比如在配置序列化提到引用[2]的序列化问题。 总结来说,回答需要结构清晰,步骤明确,覆盖主要的数据结构操作,并指出常见错误,帮助用户正确使用RedisTemplate进行缓存操作。</think>### RedisTemplate 使用详解 RedisTemplate 是 Spring Data Redis 提供的核心工具类,支持对 Redis 的多种数据结构的操作。以下是具体使用方法和示例。 --- #### **1. 配置 RedisTemplate** 在 Spring 配置类中注入 `RedisTemplate`,并设置序列化方式(默认序列化可能导致键值显示异常,建议手动配置): ```java @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); // 键使用字符串序列化 template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // 值使用JSON序列化 return template; } } ``` [^2] --- #### **2. 基本操作示例** ##### **String 类型操作** ```java @Autowired private RedisTemplate<String, Object> redisTemplate; // 存储值 public void setValue(String key, Object value) { redisTemplate.opsForValue().set(key, value); } // 获取值 public Object getValue(String key) { return redisTemplate.opsForValue().get(key); } ``` ##### **List 类型操作** ```java // 左推入列表 public void leftPush(String key, Object value) { redisTemplate.opsForList().leftPush(key, value); } // 获取列表范围 public List<Object> range(String key, int start, int end) { return redisTemplate.opsForList().range(key, start, end); } ``` ##### **Hash 类型操作** ```java // 存储哈希字段 public void putHash(String key, String hashKey, Object value) { redisTemplate.opsForHash().put(key, hashKey, value); } // 获取哈希字段值 public Object getHash(String key, String hashKey) { return redisTemplate.opsForHash().get(key, hashKey); } // 获取整个哈希 public Map<Object, Object> entries(String key) { return redisTemplate.opsForHash().entries(key); } ``` [^1][^3] --- #### **3. 常见问题与易错点** 1. **序列化问题** - 默认使用 `JdkSerializationRedisSerializer` 可能导致键值包含乱码,建议显式配置序列化方式(如 `StringRedisSerializer`)。 - 示例:`redisTemplate.setKeySerializer(new StringRedisSerializer())`。 2. **键的设计** - 键名需唯一且易读,例如 `user:123:profile`,避免不同业务的数据冲突。 3. **事务管理** - RedisTemplate 默认不开启事务,需通过 `execute(SessionCallback)` 实现: ```java redisTemplate.execute(new SessionCallback<>() { public Object execute(RedisOperations operations) { operations.multi(); operations.opsForValue().set("key1", "value1"); operations.opsForValue().set("key2", "value2"); return operations.exec(); } }); ``` 4. **连接泄漏** - 确保每次操作后释放连接,可通过 `try-with-resources` 或正确配置连接池。 5. **过期间设置** - 使用 `expire(key, timeout, timeUnit)` 设置键的过期间: ```java redisTemplate.expire("user:123", 30, TimeUnit.MINUTES); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值