Springboot中使用redis的乱码问题

问题描述

项目中如果直接通过RedisTemplate进行redis的操作,我们在redis数据库可以看到,产生了像乱码一样的东西:

乱码问题

问题原因

严格来说不是乱码,这是因为默认序列化器的问题,RedisTemplate加载时会初始化一个默认序列化器(JdkSerializationRedisSerializer ),程序中使用RedisTemplate将对象序列化后存储到 redis 中就会有这样的问题。

RedisTemplate默认序列化器加载

断点进redisTemplate.opsForValue().set()方法查看源码:

序列化源码1

查看rawValue(value)的实现源码:

序列化源码2

通过查看实现类可以看到,实现valueSerializer().serialize(value)的序列化器有好几个,如果没有初始化的话,默认就是用JdkSerializationRedisSerializer这个序列化器。

RedisSerializer实现类:

RedisSerializer实现类

继续看JdkSerializationRedisSerializer 序列化器的实现:

JdkSerializationRedisSerializer序列化实现

JdkSerializationRedisSerializer序列化实现2

JdkSerializationRedisSerializer序列化实现3

最终是通过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 对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 设置连接工厂
template.setConnectionFactory(factory);
// 设置key序列化器
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.json());
// 设置value序列化器
template.setValueSerializer(RedisSerializer.json());
template.setHashValueSerializer(RedisSerializer.json());

// 返回
return template;
}

}

如果有报错(jackson相关),需要添加 jackson 相关的包依赖,如果项目本身有依赖spring-mvc的话不会报错。

基本实现原理就是以上这样的,网上也可以查找相关:springboot redistemplate 配置,都大同小异。


Springboot中使用redis的乱码问题
https://binbiubiu.github.io/20221103140000/
作者
Binbiubiu
发布于
2022年11月3日