redis 值字符串前面部分乱码_Spring-RedisTemplate写入数据乱码问题的复现与解决
org.springframework.data.redis是Spring框架对Redis的默认集成,我们在实际项目中,也经常使用它的RedisTemplate去操作Redis,一般来说没什么问题,但是细心一点的同学会发现,经过这种方法写入redis的数据会出现乱码问题
问题复现
项目依赖
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 RedisTemplate functionDomainRedisTemplate() {
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 ListOperations listOperations;
@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(RedisTemplate redisTemplate, 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 () {
List list = 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的值貌似不太好解决)
如果一定要更换策略,那么前往要注意,存储数据的类型要根据所选择的序列化策略去进行切换
redis 值字符串前面部分乱码_Spring-RedisTemplate写入数据乱码问题的复现与解决相关推荐
- (已解决)RedisTemplate写入数据 \xAC\xED\x00\x05t\x00 序列化问题
先看现象: Spring使用RedisTemplate进行数据缓存的时候,发现缓存的数据有序列化问题 话不多说,上图 不仅仅是key出现这种序列化问题,而且value也会出现这种情况 先把解决方案放着 ...
- redis 值字符串前面部分乱码_解决spring boot redis序列化key-value乱码
最近使用spring-data-redis RedisTemplate 操作redis时发现存储在redis中的key不是设置的string值, 前面还多出了许多类似\xac\xed\x00\x05t ...
- redis 值字符串前面部分乱码_使用redis添加的数据,value有乱码前缀
Cache cache = Redis.(); String value = "android"+queue.size(); String key = "123" ...
- redis 值字符串前面部分乱码_StringBoot 整合Redis解决存储乱码(通过StringRedisSerializer来进行序列化)...
org.springframework.boot spring-boot-starter-redis 1.4.7.RELEASE 注意: spring-boot-starter-data-redis ...
- redis 值字符串前面部分乱码_redis key乱码
{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...
- linux mariadb 乱码,MariaDB插入中文数据乱码解决过程
基本情况: MariaDB安装方式:yum 乱码解决过程: 1.查看当前数据库编码(登录数据库后) # show variables like 'character%'; (上图为已经配置成功) 2. ...
- linux版本kettle 中文乱码,kettle工具同步数据乱码-Linux下乱码问题二
json校验 直接百度:json在线解析 或 json.cnhttp://json.cn/ json格式校验的.这个更加简洁些. SQL语句构建器类 问题 Java程序员面对的最痛苦的事情之一就是 ...
- mysql写入数据乱码问题的解决
mysql默认编码为latin. 我的mysql版本为5.6.安装路径下没有my.ini,但是有my-default.ini.其实mysql没有配置文件也是可以启动的,但是为了设置编码,需要将my-d ...
- RedisTemplate写入Redis数据出现无意义乱码前缀\xac\xed\x00\x05
背景 项目使用Spring的RedisTemplate进行Redis数据存取操作,实际应用中发现Redis中key和value会出现"无意义"乱码前缀\xac\xed\x00\x0 ...
最新文章
- 团队文化之表扬和批评
- Android 之UID and PID
- 红帽linux cd命令,redhat linux 文件操作
- Spring security/Shiro ---登陆成功后返回登陆前界面<页面重定向>
- 人工智能时代,学好数学有什么用?
- 【UOJ139】【UER #4】被删除的黑白树
- SpringCloud微框架系列整体模块梳理
- Linux设备驱动--块设备(一)之概念和框架(转)
- 基于line2d算法的模板匹配
- 窗口启动特效,使用win32 api
- 瑞信:区块链技术还在半山腰 2025年才能真正成熟
- linux下oracle完全卸载,linux环境下卸载oracle 11g
- Echarts地图高亮循环数据展示
- 【060】助力一箭四星,翼辉系统再续辉煌
- Cross-speaker Style Transfer with Prosody Bottleneck in Neural Speech Synthesis
- Windows Defender保护历史记录清空方法
- JavaWeb_CSS(14)_文字处理_字体和字号
- qt调用simsimi api实现小黄鸡
- vue无法加载文件C:\Users\Administrator\AppData\Roaming\npm\vue.ps1因为在此系统上禁止运行脚本……解决办法
- 明年9月,南京大学苏州校区将正式招生!