Java中Redis存储String类型会有乱码

文章讲述了在Java中使用RedisTemplate存储String类型数据时遇到的乱码问题,通过分析原因是SpringDataRedis默认使用JDK序列化导致的。解决方案是修改RedisTemplate的序列化器,使用StringRedisSerializer处理key,GenericJackson2JsonRedisSerializer处理value,并添加Jackson依赖。
摘要由CSDN通过智能技术生成

目录:

项目场景:

问题描述

原因分析:

解决方案:

总结:


项目场景:

背景:在java中使用Redis存储String类型的数据时,会出现乱码。


问题描述

例如:在java中创建RedisTemplate操作String类型的数据存储时,会出现乱码,如下代码,

我写了一条存储key为name,值为虎哥的字符串。

然后获取一下这个key为name的值,打印得到的值

package com.sxy.redis;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
class SpringDataRedisDemoApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void contextLoads() {
        //        写入一条String数据
        redisTemplate.opsForValue().set("name", "虎哥");
        //        获取String数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name=" + name);

    }

}

我们可以看到出现了乱码问题:这里不单单是值出现了乱码,而且key也有乱码问题


原因分析:

Redis的序列化分析:

因为SpringDataRedis的功能可以接收任何类型的对象,可以帮我们将java对象转成Redis可处理的字节,所以我们存进去的 name和虎哥 都被当成了java对象,而redisTemplate的底层,默认对这些对象得处理方式就是利用JDK的序列化工具,ObjectOutPutStream

进入redisTemplate我们发现了四个属性的值都是对应的数据的序列化

这里我们发现上面四个属性的值的,都是下面这个方法定义的默认的jdk的序列化器

通过断点调试redisTemplate.opsForValue().set("name", "虎哥");我们可以发现,进入了JdkSerializationRedisSerializer的类中

最后进入了这里,可以看到有ObjectOutputStream来写对象,这个流的作用就是把java对象转换为字节进行writeObject进行写入

所以我们看到的值就是这样子的数据

缺点:

  • 可读性差
  • 内存占用较大

解决方案:

我们可以通过修改RedisTemplate的序列化来实现数据乱码问题。

RedisSerializer有一些实现类

这里会有两个我们需要用到的

  1. StringRedisSerializer
    1. 如果我的key和hash可以是字符串的情况下就用它
  2. GenericJackson2JsonRedisSerializer
    1. 如果我的值是对象就用它

上代码:

代码如下,写了一个配置类注册Bean对象给spring容器管理

package com.sxy.redis.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
//        创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
//        设置连接工厂
        template.setConnectionFactory(redisConnectionFactory);
//        创建JSON序列化工具
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//        设置key的序列化为 = String
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
//        设置value的序列化为 = GenericJackson2JsonRedisSerializer
        template.setValueSerializer(genericJackson2JsonRedisSerializer);
        template.setHashValueSerializer(genericJackson2JsonRedisSerializer);
//        返回
        return template;
    }
}
  

注意:如果这里运行的话会报错为如下:

Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException

这是个明显的错误,告诉我们用了如下这个JSON序列化类没有引入jackson的依赖才报错

 GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = 
new GenericJackson2JsonRedisSerializer();

我们只需要添加如下依赖即可

<!--        Jackson依赖-->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>

随后我们尝试对其进行写入和读取数据,发现key和value都是正常的显示

总结:

直接在java中使用RedisTemplate模板进行写入字符串数据时会出现,key和value都是乱码问题,

我们修改了RedisTemplate默认的序列化器StringRedisSerializer即可解决此问题。

如果有其他问题:欢迎在下方评论区留言。各位博友,点赞+评论+收藏呗。

  • 25
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

树若逝花若殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值