Spring-RedisTemplate写入数据出现乱码怎么解决
本篇内容介绍了“Spring-redisTemplate写入数据出现乱码怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
成都创新互联,专注为中小企业提供官网建设、营销型网站制作、响应式网站开发、展示型成都做网站、成都网站设计等服务,帮助中小企业通过网站体现价值、有效益。帮助企业快速建站、解决网站建设与网站营销推广问题。
问题复现
项目依赖
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-data-redis
Redis配置
yaml文件配置
spring: application: name: booklet-redis redis: host: 127.0.0.1 port: 6379 password: adminadmin timeout: 5000ms
Redis配置类
package com.liumapp.booklet.redis.config; import org.springframework.beans.factory.annotation.Autowired; 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.*; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { /** * 注入 RedisConnectionFactory */ @Autowired RedisConnectionFactory redisConnectionFactory; @Bean public RedisTemplatefunctionDomainRedisTemplate() { RedisTemplate redisTemplate = new RedisTemplate<>(); initDomainRedisTemplate(redisTemplate, redisConnectionFactory); return redisTemplate; } /** * 设置数据存入 redis 的序列化方式 * * @param redisTemplate * @param factory */ private void initDomainRedisTemplate(RedisTemplate redisTemplate, RedisConnectionFactory factory) { redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setConnectionFactory(factory); } /** * 实例化 HashOperations 对象,可以使用 Hash 类型操作 * * @param redisTemplate * @return */ @Bean public HashOperations hashOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForHash(); } /** * 实例化 ValueOperations 对象,可以使用 String 操作 * * @param redisTemplate * @return */ @Bean public ValueOperations valueOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForValue(); } /** * 实例化 ListOperations 对象,可以使用 List 操作 * * @param redisTemplate * @return */ @Bean public ListOperations listOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForList(); } /** * 实例化 SetOperations 对象,可以使用 Set 操作 * * @param redisTemplate * @return */ @Bean public SetOperations setOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForSet(); } /** * 实例化 ZSetOperations 对象,可以使用 ZSet 操作 * * @param redisTemplate * @return */ @Bean public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForZSet(); } }
测试代码
package com.liumapp.booklet.redis; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.ListOperations; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; @SpringBootTest(classes = BookletRedisMain.class) @RunWith(SpringRunner.class) public class BookletRedisMainTest { @Resource private ListOperationslistOperations; @Test public void leftPushTest () { List list = new ArrayList<>(); list.add("hello world"); listOperations.leftPush("listKey", list); } }
运行上述测试代码后,我们会在redis中插入一组list类型的数据,其key为listKey,value为只有一个元素的list对象
接下来我们通过redis-cli去获取listKey这个值,可以看到乱码的出现:
127.0.0.1:6379> LRANGE listKey 0 10 1) "\xac\xed\x00\x05sr\x00\x13java.util.ArrayListx\x81\xd2\x1d\x99\xc7a\x9d\x03\x00\x01I\x00\x04sizexp\x00\x00\x00\x01w\x04\x00\x00\x00\x01t\x00\x0bhello worldx"
当然,这对于我们项目的实际使用没有什么影响,在程序中再次获取listKey也不会出现乱码,只有通过redis-cli等工具直接取值的时候,才会出现乱码
问题出现原因
问题原因在于我们对Redis进行配置的这一段代码(事实上这也是redisTemplate的默认配置代码):
private void initDomainRedisTemplate(RedisTemplateredisTemplate, RedisConnectionFactory factory) { redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setConnectionFactory(factory); }
在这里,redisTemplate对HashValue和Value的序列化类采用的是JDK默认的序列化策略,而不是String类型的序列化策略,所以我们在redis-cli中看到的value会因为序列化策略的问题,出现乱码
解决办法
将JDK默认的序列化策略更换为String类型的序列化策略
redisTemplate.setHashValueSerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer());
但是这样做的话,我们在进行存储的时候,也只能存储String类型的数据,所以测试代码要进行如下修改
@Test public void leftPushTest () { Listlist = new ArrayList<>(); list.add("hello world2"); listOperations.leftPush("listKey", list.toString()); }
再一次去redis-cli中取值,得到如下结果:
127.0.0.1:6379> LRANGE listKey 0 10 1) "[hello world2]" 2) "\xac\xed\x00\x05sr\x00\x13java.util.ArrayListx\x81\xd2\x1d\x99\xc7a\x9d\x03\x00\x01I\x00\x04sizexp\x00\x00\x00\x01w\x04\x00\x00\x00\x01t\x00\x0bhello worldx"
可以发现乱码问题已经解决
总结
不建议更换redisTemplate默认的序列化策略,有乱码就让它乱着吧,反正知道正确的解码策略就不会影响程序的正常运行(不过通过php等其他语言去获取redis的值貌似不太好解决)
“Spring-RedisTemplate写入数据出现乱码怎么解决”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!
网页标题:Spring-RedisTemplate写入数据出现乱码怎么解决
文章出自:http://scyanting.com/article/jcghoi.html