热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:Java实现短信验证码设置发送间隔时间,以及有效时间(Java+Redis)

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java实现短信验证码--设置发送间隔时间,以及有效时间(Java+Redis)相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java实现短信验证码--设置发送间隔时间,以及有效时间(Java+Redis)相关的知识,希望对你有一定的参考价值。




Java实现短信验证码--设置发送间隔时间,以及有效时间(Java+Redis)


这篇文章,实现了Java发送手机短信验证码发送的间隔时间,以及手机验证码的有效时间和手机验证码格式的合法性验证,可以防止恶意刷接口


关于Java项目怎么连接redis,请看这一篇文章 https://www.cnblogs.com/nanstar/p/13367747.html



代码部分

package com.zxjs.controller.app;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 发送短信验证码
*/
@Api(value="发送短信验证码",description = "发送短信验证码,默认发送短信的间隔是一分钟",tags = {"发送短信验证码"})
@RestController
@RequestMapping("appISendSms")
public class SendSMS {
private final static Logger logger = LoggerFactory.getLogger(SendSMS.class);
/**
* 链接redis数据库,使用验证码的时候,只需要在其他的地方用redis查询这个手机号的验证码就可以了
*/
static Jedis jedis = new Jedis("localhost");
/**
* 生成随机的六位验证码
*/
static String sale = "";
/**
* @param args
*/
public static void main(String[] args) throws InterruptedException{
//手机号测试部分
sendSmsInfo("13683654784");
}
/**
* 发送验证消息
* 传入手机号,接收到的是用户的手机号码
* @return
*/
@ApiOperation(value="发送验证消息",notes = "发送验证消息,默认同一个手机号码发送短信间隔是一分钟,加入手机号码格式验证,可使用时长是五分钟,可以有效防止恶意刷接口")
@ApiImplicitParam(paramType = "query",name="phone",value = "0",required = true)
@GetMapping("getReCode")
@ResponseBody
public static String sendSmsInfo(String phone){
//进入发送逻辑的时候生成随机验证码,六位数字
sale = RandomStringUtils.randomNumeric(6);
//思路,每个手机号进来的时候,放到redis里面一个值,(手机号,验证码+开始时间)
// 当这个用户再次来查询的时候,查看时间是否到达一分钟,到达的话可以发送验证码
try {
//验证码有效时间,放到redis缓存里面(手机号,验证码+开始时间),根据开始时间来判断,达到了时间删掉缓存里面的手机号
String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9])|(16[6]))\\\\d{8}$";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(phone);
boolean isMatch = m.matches();
if (! isMatch) {
return "手机号码格式不正确,请核对后重新输入!";
} else {
/*检测redis是否开启,未开启的话,返回信息*/
if(jedis.ping() == "PONG"){
return "Redis Is Not Run!";
}
//当前时间秒数
Long timemili = System.currentTimeMillis() / 1000;
// System.out.println("当前的秒数" + timemili);
// System.out.println(jedis.dbSize());
// System.out.println(jedis.keys("*"));
/*在这里写一个定时的for循环,用来取redis的手机号码信息,然后查询手机号码开始的时间,若是大于等于五分钟
* 就给删除这个键值*/
//创建多线程定时任务,延迟1s启动,每隔1s执行一次,是前一个任务开始时就开始计算时间间隔,但是会等上一个任务结束在开始下一个
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
/*执行程序的位置*/
//首先取出所有的手机号 键信息,放到新的集合里
Set setPhOne= new HashSet();
setPhOne= jedis.keys("*");
for (Object setInfo : setPhone) {
//判断这个键的值是不是超过五分钟,是的话就删除掉这个键
System.out.println("计算结果"+ (System.currentTimeMillis() / 1000 - Long.parseLong(jedis.get(setInfo.toString()).substring(6))) );
if(System.currentTimeMillis() / 1000 - Long.parseLong(jedis.get(setInfo.toString()).substring(6)) > 300){
jedis.del(setInfo.toString());
}
// System.out.println(setInfo);
}
}
}, 1, 2, TimeUnit.SECONDS);
/**
* 设置键值的时候先查询是否存在这个键值对,存在的话查看时长,不存在的话直接发送短信
*/
boolean str = jedis.exists(phone);
if (! str) {
//发送短息
String recode = SmsInfo(phone);
jedis.set(phone, (sale + timemili));
return recode;
} else {
String strT = jedis.get(phone);
//查看请求间隔,默认是一分钟,小于一分钟继续等待,超过一分钟发送短信
if (timemili - Long.parseLong(strT.substring(6)) <60) {
// System.out.println("请一分钟后再次重试" + new Date());
return "请等待一分钟后再次重试!";
} else {
//发送短息
String recode = SmsInfo(phone);
jedis.set(phone, (sale + timemili));
return recode;
}
}
}
}catch(Exception e){
logger.error(e.getMessage());
}
return "false";
}
/**
* 发送短息
* @return
*/
public static String SmsInfo(String phone){
这里设置短信验证码的接口和账户密码部分(自己购买的接口在这里)
String url ="http://www.ztsms.cn/sendNSms.do";
String username ="";//内容
String password ="";//密码
String mobile = phone; //号码
String cOntent="您本次操作的的验证码是:"+sale+",验证码五分钟内有效,请不要把验证码发送给别人!";//内容
String productid =""; //产品id
String xh ="";//设置为空
String tkey = TimeUtil.getNowTime("yyyyMMddHHmmss");
try{
cOntent= URLEncoder.encode(content,"utf-8");
}catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String param="gateway="+url+"&username="+username+"&password="+ MD5Gen.getMD5(MD5Gen.getMD5(password)+tkey)+"&tkey="+tkey+"&mobile="+mobile+"&cOntent="+content+"&productid="+productid+"&xh"+xh;
// String ret= HttpRequest.sendGet(url, param);//sendPost or sendGet 即get和post方式
System.out.println("ret:"+ret+param);
return sale;
}
}

