谈谈spring-data-redis遇到的问题
来源:互联网 发布:淘宝详情图怎么加链接 编辑:程序博客网 时间:2024/06/08 00:06
谈谈spring-data-redis遇到的问题
1. key序列化问题
使用spring-data-redis中的redisTemplate存储key-value,然后使用redis-cli去查询时查询不到相应的key。使用keys *时发现redis中key的前缀多了一些字符
\xac\xed\x00\x05t\x00\x0e
问题关键
使用spring-data-redis,默认情况下使用的是org.springframework.data.redis.serializer.JdkSerializationRedisSerializer来进行序列化key
我们看看关键代码 RedisTemplate
public void afterPropertiesSet() { super.afterPropertiesSet(); boolean defaultUsed = false; if (defaultSerializer == null) { defaultSerializer = new JdkSerializationRedisSerializer( classLoader != null ? classLoader : this.getClass().getClassLoader()); } if (enableDefaultSerializer) { if (keySerializer == null) { keySerializer = defaultSerializer; defaultUsed = true; } if (valueSerializer == null) { valueSerializer = defaultSerializer; defaultUsed = true; } if (hashKeySerializer == null) { hashKeySerializer = defaultSerializer; defaultUsed = true; } if (hashValueSerializer == null) { hashValueSerializer = defaultSerializer; defaultUsed = true; } } if (enableDefaultSerializer && defaultUsed) { Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized"); } if (scriptExecutor == null) { this.scriptExecutor = new DefaultScriptExecutor<K>(this); } initialized = true; }
解决问题
手动设置key的序列化方式为StringRedisSerializer
看代码
@Beanpublic RedisTemplate<String, ?> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(factory); RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate;}
2. value 序列化问题
我们在使用无参构造GenericJackson2JsonRedisSerializer序列化对象时,序列化出来的值是这样的
{ "@class": "com.xxx.MenuTask", "taskId": "1617776640", "planId": "10000000", "createTime": [ "java.util.Date", 1500540438240 ], "execDate": [ "java.util.Date", 1500480000000 ], "status": 0, "totals": { "@class": "java.util.HashMap", "35430d2a56ae508f24a76a68e71b9f53": 1500, "75aa86c5a85f65687c95444655c51de9": 500, "ab90efa7a0079b88f224a296b211c209": 1000 }}
这样的json格式使用其他的json序列化时会出现无法解析的错误,如fastjson解析时会抛出异常
com.alibaba.fastjson.JSONException: parse error at com.alibaba.fastjson.serializer.DateCodec.cast(DateCodec.java:206) at com.alibaba.fastjson.parser.deserializer.AbstractDateDeserializer.deserialze(AbstractDateDeserializer.java:142) at com.alibaba.fastjson.parser.deserializer.AbstractDateDeserializer.deserialze(AbstractDateDeserializer.java:19) at com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer.parseField(DefaultFieldDeserializer.java:71) at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseField(JavaBeanDeserializer.java:790) at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:595)
主要原因是因为Date格式不正确,应该是一个long类型的数字,而不是一个数组
问题关键
我们来分析一下源码
public class GenericJackson2JsonRedisSerializer implements RedisSerializer<Object> { private final ObjectMapper mapper; /** * Creates {@link GenericJackson2JsonRedisSerializer} and configures {@link ObjectMapper} for default typing. */ public GenericJackson2JsonRedisSerializer() { this((String) null); } public GenericJackson2JsonRedisSerializer(String classPropertyTypeName) { this(new ObjectMapper());//------------------------ start ------------------------ mapper.registerModule(new SimpleModule().addSerializer(new NullValueSerializer(classPropertyTypeName))); if (StringUtils.hasText(classPropertyTypeName)) { mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, classPropertyTypeName); } else { mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY); }//------------------------ end ------------------------ } public GenericJackson2JsonRedisSerializer(ObjectMapper mapper) { Assert.notNull(mapper, "ObjectMapper must not be null!"); this.mapper = mapper; } ... ...}
原因所在地方 // — start — // — end —之间的那段代码 源码的63-69行,这里会将属性的类型写到json中。
解决问题
手动设置一个ObjectMapper,这样redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer(new ObjectMapper()));
@Beanpublic RedisTemplate<String, ?> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(factory); RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer(new ObjectMapper())); return redisTemplate;}
阅读全文
0 0
- 谈谈spring-data-redis遇到的问题
- spring-data-redis 的序列化问题
- 使用Spring Data Redis时,遇到的几个问题
- Spring Session Data Redis 配置中遇到的坑
- 使用Spring Data Redis时,遇到的几个问题
- Redis与spring的整合遇到问题
- Redis 使用spring-data-redis的序列化问题
- spring data jpa遇到的一些琐碎问题
- spring-data-redis接口调用出现乱码的问题
- redis遇到的问题
- Spring-data-redis操作Redis的Sentinel
- 12.10 搭建spring hibern redis时遇到的问题
- spring data redis 遇到的“坑”——set集合的 Srandmember
- redis:spring-data-redis
- Spring中spring-data-redis的使用
- java-谈谈工作中遇到的问题
- spring-data-redis : Spring 提供的 redis客户端工具包
- redis 安装遇到的问题
- 实训--day11
- Dubbo 介绍 2- 源码分析,通过 schema 启动服务
- HDU2647 Reward(拓扑排序)
- 定向输出
- 多线程通信【生产消费案例】
- 谈谈spring-data-redis遇到的问题
- Java_基础—文件名称过滤器的概述及使用
- Oracle GI 12.2新特性: OCR和Voting Disk必须存放在ASM中
- Activity基础
- Opencv3 python学习2——视频基础
- 模板方法模式(Template Method Pattern)。
- Android多媒体(音乐播放器)
- 数据结构和算法学习笔记
- 委托的理解