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

 更新时间:2024年04月03日 11:11:52   作者:树若逝花若殇  
在java中使用Redis存储String类型的数据时,会出现乱码,我写了一条存储key为name,值为虎哥的字符串,然后获取一下这个key为name的值,打印得到的值,下面通过实例代码介绍Java中Redis存储String类型会有乱码的问题及解决方案,一起看看吧
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

项目场景:

背景:在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存储乱码内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • Spring Cloud Alibaba和Dubbo融合实现

    Spring Cloud Alibaba和Dubbo融合实现

    这篇文章主要介绍了Spring Cloud Alibaba和Dubbo融合实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • 如何使用java判断是不是数字

    如何使用java判断是不是数字

    这篇文章主要给大家介绍了关于如何使用java判断是不是数字的相关资料,判断一个字符串是否为数字是Java开发中很常见的业务需求,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • 基于log4j2.properties踩坑与填坑

    基于log4j2.properties踩坑与填坑

    这篇文章主要介绍了log4j2.properties踩坑与填坑方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • mybatis的mapper特殊字符转移及动态SQL条件查询小结

    mybatis的mapper特殊字符转移及动态SQL条件查询小结

    mybatis mapper文件中条件查询符,如>=,<,之类是不能直接写的会报错的需要转移一下,本文给大家介绍了常见的条件查询操作,对mybatis的mapper特殊字符及动态SQL条件查询相关知识感兴趣的朋友一起看看吧
    2021-09-09
  • 使用JPA+querydsl如何实现多条件动态查询

    使用JPA+querydsl如何实现多条件动态查询

    这篇文章主要介绍了使用JPA+querydsl如何实现多条件动态查询,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • 浅谈Java方法的重载

    浅谈Java方法的重载

    方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。调用重载方法时,Java编译器能通过检查调用的方法的参数类型和个数选择一个恰当的方法。方法重载通常用于创建完成一组任务相似但参数的类型或参数的个数不同的方法。
    2016-04-04
  • SpringBoot?@InitBinder注解绑定请求参数的过程详解

    SpringBoot?@InitBinder注解绑定请求参数的过程详解

    这篇文章主要介绍了SpringBoot?@InitBinder注解绑定请求参数,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • 一文讲透为什么遍历LinkedList要用增强型for循环

    一文讲透为什么遍历LinkedList要用增强型for循环

    这篇文章主要为大家介绍了为什么遍历LinkedList要用增强型for循环的透彻详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • springboot如何通过不同的策略动态调用不同的实现类

    springboot如何通过不同的策略动态调用不同的实现类

    这篇文章主要介绍了springboot如何通过不同的策略动态调用不同的实现类,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Java 栈和队列的交互实现

    Java 栈和队列的交互实现

    栈和队列都是常用的数据结构,本文就来介绍一下Java 栈和队列的交互实现,主要包括队列模拟实现栈及栈模拟实现队列,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12

最新评论

?


http://www.vxiaotou.com