【代码Demo】SpringBoot+Redis+定时任务模拟手机短信验证

目录

说明

  1. 只是模拟给手机发送短信验证码,并且进行校验
  2. 真正能够给手机发送验证码短信还需要结合第三方,如阿里云、讯飞等

需求

  • 发送手机号,返回验证码(6位随机数字)
    • 每个手机号一天只能发送10次(为了测试方便,可以改成3次),每天0点重置次数
    • 当天获取次数达到上限,提示"当天验证码获取次数已达上限,请明天再次使用"
    • 每个验证码有效期为5分钟,获取验证码提示"【XX系统】您的手机验证码为:XXXXXX,有效期5分钟,此功能每天最多获取XX条,请勿向任何人出示,以免账号被盗"
    • 5分钟内再次获取验证码提示"已有可用验证码,XX分XX秒内依然有效"
  • 发送手机号和验证码,对手机号和验证码进行校验,返回验证结果
    • 提示:"验证通过"或"验证失败,请确认手机号或验证码"

代码实现

1.依赖

xml 复制代码
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2.Controller

java 复制代码
@RestController
public class PhoneController {
    @Resource
    private PhoneService phoneService;

    @RequestMapping("/send")
    public String send(String phone) {
        return phoneService.send(phone);
    }

    @RequestMapping("/check")
    public String check(String phone,String code) {
        return phoneService.check(phone,code);
    }
}

3.service

3.1常量设定

java 复制代码
    private static final int MAX_TIME_OUT = 5;
    private static final String MAX_PHONE_COUNT= "3";
    private static final String PHONE_COUNT_SUFFIX=":COUNT";
    private static final String PHONE_CODE_SUFFIX=":CODE";

3.2判断获取次数

java 复制代码
        if(RedisStringUtil.get(codeKey)==null &&
                "3".equals(RedisStringUtil.get(countKey))){
            return "当天验证码获取次数已达上限,请明天再次使用";
        }

3.3判断验证码剩余时间

java 复制代码
        long exTime = RedisKeyUtil.getExpire(codeKey);
        if(exTime>0){
            return "已有可用验证码," + (exTime / 60) + "分 " + (exTime % 60) +
                    " 秒内依然有效";
        }

3.4获取验证码

java 复制代码
		String.valueOf(new Random().nextInt(900000) + 100000);

3.5保存验证码,设置有效期,累加获取次数

java 复制代码
        String code = getCode();
        RedisStringUtil.setEx(codeKey,code,MAX_TIME_OUT, TimeUnit.MINUTES);
        RedisStringUtil.incrBy(countKey,1);

3.6校验手机号与验证码

java 复制代码
        String codeKey = phone + PHONE_CODE_SUFFIX;
        if(code!=null && code.equals(RedisStringUtil.get(codeKey))){
            return "验证成功";
        }
        return "验证失败,请确认手机号或验证码";

service层完整代码

java 复制代码
@Service
public class PhoneService {
    private static final int MAX_TIME_OUT = 5;
    private static final String MAX_PHONE_COUNT= "3";
    private static final String PHONE_COUNT_SUFFIX=":COUNT";
    private static final String PHONE_CODE_SUFFIX=":CODE";
    public String send(String phone) {
        String countKey = phone + PHONE_COUNT_SUFFIX; //次数
        String codeKey = phone + PHONE_CODE_SUFFIX; //验证码
        if(RedisStringUtil.get(codeKey)==null &&
                "3".equals(RedisStringUtil.get(countKey))){
            return "当天验证码获取次数已达上限,请明天再次使用";
        }
        long exTime = RedisKeyUtil.getExpire(codeKey);
        if(exTime>0){
            return "已有可用验证码," + (exTime / 60) + "分 " + (exTime % 60) +
                    " 秒内依然有效";
        }
        String code = getCode();
        RedisStringUtil.setEx(codeKey,code,MAX_TIME_OUT, TimeUnit.MINUTES);
        RedisStringUtil.incrBy(countKey,1);
        return "【地笼系统】您的手机验证码为:" + code
                + ",有效期5分钟,此功能每天最多获取" + MAX_PHONE_COUNT +
                "条,请勿向任何人出示,以免账号被盗";
    }

    public String check(String phone, String code) {
        String codeKey = phone + PHONE_CODE_SUFFIX;
        if(code!=null && code.equals(RedisStringUtil.get(codeKey))){
            return "验证成功";
        }
        return "验证失败,请确认手机号或验证码";
    }

    private String getCode(){
        return String.valueOf(new Random().nextInt(900000) + 100000);
    }
}

4.设置定时任务,每天0点清除所有短信获取次数

java 复制代码
@Configuration
public class TaskConfig {
    @Scheduled(cron = "10 18 * * * ?")
    public void clearPhoneCount(){
        System.out.println("-----------------");
        RedisKeyUtil.delete(RedisKeyUtil.keys("*:COUNT"));
    }
}

5.启动类上添加开启定时任务

java 复制代码
@EnableScheduling
public class RedisdemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisdemoApplication.class, args);
    }
}
相关推荐
脚本自动化开发2 小时前
柔光屏平板怎么选?华为 MatePad Air Z 柔光版学
后端
程序猿DD3 小时前
OctaFuse 2.19.0:重做管理后台界面与交互,模型目录同步更新
后端
金銀銅鐵4 小时前
带您看懂字节码指令(一):一帧里有什么
java·后端·ai编程
码事漫谈5 小时前
Agent 测评是什么?大白话讲一讲
后端
皮皮林5515 小时前
在 IDEA 里斗个地主不过分吧!
后端
nice_lcj5205 小时前
【从零理解 Spring AI · 14】RAG 的四个环节:加载、切分、向量化、检索
java·spring boot·embedding·向量数据库·rag·spring ai·ai应用开发
SomeOtherTime6 小时前
Rust所有权(AI回答)
开发语言·后端·rust
Easyhood6 小时前
Android 开发入门实践(十四):Compose 副作用入门与四个常用 API
android·开发语言·kotlin·android jetpack·compose
白杨尚青7 小时前
C++进阶篇(六):map 和 set 的模拟实现——用红黑树封装 mymap/myset(迭代器 + operator[])
开发语言·c++·迭代器·stl·set·map·红黑树
程序员cxuan7 小时前
离谱,AI 大佬顺手搓了个 YouTube ,而我顺手给他搓了个中文插件
人工智能·后端·程序员