欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot项目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑

程序员文章站 2022-04-14 19:59:12
前端时间新项目使用SpringBoot的RedisTemplate遇到一个问题,先简单描述一下问题:不同项目之间redis共用一个,但是我们新项目读不到老项目存储的缓存。新项目搭建的时候没有跟老项目使用同一个core包里的redisutils工具类,老项目使用的是jedis对象来操作redis,新项 ......

  前端时间新项目使用springboot的redistemplate遇到一个问题,先简单描述一下问题:不同项目之间redis共用一个,但是我们新项目读不到老项目存储的缓存。新项目搭建的时候没有跟老项目使用同一个core包里的redisutils工具类,老项目使用的是jedis对象来操作redis,新项目使用了springboot封装的redistemplate,代码上存在差异所以出现问题也就很正常,先来看一下新项目里对redistemplate的使用:(截取一个方法为例)

  现象:

  SpringBoot项目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑

   可以看出来工具直接注入spring容器中的redistemplate,没有指定泛型,在使用的时候通过key的泛型使用的是serializable,value的泛型是value,从泛型能看出来key跟泛型有一定关系,下面就来验证一下为什么取不到值。我们先往redis里存储一个缓存以字符串为例:

  SpringBoot项目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑

   写一个junit测试 

  SpringBoot项目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑

   测试取缓存

  SpringBoot项目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑

   通过结果发现没有取到值,反过来通过测试方法存一下缓存,再看我们存的是一个什么值

  SpringBoot项目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑

   通过结果发现我们存进去的key是redistemplate-test,但是redis实际存进去的key却是\xac\xed\x00\x05t\x00\x12redistemplate-test,同理,我们取缓存的时候前面也会自动加上一串看不懂的东西,所以取值的时候肯定也取不出来。做项目的时候时间比较紧,用了其他同事的代码保证项目上线,上线后才回过头去看取不到值的原因,其实同事的代码也很简单,只是在使用redistemplate的时候指定了泛型为string,就可以取到值了,其实也可以使用stringredistemplate来操作,但是stringredistemplate主要用来存储字符串,它的泛型指定的是string。如果存入对象时,会报错 :can not cast into string,所以我们就继续修改这个工具,解决key值前面的字符串。

   原因:

  下面我们简单的看一下redistemplate源码

  SpringBoot项目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑

  opsforvalue方法会返回一个valueoperations<k, v>,k跟v就是泛型,我们就是通过valueops来get,set我们的值。这个方法会new一个defaultvalueoperations对象,传入的template就是当前redistemplate对象,向下看:

SpringBoot项目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑SpringBoot项目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑

   有很多个redisserializer,默认都是null,当调用opsforvalue方法时会传入当前redistemplate对象,以keyserializer为例,它默认为null,如果等于null就被赋值dafaultserializer,默认dafaultserializer也为空,最终keyserializer就被赋值为jdkserializationredisserializer,所以没有设置序列化方式的时候redistemplate使用的序列化方式为jdkserializationredisserializer,所以我们存入key前面会带上一串东西,而stringredistemplate使用的是 stringredisserializer,序列化的方式不一样,所以使用的时候key就不会出现一串字符串。

  解决方案:

  简单了解原因后,现在就来解决这个问题,解决问题的方法就是设置序列化方式

  SpringBoot项目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑

   这样解决了上面的问题。问题倒不难,只是自己以前没有遇到过,不知道这个方法是从网上直接复制的还是自己写的,只能说复制的时候不够严谨,没有考虑到项目的实际情况,这个问题其实只要拿出一块时间去看看代码,查查资料就能解决,所以遇到问题的时候一定要找到原因去解决问题,而不是把问题隐藏掉。