Bug:redisTemplate设置值之后,redis-cli和redisTemplate的get方法中获取不到

Bug:redis-cli和redisTemplate的get方法中获取不到redis的值

1 问题复现

今天在做挂号项目的时候,发现使用redisTemplate设置值之后不报错,但是redis-cli获取不到值【对接短信验证码】

//错误示例
@ApiOperation(value = "发送手机验证码")
    @GetMapping("/send/{phone}")
    public Result sendCode(@PathVariable String phone){
        //从redis中获取验证码,如果获取到,返回ok
        //key手机号     value验证码
        String code = redisTemplate.opsForValue().get("phone");
        System.out.println("code=============" + code);
        if(!StringUtils.isEmpty(code)){
            return Result.ok();
        }
        //如果验证码获取不到,就生成验证码
        code = RandomUtil.getFourBitRandom();//生成四位验证码
        //调用service方法,通过整合短信服务进行发送
        boolean isSend = msmService.send(phone, code);
        //生成的验证码存放到redis中,并设置有效时间
        if(isSend) {
            redisTemplate.opsForValue().set(phone, code, 2, TimeUnit.MICROSECONDS);
            return Result.ok();
        } else {
            return Result.fail().message("发送短信失败");
        }
    }

①后面经过排查发现是get的值写成了"phone",应该改为phone

String code = redisTemplate.opsForValue().get(phone);

②结果发现,修改完之后还是获取不到值,经过再一次排查,发现是自己设置值的过期时间设置成了微秒

redisTemplate.opsForValue().set(phone, code, 2, TimeUnit.MINUTES);

修改完之后,发现IDEA中获取不到值,但是redis-cli中有值,人了…

后来发现了RedisTemplate与StringRedisTemplate的区别,修改完成之后,终于可用了
解决办法:

  • 使用StringRedisTemplate【因为我的value是String类型的】
  • RedisTemplate加上泛型

产生原因【redisTemplate 与StringRedisTemplate 区别】:

区别主要在于他们使用的序列化类。

RedisTemplate使用的是 JdkSerializationRedisSerializer
StringRedisTemplate使用的是 StringRedisSerializer
StringRedisTemplate 继承了RedisTemplate,在构造器中,直接设置了序列化方式
Bug:redisTemplate设置值之后,redis-cli和redisTemplate的get方法中获取不到_第1张图片
RedisTemplate默认存储数据会将其转换为字节数组形式,当我们通过redisTemplate获取值时,如果字节数组转换正常就可以成功获取正确的值,如果转换失败,就获得了null

总结:当Redis当中的数据值是以可读的形式显示出来的时候,
只能使用StringRedisTemplate才能获取到里面的数据。
所以当你使用RedisTemplate获取不到数据的时候请检查一下是不是Redis里面的数据是可读形式而非字节数组

2 分析原因

①get的值写错了

String code = redisTemplate.opsForValue().get(phone);//get("phone")

②过期时间设置错了

redisTemplate.opsForValue().set(phone, code, 2, TimeUnit.MINUTES);//"MICROSECONDS"

③StringRedisTemplate与RedisTemplate区别

如果我们要再redis中存储可读形式的数据:

  1. 使用StringRedisTemplate
  2. RedisTemplate

④redis配置问题

查看是否是自己redis的连接地址或密码啥的配置错误

3 解决bug

①修改get的值
②修改过期时间
③添加泛型

4 拓展:连接不上虚拟机的redis

  1. 防火墙没关(端口未开放)
  2. protected mode保护模式没关
  3. bind 127.0.0.1没有注释
  4. redis启动时没有正确指定redis.conf
  5. 密码错误(如果有设置的话)

参考文章:https://blog.csdn.net/xjszsd/article/details/121746176

你可能感兴趣的:(bug,redis,bug,缓存,RedisTemplate)