Spring Data操作Redis时,发现key值出现 \xac\xed\x00\x05t\x00\tb
原文链接:http://blog.csdn.net/yunhaibin/article/details/9001198
最近在研究redis,以及spring data对redis的支持发现了一个奇怪的现象
先说现象吧,通过redisTemplate下的opsForHash方法存储hash类型的值,操作成功以后,去redis控制台显示keys * 的时候,发现一个奇怪的现象,插入的hash类型的key前面会有一堆的\xac\xed\x00\x05t\x00\tb 这种东西,见图1
(图1)
看见了吗?就是第二行那一串自己冒出来的东西,分析spring-data的org.springframework.data.redis.core.RedisTemplate源代码以后发现:
- private RedisSerializer<?> defaultSerializer = new JdkSerializationRedisSerializer();
- private RedisSerializer keySerializer = null;
- private RedisSerializer valueSerializer = null;
- private RedisSerializer hashKeySerializer = null;
- private RedisSerializer hashValueSerializer = null;
- private RedisSerializer<String> stringSerializer = new StringRedisSerializer();
发现了一个:
- private RedisSerializer<?> defaultSerializer = new JdkSerializationRedisSerializer();
因为spring操作redis是在jedis客户端基础上进行的,而jedis客户端与redis交互的时候协议中定义是用byte类型交互,jedis中提供了string类型转为byte[]类型,但是看到spring-data-redis中RedisTemplate<K, V>在操作的时候k,v是泛型的,所以RedisTemplate中有了上面那段代码,在没有特殊定义的情况下,spring默认采用defaultSerializer = new JdkSerializationRedisSerializer();来对key,value进行序列化操作,在经过查看JdkSerializationRedisSerializer中对序列化的一系列操作,发现如下代码:
- private Converter<Object, byte[]> serializer = new SerializingConverter();
- public byte[] serialize(Object object) {
- if (object == null) {
- return SerializationUtils.EMPTY_ARRAY;
- }
- try {
- return serializer.convert(object);
- } catch (Exception ex) {
- throw new SerializationException("Cannot serialize", ex);
- }
- }
序列化支持的是Object对象,调用了SerializingConverter类下的convert方法转换对象,转换对象的方法是:
- private final Serializer<Object> serializer;
- /**
- * Serializes the source object and returns the byte array result.
- */
- public byte[] convert(Object source) {
- ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128);
- try {
- this.serializer.serialize(source, byteStream);
- return byteStream.toByteArray();
- }
- catch (Throwable ex) {
- throw new SerializationFailedException("Failed to serialize object using " +
- this.serializer.getClass().getSimpleName(), ex);
- }
- }
原因其实就出现在这里,解决的办法就是手动定义序列化的方法,spring-data-redis中还提供了一个序列化的类专门针对string类型的序列化org.springframework.data.redis.serializer.StringRedisSerializer这个类,可以在xml里面指定:
- <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
- p:connection-factory-ref="jedisConnectionFactory">
- <property name="keySerializer">
- <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
- </property>
- <property name="valueSerializer">
- <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
- </property>
- <property name="hashKeySerializer">
- <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
- </property>
- <property name="hashValueSerializer">
- <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
- </property>
- </bean>
其中我将redis中基础类型的key,value和hash类型的key,value都指定为StringRedisSerializer类来进行序列化,然后发现又报错了,找了一会发现我的代码中:
- public void setBank(final Bank bank) {
- // TODO setBank
- final String key = String.format("bank:%s", bank.getId());
- final Map<String, Object> properties = new HashMap<String, Object>();
- properties.put("id", bank.getId());
- properties.put("name", bank.getBank_name());
- redisTemplate.opsForHash().putAll(key, properties);
- }
bank.getId是Integer类型的,因为Hashmap中的key和value也会进行序列化操作,而StringRedisSerializer中的serialize方法只接收String类型的值,如下:
- public byte[] serialize(String string) {
- return (string == null ? null : string.getBytes(charset));
- }
所以这里的类型转换报错了,二话不说直接bank.getId().toString(),执行成功,然后进入redis控制台打开查看发现那堆恶心巴拉的\xac\xed\x00\x05t\x00\tb没有了,大功告成了
(红色部分)
其实redis在使用中,必须要提前考虑的就是内存的占用问题(博客中另外一篇文章很经典,阐述了一个外国人做的测试,同样的存储可以节约几十G的内存【Redis 内存优化】节约内存:Instagram的Redis实践),在设计的时候使用hash可以节约很多的内存,而存储的时候如果每条数据就放一堆\xac\xed\x00\x05t\x00\tb这个东西,肯定是无法直视的
------------------------------------------------------------------------------------------------
Spring Data操作Redis时,发现key值出现 \xac\xed\x00\x05t\x00\tb的更多相关文章
- SpringBoot使用RedisTemplate操作Redis时,key值出现 \xac\xed\x00\x05t\x00\tb
原因分析 原因与RedisTemplate源码中的默认序列化方式有关 defaultSerializer = new JdkSerializationRedisSerializer( classLoa ...
- Spring Data操作Redis详解
Spring Data操作Redis详解 Redis是一种NOSQL数据库,Key-Value形式对数据进行存储,其中数据可以以内存形式存在,也可以持久化到文件系统.Spring data对Redis ...
- redis key/value 出现\xAC\xED\x00\x05t\x00\x05
1.问题现象: 最近使用spring-data-redis 和jedis 操作redis时发现存储在redis中的key不是程序中设置的string值,前面还多出了许多类似\xac\xed\x00\x ...
- Java Spring mvc 操作 Redis 及 Redis 集群
本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5941953.html 关于 Redis 集群搭建可以参考我的另一篇文章 Redis集群搭建与简单使用 R ...
- 160309、Spring AOP操作action时无法注入,报空指针错误
今天帮同事看个问题,action注入失败,代码没问题,主要是stuts2权限移交的问题,特此记录一下 Spring AOP操作action时无法注入,报NullPointer异常 当使用Spring ...
- Spring AOP操作action时无法注入,报NullPointer异常
Spring AOP操作action时无法注入,报NullPointer异常当使用Spring AOP对action层进行操作时,会出现注入失败的问题,出现空指针异常.原因是一般struts2+spr ...
- 【redis】java操作redis时,StringRedisTemplate的expire()方法的作用,什么时候使用
java操作redis时,StringRedisTemplate的expire()方法的作用,什么时候使用 //重新设置过期时间为30分钟,刷新时间 redisTemplate.expire(MsOp ...
- 解决Spring Boot 使用RedisTemplate 存储键值出现乱码 \xac\xed\x00\x05t\x00
spring-data-redis的RedisTemplate<K, V>模板类在操作redis时默认使用JdkSerializationRedisSerializer来进行序列化解决方法 ...
- Spring Data 教程 - Redis
1. Redis简介 Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value ...
随机推荐
- 网络压缩论文集(network compression)
Convolutional Neural Networks ImageNet Models Architecture Design Activation Functions Visualization ...
- spring +servlet 与 spring MVC
spring serlvetSpring框架中context-param与servlet中init-param的contextConfigLocation的区别https://blog.csdn.ne ...
- MVC ---- IEnumerable<T>、List<T> 前台遍历展示
突然做前台数据展示,发现IEnumerable 对一个列表的展示还是可以,但要是多个类型放在一个表中如何处理呢,如下: 一个类IEnumerable遍历 后台 public IEnumerable&l ...
- python os.system command_line
command_line = ("{7} {0} -Xmx{1} -jar {2} -T Pileup -R {3} -I {4} -L {5} -o {6} " + " ...
- 卸载 mysql
sudo apt-get remove mysql-* dpkg -l |grep ^rc|awk '{print $2}' |sudo xargs dpkg -P 之后会跳出一个弹框点击“是”就行了
- wc的使用
统计文件个数 ls -l |grep "^-"|wc -l 统计目录的个数 ls -l|grep "^d"|wc -l 统计文件个数(包括子文件夹) ls -l ...
- [原]设置vs的release版本调试
通过三步设置就可以实现realse下的调试啦: 1.设置“C/C++”------>“常规”------->“调试信息格式”设置成:“程序数据库(/Zi)” 2.设置“链接器”------ ...
- LeetCode--155--最小栈
问题描述: 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈. push(x) -- 将元素 x 推入栈中. pop() -- 删除栈顶的元素. top() -- 获取 ...
- 1月5日 对象Object, 含过去看的英文档的总结链接
Object 也是一种数据类型,可以有属性,有method. 反之,在Ruby中,每一种数据类型都是Object.如String,Integer,Float,Array,Hash. IN Ruby e ...
- codeforces 576a//Vasya and Petya's Game// Codeforces Round #319 (Div. 1)
题意:猜数游戏变种.先选好猜的数,对方会告诉你他想的那个数(1-n)能不能整除你猜的数,问最少猜几个数能保证知道对方想的数是多少? 对一个质数p,如果p^x不猜,那么就无法区分p^(x-1)和p^x, ...