文档章节

Spring Data操作Redis时,发现key值出现\xAC\xED\x00\x05t\x00

小致dad
 小致dad
发布于 2016/12/10 21:48
字数 700
阅读 502
收藏 3
点赞 0
评论 0

最近在研究Redis,以及spring data对redis的支持发现了一个奇怪的现象

先说现象吧,通过redisTemplate下的opsForHash方法存储hash类型的值,操作成功以后,去redis控制台显示keys * 的时候,发现一个奇怪的现象,插入的hash类型的key前面会有一堆的\xAC\xED\x00\x05t\x00 ,分析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没有了,大功告成了

© 著作权归作者所有

共有 人打赏支持
小致dad
粉丝 114
博文 496
码字总数 549917
作品 0
济南
技术主管
redis配置及和spring的各种结合

下载 编译安装运行 如果出错使用安装成功后,会自动把一些可执行文件复制到环境变量/usr/local/bin/下 redis根目录下有2个重要的配置文件 redis.conf #redis本身的配置文件 sentinel.conf #容...

whaon ⋅ 2016/07/14 ⋅ 0

Redis Monitor命令

使用的语言是Java,使用的Redis客户端为Jedis 我调用redis的monitor命令捕获一条如下信息 1437562679.165098 [0 192.168.14.71:54692] "SET" "xe5x90x8cxe5xadxa6" "xacxedx00x05srx00x13co......

清风-蓝魔泪 ⋅ 2015/07/22 ⋅ 1

RedisHttpSession 的设计与实现

本文作者:伯乐在线 -肖汉松 。未经作者许可,禁止转载! 欢迎加入伯乐在线专栏作者。 前言 RedisHttpSession 是我的一个 Java 开源项目,通过将 Session 存储在 Redis 中实现多服务器间共享...

伯乐在线 ⋅ 2016/07/30 ⋅ 0

关于Spring Data redis几种对象序列化的比较

问题 最近在整一个spring data redis,网上有一本《Spring Data》的电子书(我一个朋友正在翻译,应该今年会有中文版出来,人邮的),下载来看了一下,其中第8章讲到了Spring data对redis的支...

stamen ⋅ 2015/08/21 ⋅ 0

请教一个JdbcTemplate reparedStatement的问题

this.jdbcTemplate.update("INSERT INTO XXX VALUES(?,?,?,?,?,?,?,?)", new Object[]{'1','1','1','1','1','1','1','1'}); 这样PreparedStatement形式的话会报错 PreparedStatementCallbac......

Holt_Vong ⋅ 2011/05/16 ⋅ 4

Redis之KEY操作命令 【学习笔记】

开启服务 $sudo ./src/redis-server & 键操作 *定义并赋值变量苹果的数量$ redis-cli set dangcheng::apple::count 152OK *获取刚才的苹果数量$ redis-cli get dangcheng::apple::count"152......

党程V ⋅ 2014/12/05 ⋅ 0

java.sql.SQLException: Incorrect string value: '\xAC\xED\x00\x05sr...' for colum

@JFinal 你好,想跟你请教个问题: Record 插入数据库表中,如果其中的一个字段是varchar,Java的对象时StringBuilder, 插入时会抛出java.sql.SQLException: Incorrect string value: 'xACxE...

freedomcat ⋅ 2016/07/18 ⋅ 2

BSON 规范简译

英文原址:http://bsonspec.org/#/specification 1.0 版 BSON是一种由零个或多个键值对存储为单个实体的二进制格式,我们称这种实体为文档。 下面是BSON标准的1.0版本的语法规范,我们使用伪...

棋有此理 ⋅ 2011/03/13 ⋅ 4

基于golang rocksdb实现的高性能队列

前言: 高性能队列? golang channel 可以理解为一个高性能的队列。但他毕竟是基于内存的,如果因各种情况堆积任务,可能会被oom,怎么办? 除去业务上的优化,看看是否有别的选择? 什么redis ?...

rfyiamcool ⋅ 2017/12/08 ⋅ 0

redis 取gzip压缩过的数据UnicodeDecodeError的问题

数据经压缩后再存入reids中,取出的时候由于连接redis时decode_responses默为true则会抛出 解决方法: 连接redis时带上decode_responses=False 取消对返回结果的decode('utf-8')操作 修改red...

pallormoon ⋅ 2016/03/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JPA入门,配置文件的设置

<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http......

码农屌丝 ⋅ 14分钟前 ⋅ 0

Java基础——面向对象和构造器

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。 静态成员介绍 为什么要有静态成员?静态成员用来...

凯哥学堂 ⋅ 15分钟前 ⋅ 0

vmware中Centos 7 linux的LVM磁盘扩容

系统是RHEL7(centos7差不多一样) 关闭系统,在vmware、设置、硬盘、扩展、输入数字大于当前系统内存、点击扩展。 开机再查看磁盘信息 fdisk -l 注意:可以看出sda磁盘增加了,但是根目录还...

gugudu ⋅ 26分钟前 ⋅ 0

JAVA线程sleep和wait方法区别

昨天面试,突然被问到sleep 和 wait的区别,一下子有点蒙,在这里记一下,以示警戒。 首先说sleep,sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过去后,cpu...

徐玉强 ⋅ 28分钟前 ⋅ 0

vuex学习--模块

随着项目复杂性增加,共享状态也越来越多。需要对转态操作进行分组,分组后在进行分组编写。学习一下module:状态管理器的模块组操作。 首先是声明: const moduleA={ state,mutations,g...

大美琴 ⋅ 30分钟前 ⋅ 0

Selenium 简单入门

安装 pip install selenium 驱动下载 https://chromedriver.storage.googleapis.com/index.html 下载最新的驱动,放入path中,可以放入Python的scripts目录下,也可以放入Chrome安装目录,并...

阿豪boy ⋅ 32分钟前 ⋅ 0

292. Nim Game - LeetCode

Question 292. Nim Game Solution 思路:试着列举一下,就能发现一个n只要不是4的倍数,就能赢。 n 是否能赢1 true2 true3 true4 false 不论删除几,对方都能一把赢5 t...

yysue ⋅ 今天 ⋅ 0

6.5 zip压缩工具 6.6 tar打包 6.7 打包并压缩

zip压缩工具 zip命令可以压缩目录和文件,-r 压缩目录。 zip使用方法 zip 1.txt.zip 1.txt //压缩文件 zip -r 123.zip 123/ //压缩目录 unzip 1.txt.zip //解压 unzip 123.zip -d /root/456...

Linux_老吴 ⋅ 今天 ⋅ 0

react-loadable使用跳坑

官方给react-loadable的定义是: A higher order component for loading components with dynamic imports. 动态路由示例 withLoadable.js import React from 'react'import Loadable fro......

pengqinmm ⋅ 今天 ⋅ 0

记录工作中遇到的坑

1、ios safari浏览器向下滚动会触发window resize事件

端木遗风 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部