用到的工具类的部分


phoneUtils https://files.cnblogs.com/files/nanstar/phoneUtils.zip




推荐阅读
  • 本文将深入探讨如何在不依赖第三方库的情况下,使用 React 处理表单输入和验证。我们将介绍一种高效且灵活的方法,涵盖表单提交、输入验证及错误处理等关键功能。 ... [详细]
  • 本文详细介绍了如何准备和安装 Eclipse 开发环境及其相关插件,包括 JDK、Tomcat、Struts 等组件的安装步骤及配置方法。 ... [详细]
  • 自己用过的一些比较有用的css3新属性【HTML】
    web前端|html教程自己用过的一些比较用的css3新属性web前端-html教程css3刚推出不久,虽然大多数的css3属性在很多流行的浏览器中不支持,但我个人觉得还是要尽量开 ... [详细]
  • Python 异步编程:ASGI 服务器与框架详解
    自 Python 3.5 引入 async/await 语法以来,异步编程迅速崛起,吸引了大量开发者的关注。本文将深入探讨 ASGI(异步服务器网关接口)及其在现代 Python Web 开发中的应用,介绍主流的 ASGI 服务器和框架。 ... [详细]
  • 通过Web界面管理Linux日志的解决方案
    本指南介绍了一种利用rsyslog、MariaDB和LogAnalyzer搭建集中式日志管理平台的方法,使用户可以通过Web界面查看和分析Linux系统的日志记录。此方案不仅适用于服务器环境,还提供了详细的步骤来确保系统的稳定性和安全性。 ... [详细]
  • 不确定性|放入_华为机试题 HJ9提取不重复的整数
    不确定性|放入_华为机试题 HJ9提取不重复的整数 ... [详细]
  • 本文详细介绍了在企业级项目中如何优化 Webpack 配置,特别是在 React 移动端项目中的最佳实践。涵盖资源压缩、代码分割、构建范围缩小、缓存机制以及性能优化等多个方面。 ... [详细]
  • Java 中的月减()方法 ... [详细]
  • 本文介绍了一个用于 Android 开发的 Logcat 日志管理工具类,该类提供了默认和自定义标签的日志记录方法。通过这种方式,开发者可以更方便地管理和调试应用程序中的日志输出。 ... [详细]
  • 开发笔记:2020 BJDCTF Re encode
    开发笔记:2020 BJDCTF Re encode ... [详细]
  • TechStride 网站
    TechStride 成立于2014年初,致力于互联网前沿技术、产品创意及创业内容的聚合、搜索、学习与展示。我们旨在为互联网从业者提供更高效的新技术搜索、学习、分享和产品推广平台。 ... [详细]
  • 本文介绍了如何使用Java中的同步方法和同步代码块来实现两个线程的交替打印。一个线程负责打印1到52的数字,另一个线程负责打印A到Z的字母,确保输出顺序为12A34B...5152Z。 ... [详细]
  • C# LiNQ 查询 join连接
    C# LiNQ 查询 join连接 ... [详细]
  • 本文探讨了如何在日常工作中通过优化效率和深入研究核心技术,将技术和知识转化为实际收益。文章结合个人经验,分享了提高工作效率、掌握高价值技能以及选择合适工作环境的方法,帮助读者更好地实现技术变现。 ... [详细]
  • jQuery HooRay:一款自创的实用 jQuery 工具插件
    这款插件主要由作者在工作中积累的常用功能开发而成,旨在解决现有插件间的冲突及浏览器兼容性问题。通过整合和优化现有插件,确保其稳定性和高效性。 ... [详细]
author-avatar
Timeless
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有