SpringBoot+Redis+定时任务模拟手机短信验证

fb43c9936ccdd08259d3b33217d3b8e6.jpeg来源:https://blog.csdn.net/weixin_37833693

👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 /  赠书福利

新项目:仿小红书(微服务架构)正在更新中... , 全栈前后端分离博客项目 2.0 版本完结啦, 演示链接http://116.62.199.48/ 。全程手摸手,后端 + 前端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,直到项目上线。目前已更新了255小节,累计40w+字,讲解图:1716张,还在持续爆肝中.. 后续还会上新更多项目,目标是将Java领域典型的项目都整一波,如秒杀系统, 在线商城, IM即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,已有1300+小伙伴加入(早鸟价超低)

39041b27a96a6dc0f963093a333e1b81.gif

说明

只是模拟给手机发送短信验证码,并且进行校验

真正能够给手机发送验证码短信还需要结合第三方,如阿里云、讯飞等

需求

  • 发送手机号,返回验证码(6位随机数字)

    • 每个手机号一天只能发送10次(为了测试方便,可以改成3次),每天0点重置次数

    • 当天获取次数达到上限,提示“当天验证码获取次数已达上限,请明天再次使用”

    • 每个验证码有效期为5分钟,获取验证码提示“【XX系统】您的手机验证码为:XXXXXX,有效期5分钟,此功能每天最多获取XX条,请勿向任何人出示,以免账号被盗”

    • 5分钟内再次获取验证码提示“已有可用验证码,XX分XX秒内依然有效”

  • 发送手机号和验证码,对手机号和验证码进行校验,返回验证结果

    • 提示:“验证通过”或“验证失败,请确认手机号或验证码”

代码实现

1.依赖
<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
@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常量设定

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判断获取次数

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

3.3判断验证码剩余时间

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

3.4获取验证码

String.valueOf(new Random().nextInt(900000) + 100000);

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

String code = getCode();
RedisStringUtil.setEx(codeKey,code,MAX_TIME_OUT, TimeUnit.MINUTES);
RedisStringUtil.incrBy(countKey,1);

3.6校验手机号与验证码

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

service层完整代码

@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点清除所有短信获取次数
@Configuration
public class TaskConfig {
    @Scheduled(cron = "10 18 * * * ?")
    public void clearPhoneCount(){
        System.out.println("-----------------");
        RedisKeyUtil.delete(RedisKeyUtil.keys("*:COUNT"));
    }
}
5.启动类上添加开启定时任务
@EnableScheduling
public class RedisdemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisdemoApplication.class, args);
    }
}

👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 /  赠书福利

新项目:仿小红书(微服务架构)正在更新中... , 全栈前后端分离博客项目 2.0 版本完结啦, 演示链接http://116.62.199.48/ 。全程手摸手,后端 + 前端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,直到项目上线。目前已更新了255小节,累计40w+字,讲解图:1716张,还在持续爆肝中.. 后续还会上新更多项目,目标是将Java领域典型的项目都整一波,如秒杀系统, 在线商城, IM即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,已有1300+小伙伴加入(早鸟价超低)

64995bd1a5c7f868181ca8acf30ad0d4.gif

5980d65ff08ad6ff21979b8f1bf4be1a.jpeg

 
 

8507657054366e6bebad99b29b8b0871.gif

 
 
 
 
1. 我的私密学习小圈子~
2. 如何优雅的实现接口统一调用
3. 分层设计:Service 层真的需要实现接口吗?
4. 分布式链路追踪:TraceIdFilter + MDC + Skywalking
 
 
最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。
PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。
点“在看”支持小哈呀,谢谢啦
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值