在 Spring Boot 中,如果直接使用默认的 RedisTemplate,它默认使用 JDK 序列化(JdkSerializationRedisSerializer)。这会导致存入 Redis 的数据是一堆包含类元信息的二进制字节流,用 redis-cli 查看时全是乱码,且占用内存大。这段代码通过以下配置解决了这个问题:类似这样的乱码\xac\xed\x00\x05t\x00\x05

编写配置文件:要解决的问题

  • Key 的序列化(setKeySerializer & setHashKeySerializer):
    设置为 new StringRedisSerializer()。这意味着 Redis 中的 Key(以及 Hash 结构中的 Field)会被序列化为普通的 UTF-8 字符串。保证了 Key 在 Redis 中的可读性。
  • Value 的序列化(setValueSerializer & setHashValueSerializer):
    使用了 RedisSerializer.json()。这是 Spring Data Redis 4.0+ 版本推荐的新写法(等同于以前常用的 GenericJackson2JsonRedisSerializer)。它会将存入的 Java 对象自动转换为 JSON 字符串格式。这保证了 Value 在 Redis 中的可读性,并且方便跨语言(如 Node.js、Python)读取。

Alt

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        
        // 使用 RedisSerializer.json() 创建 JSON 序列化器(Spring Data Redis 4.0+ 推荐方式)
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(RedisSerializer.json());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(RedisSerializer.json());
        
        return redisTemplate;
    }
}

从 Redis 中读取数据时,底层会自动将 JSON 反序列化回 Java 对象,开发者无需手动处理转换逻辑。

总结

配置完这段代码后,当你在业务代码中执行类似 redisTemplate.opsForValue().set("user:1", new User("张三", 20)) 的操作时:

  1. 存入 Redis 的 Key 会是清晰的 user:1(而不是乱码)。
  2. 存入 Redis 的 Value 会是清晰的 JSON 格式(如 {"name":"张三","age":20,"@class":"com.xxx.User"})。
  3. 从 Redis 中读取数据时,底层会自动将 JSON 反序列化回 Java 对象,开发者无需手动处理转换逻辑。
    在终端:
    key “user:1”
127.0.0.1:6379> keys *
...
n) "user:1"
...
127.0.0.1:6379> get user:1
"\"{\\\"name\\\":\\\"\xe5\xbc\xa0\xe4\xb8\x89\\\",\\\"age\\\":20,\\\"@class\\\":\\\"com.xxx.User\\\"}\""
127.0.0.1:6379>

: Started RedisApplicationTests in 2.741 seconds (process running for 3.639)

Java HotSpot™ 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
{“name”:“张三”,“age”:20,“@class”:“com.xxx.User”}

: INFO 2508 — [ionShutdownHook] com.alibaba.druid.pool.DruidDataSource : {dataSource-0} closing …

ok

更多推荐