• SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.3 手机验证码案例 - 生成验证码


    SpringBoot

    【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】

    SpringBoot 开发实用篇

    5 整合第三方技术

    5.3 手机验证码案例 - 生成验证码
    5.3.1 SpringBoot 的缓存方案

    SpringBoot提供的缓存技术除了提供默认的缓存方案,还可以对其他缓存技术进行整合,统一接口,方便缓存技术的开发与管理

    刚刚我们做的就是用SpringBoot 默认的缓存技术实现的

    在这里插入图片描述

    在李老师录制课程那会儿,SpringBoot 可以整合的缓存技术

    • Generic
    • JCache
    • Ehcache
    • Hazelcast
    • Infinispan
    • Couchbase
    • Redis
    • Caffeine
    • Simple(默认)
    • memcached【市面常用】
    5.3.2 缓存使用案例 —— 手机验证码

    需求:

    • 输入手机号获取验证码,组织文档以短信形式发送给用户(页面模拟)
    • 输入手机号和验证码验证结果

    需求分析:

    • 提供controller,传入手机号,业务层通过手机号计算出独有的6位验证码数据,存入缓存后返回此数据
    • 提供controller,传入手机号与验证码,业务层通过手机号从缓存中读取验证码与输入验证码进行比对,返回比对结果

    【直接开干】

    创建一个新的实体类【验证码】

    package com.dingjiaxiong.domain;
    
    import lombok.Data;
    
    /**
     * ClassName: SMSCode
     * date: 2022/10/21 13:46
     *
     * @author DingJiaxiong
     */
    
    @Data
    public class SMSCode {
    
        private String tele;
        private String code;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    直接做业务层【因为我们不用去数据库拿数据】

    package com.dingjiaxiong.service;
    
    import com.dingjiaxiong.domain.SMSCode;
    
    /**
     * ClassName: SMSCodeService
     * date: 2022/10/21 13:47
     *
     * @author DingJiaxiong
     */
    
    
    public interface SMSCodeService {
    
        //模拟发送验证码到手机
        public String sendCodeToSMS(String tele);
    
        //校验验证码
        public boolean checkCode(SMSCode smsCode);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    先来一个生成6位加密验证码的“小工具类”

    package com.dingjiaxiong.utils;
    
    import org.springframework.stereotype.Component;
    
    /**
     * ClassName: CodeUtils
     * date: 2022/10/21 13:53
     *
     * @author DingJiaxiong
     */
    
    @Component
    public class CodeUtils {
    
        private String[] patch = {"000000","00000","0000","000","00","0",""};
    
        public String generator(String tele){
    
            int hash = tele.hashCode();
            int encryption = 20206666;
    
            long result = hash ^ encryption; //异或
            long nowTime = System.currentTimeMillis();
    
            result = result ^ nowTime; //与系统当前时间再次异或
    
            long code = result % 1000000; //取加密后的后六位
            code = code < 0 ? -code : code ; //负数特殊处理
            String codeStr = code + "";//可能还得补0
            int len = codeStr.length();
    
    
            return patch[len] + codeStr;
    
        }
    
    //    public static void main(String[] args) {
    //        System.out.println(new CodeUtils().generator("18866668888"));
    //    }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    业务层实现类

    package com.dingjiaxiong.service.impl;
    
    import com.dingjiaxiong.domain.SMSCode;
    import com.dingjiaxiong.service.SMSCodeService;
    import com.dingjiaxiong.utils.CodeUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.stereotype.Service;
    
    /**
     * ClassName: SMSCodeServiceImpl
     * date: 2022/10/21 13:50
     *
     * @author DingJiaxiong
     */
    
    @Service
    public class SMSCodeServiceImpl implements SMSCodeService {
    
        @Autowired
        private CodeUtils codeUtils;
    
        @Override
        @Cacheable(value = "smsCode" ,key = "#tele")
        public String sendCodeToSMS(String tele) {
            String code = codeUtils.generator(tele);
            return code;
        }
    
        @Override
        public boolean checkCode(SMSCode smsCode) {
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    校验还没写

    控制器

    package com.dingjiaxiong.controller;
    
    import com.dingjiaxiong.domain.SMSCode;
    import com.dingjiaxiong.service.SMSCodeService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * ClassName: SMSCodeController
     * date: 2022/10/21 13:51
     *
     * @author DingJiaxiong
     */
    
    @RestController
    @RequestMapping("/sms")
    public class SMSCodeController {
    
        @Autowired
        private SMSCodeService smsCodeService;
    
        @GetMapping
        public String getCode(String tele){
            String code = smsCodeService.sendCodeToSMS(tele);
            return code;
        }
    
        @PostMapping
        public boolean checkCode(SMSCode code){
            return smsCodeService.checkCode(code);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    直接启动服务器

    在这里插入图片描述

    直接测试一下生成验证码

    在这里插入图片描述

    这样就得到了一个验证码,再发一次

    在这里插入图片描述

    并没有变化好家伙,验证码过期机制没了

    什么原因

    这是因为业务层中

    在这里插入图片描述

    第一次访问,生成一个code 存入缓存后,下一次再访问时,检测到手机号没变,直接返回了第一次生成的验证码。这显然是不符合常理的【这样就可以看到@Cacheable 这个注解在现在这个场景下就不适用了】

    我们需要仅仅在把单次操作放到缓存,但是不要主动去读

    换一个

    @CachePut(value = "smsCode" ,key = "#tele")
    
    • 1

    这个就没有取的操作了

    在这里插入图片描述

    重启服务器,再试一次

    在这里插入图片描述

    这样就每次都不一样了

    【OK,这样第一步就完成了,生成验证码,并且“放入”缓存】

  • 相关阅读:
    【C语言】2.数组与指针
    信号系统|信号的分类|确定信号与随机信号 连续信号与离散信号 周期信号与非周期信号 能量信号与功率信号 奇异信号
    CentOS7多种方式安装MySQL-5.7.X数据库
    java-net-php-python-s2sh教学管理平台hsg8229AGA2录像计算机毕业设计程序
    CK草稿本
    TCP 四次挥手,可以变成三次挥手吗?
    SDL2.0播放pcm格式音频
    【无人机】基于Matlab的四旋翼无人机控制仿真
    基于骨架的动作识别:SkeleTR: Towrads Skeleton-based Action Recognition in the Wild
    锐捷EG易网关 phpinfo.view.php 信息泄露
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/127945576