redis使用Jackson2JsonRedisSerializer序列化问题
一、spring boot 集成Redis方法
- 依赖
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
- Redis自定义序列化
@Configuration
public class RedisConfig { @Bean(name = "strRedisTemplate")
public RedisTemplate<String, String> strRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory); // 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化)
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om); redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
return redisTemplate;
} @Bean(name = "intRedisTemplate")
public RedisTemplate<String, Integer> intRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Integer> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory); // 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化)
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om); redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
return redisTemplate;
} }
- 使用代码
@Service
public class RedisServiceImpl implements IRedisService { @Resource(name = "intRedisTemplate")
private RedisTemplate<String, Integer> intTemplate;
@Resource(name = "strRedisTemplate")
private RedisTemplate<String, String> strTemplate; @Override
public void incrHash(String key, String field, Integer value) {
intTemplate.opsForHash().increment(key, field, value);
} @Override
public void incrKey(String key, Integer value) {
if(null == key || null == value){
return;
}
intTemplate.opsForValue().increment(key,value);
} @Override
public Integer getInteger(String key) {
if(null == key){
return null;
}
return intTemplate.opsForValue().get(key);
}
}
五、出现问题
使用的时候,发现一个问题,如果我用IntegerTemplate存储值到Redis,会进行序列化,自动为String类型的键和值添加双引号,这是Jackson2JsonRedisSerializer特性,但是使用StringTemplate,存储的String类型的键和值都不带双引号
六、几种序列化对比
这是别人总结的Redis常见的几种序列化方式特性,详细见:参考文章
以下内容引用别人博客
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
我们这里针对StringRedisSerializer,Jackson2JsonRedisSerializer和JdkSerializationRedisSerializer进行测试。
下面是,把3种Serializer保存到Redis中的结果:
1,所有的KeySerializer和HashKeySerializer都使用StringRedisSerializer,用其它Serializer的没有什么意义,就像最上面的例子一样。
2,上面序列化后的值,是保存到redis中的值,从Redis中读取回Java中后,值的内容都是一样的。

从上面的结果不难看出,
1,用StringRedisSerializer进行序列化的值,在Java和Redis中保存的内容是一样的
2,用Jackson2JsonRedisSerializer进行序列化的值,在Redis中保存的内容,比Java中多了一对双引号。
3,用JdkSerializationRedisSerializer进行序列化的值,对于Key-Value的Value来说,是在Redis中是不可读的。对于Hash的Value来说,比Java的内容多了一些字符。
(如果Key的Serializer也用和Value相同的Serializer的话,在Redis中保存的内容和上面Value的差异是一样的,所以我们保存时,只用StringRedisSerializer进行序列化)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
七、问题原因
出现“存储Integer类型数据,自动序列化(加双引号),存储String类型,序列化失败(没有双引号)”的原因是:
我在设置自定义序列化的时候,为Bean起了个名称叫:"StringRedisTemplate",这个名称和StringRedisTemplate重名了,spring注入的时候,注入的是StringRedisTemplate,不是我更改过序列化方式后的Template对象。
@Bean(name = "stringRedisTemplate")
public RedisTemplate<String, String> strRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory); // 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化)
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om); redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
return redisTemplate;
}
真是个傻逼错误
redis使用Jackson2JsonRedisSerializer序列化问题的更多相关文章
- 深入理解Spring Redis的使用 (七)、Spring Redis 使用 jackson序列化 以及 BaseDao代码
之前在介绍Spring Redis进行存储的时候,都是通过RedisTemplate中的defaultSerializer,即JdkSerializationRedisSerializer.通过Jdk ...
- python redis存入字典序列化存储
在python中通过redis hset存储字典时,必须主动把字典通过json.dumps()序列化为字符串后再存储, 不然hget获取后将无法通过json.loads()反序列化为字典 序列化存储 ...
- Redis存储对象(序列化和反序列化)
代码以及实例: package com.hp.test; import redis.clients.jedis.Jedis; import java.io.*; public class Test3 ...
- Redis在存取序列化和反序列化性能问题
1. 问题场景 我们在使用Redis的时候经常会将对象序列化存储到Redis中,在取出的时候进行反序列化,如果对象过大在进行序列化和反序列化的时候会有一定性能问题.今天查看了CSRedis源码发现在S ...
- Redis键的序列化和反序列化
序列化 命令名称:DUMP 语法:DUMP key 功能:序列化给定key,并返回被序列化的值.序列化的值不包括任何生存时间信息. 返回值:如果key不存在,那么返回nil.否则返回序列化之后的值 反 ...
- Redis存储对象序列化和反序列化
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInpu ...
- Redis 序列化方式StringRedisSerializer、FastJsonRedisSerializer和KryoRedisSerializer
当我们的数据存储到Redis的时候,我们的键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的.RedisTemplate默认使用的是JdkSerializat ...
- Spring Boot 结合 Redis 序列化配置的一些问题
前言 最近在学习Spring Boot结合Redis时看了一些网上的教程,发现这些教程要么比较老,要么不知道从哪抄得,运行起来有问题.这里分享一下我最新学到的写法 默认情况下,Spring 为我们提供 ...
- SpringBoot缓存管理(三) 自定义Redis缓存序列化机制
前言 在上一篇文章中,我们完成了SpringBoot整合Redis进行数据缓存管理的工作,但缓存管理的实体类数据使用的是JDK序列化方式(如下图所示),不便于使用可视化管理工具进行查看和管理. 接下来 ...
随机推荐
- python基础整理6——爬虫基础知识点
爬虫基础 什么是爬虫: 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁. ...
- js判断设备信息,安卓、ios、还是pc端
前端开发获取设备信息的代码if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) { window.location.href =" ...
- postmark使用
一.Postmark原理 Postmark是由着名的NAS提供商NetApp开发,用来测试其产品的后端存储性能. Postmark主要用于测试文件系统在邮件系统或电子商务系统中性能,这类应用的特点是: ...
- pyhton 面向对象之 小明左右手换牌
'''#左右手交换牌 案列#小明手里有俩张牌,左手红桃♥K,右手黑桃♠A,小明交换俩手的牌后,手里分别是什么? 人类: 属性:小明,左手,右手 行为:展示手里的牌, 交换手里的牌手类: ...
- Linux服务-samba
目录 1. samba简介 2. samba访问 Linux服务-samba 1. samba简介 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成. 在 ...
- linux-2.6内核驱动学习——jz2440之输入子系统
如果按照上一篇记录的那样,只有本公司的人或者自己才能使用驱动.想写出一个通用的驱动程序,让其他应用程序来无缝移植,需要使用现成的驱动——输入子系统. /drivers/input/input.c #d ...
- go基础1:Hello world与变量声明
一.go语言版hello world package main # 指明文件属于main包 main包使用后来定义一个独立的可执行程序,而不是库main包中的main函数是特殊的,不管在什么程序中,m ...
- Go压缩文件
Go压缩文件 首先是恭喜IG获得S8全球总决赛冠军,IG牛逼.但咱是一介草民,狂欢后,还是得老老实实的开始敲代码.最近做了一个给底层固件压缩加密的工具,是使用C#做的,已经提交出去可以正常使用的.既然 ...
- python中的控制流
ifpython条件语句是通过一条或多条语句的执行结果(True或false)来决定执行的代码块 if语句用于控制程序的执行,基本形式为:if 判断条件:执行语句....elif判断语句:执行语句.. ...
- Android初学-AsyncTask下载网络图片
AsyncTask 异步处理: mainfest: 注意添加的: -------------------- <uses-permission android:name="android ...