Java中Redis存储String类型会有乱码的问题及解决方案

 更新时间:2024年04月03日 11:11:52   作者:树若逝花若殇  
在java中使用Redis存储String类型的数据时,会出现乱码,我写了一条存储key为name,值为虎哥的字符串,然后获取一下这个key为name的值,打印得到的值,下面通过实例代码介绍Java中Redis存储String类型会有乱码的问题及解决方案,一起看看吧

项目场景:

背景:在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有一些实现类

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

  • StringRedisSerializer

    如果我的key和hash可以是字符串的情况下就用它

  • GenericJackson2JsonRedisSerializer

    如果我的值是对象就用它

上代码:

代码如下,写了一个配置类注册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即可解决此问题。

到此这篇关于Java中Redis存储String类型会有乱码的文章就介绍到这了,更多相关java redis存储乱码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • idea中将单个java类导出为jar包文件的方法

    idea中将单个java类导出为jar包文件的方法

    这篇文章主要给大家介绍了关于idea中将单个java类导出为jar包文件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09
  • 关于Seata基本使用及二阶提交流程

    关于Seata基本使用及二阶提交流程

    这篇文章主要介绍了关于Seata基本使用及二阶提交流程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • SpringBoot配置文件注入值的简单实现

    SpringBoot配置文件注入值的简单实现

    本文主要介绍了SpringBoot配置文件注入值的简单实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-11-11
  • Java多线程中的ReentrantLock可中断锁详细解读

    Java多线程中的ReentrantLock可中断锁详细解读

    这篇文章主要介绍了Java多线程中的ReentrantLock可中断锁详细解读,ReentrantLock中的lockInterruptibly()方法使得线程可以在被阻塞时响应中断,比如一个线程t1通过lockInterruptibly()方法获取到一个可重入锁,并执行一个长时间的任务,需要的朋友可以参考下
    2023-12-12
  • 模仿Spring手写一个简易的IOC

    模仿Spring手写一个简易的IOC

    这篇文章主要介绍了模仿Spring手写一个简易的IOC,帮助大家更好的理解和学习spring框架,感兴趣的朋友可以了解下
    2020-11-11
  • mybaties plus实体类设置typeHandler不生效的解决

    mybaties plus实体类设置typeHandler不生效的解决

    这篇文章主要介绍了mybaties plus实体类设置typeHandler不生效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • Spring-AOP-ProceedingJoinPoint的使用详解

    Spring-AOP-ProceedingJoinPoint的使用详解

    这篇文章主要介绍了Spring-AOP-ProceedingJoinPoint的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • 详解Spring-Boot集成Spring session并存入redis

    详解Spring-Boot集成Spring session并存入redis

    这篇文章主要介绍了详解Spring-Boot集成Spring session并存入redis,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • Java操作Zookeeper原理及过程详解

    Java操作Zookeeper原理及过程详解

    这篇文章主要介绍了Java操作Zookeeper原理及过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Java报错Java.net.SocketTimeoutException的几种解决方法

    Java报错Java.net.SocketTimeoutException的几种解决方法

    在 Java 网络编程中,SocketTimeoutException 通常表示在进行网络操作时,等待响应的时间超过了设定的超时时间,本文将深入探讨 Java.net.SocketTimeoutException 的问题,并为开发者和环境配置者提供详细的解决方案,需要的朋友可以参考下
    2024-10-10

最新评论