java手机短信验证,并存入redis中,验证码时效5分钟
目录
1、注册发送短信账号一个账号
2、打开虚拟机,将redis服务端打开
3、创建springboot工程,导入相关依赖
4、写yml配置
5、创建controller层,并创建controller类
6、创建service层,并创建service类
7、创建工具类,将发送短信的代码放入工具类
8、返回值工具类
9、写前端代码验证
结合第三方API和redis实现以下功能:
1:手机短信验证,每条验证码有效期为5分钟,
2:五分钟内如果该手机号再次获取验证码,则提示短信已发送,请XX分钟后(剩余过期时间)重新
获取
3:每个手机号每天最多只能发送3次,24小时后可发送次数重置
1、注册发送短信账号一个账号
网址:https://www.ihuyi.com/
注册送10条免费短信

发送短信需要对接相关资源
2、打开虚拟机,将redis服务端打开

3、创建springboot工程,导入相关依赖
工程结构

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>io.projectreactor</groupId><artifactId>reactor-test</artifactId><scope>test</scope></dependency>
4、写yml配置
spring:redis:port: 6379 #端口号host: 192.168.138.129 #虚拟机IP地址password: 123456 #密码database: 0 #redis默认数据库timeout: 5000mvc:static-path-pattern: /** #加载静态资源thymeleaf:cache: false #关闭页面缓存mode: HTML #模板模式suffix: .html #构建URL时附加到查看名称的后缀
5、创建controller层,并创建controller类
@Controller
public class CodeController {@Autowiredprivate CodeService codeService;//访问8080直接进入index页面@GetMapping("/")public String index(){return "index";}/*** @description 获取验证码* @author * @date 2023-02-13 15:25:02* @param phone* @return {@link String}*/@PostMapping("/getPhone")@ResponseBodypublic String phone(String phone){//调用方法,发送手机验证码String result = codeService.getCode(phone);if (result != null){return result;}return JSON.toJSONString(new R("0","验证码发送失败,请重试!",null));}/*** @description 登录验证* @author * @date 2023-02-13 15:25:18* @param phone* @param code* @return {@link String}*/@GetMapping("/login.do")public String login(String phone,String code){boolean flag = codeService.checkCode(phone, code);// 判断是否相同if (flag){// 相同,通过,跳转页面return "login";}else {// 不同,不通过,返回原页面return "index";}}
}
6、创建service层,并创建service类
@Service
public class CodeService {/*** @description 获取验证码* @author * @date 2023-02-13 14:10:27* @param* @return {@link String}*/public String phoneCode(){return (int)((Math.random()*9+1)*100000)+"";}/*** @description 根据手机号获取验证码,并设置有效期* @author * @date 2023-02-13 14:11:42* @param* @return {@link String}*/public String getCode(String phone){//手机号对应的次数keyString countKey = phone +"_count";//手机验证码的keyString codeKey = phone + "_code";//获取手机号次数String phoneCount = RedisTools.get(countKey);if (phoneCount == null || "".equals(phoneCount)){//第一次获取验证码,存入redisRedisTools.setEx(countKey,"1",1, TimeUnit.DAYS);}else if (Integer.parseInt(phoneCount) <= 2){//获取验证码剩余时间Long timeRemaining = RedisTools.getExpire(codeKey);if (timeRemaining > 0){//转换为分钟long m = timeRemaining / 60;//转换为秒long s = timeRemaining % 60;return JSON.toJSONString(new R("0","短信已成功发送,请"+m+"分钟"+s+"秒后重新获取",null));}//获取验证码次数加一RedisTools.incrBy(countKey,1);}else {return JSON.toJSONString(new R("0","今日发送验证码的次数已达上限!",null));}//获取验证码String phoneCode = this.phoneCode();//发送验证码,获取返回结果String result = CodeTools.getCode(phone, code);//String result = "{\"code\":2,\"msg\":\"account或password不正确\",\"smsid\":\"0\"}";//如果结果为空则发送验证码失败if (result == null){return JSON.toJSONString(new R("0","验证码获取失败!",null));}else {//将验证码存入redisRedisTools.setEx(codeKey,phoneCode,5,TimeUnit.MINUTES);}// 将字符串类型的json数据转换为json对象JSONObject jsonObject = JSONObject.parseObject(result);// 从json对象中拿取code code为2时返回为正常String code = jsonObject.get("code").toString();if (code.equals("2")){return JSON.toJSONString(new R("1","验证码已发送,请注意查看!",null));}else {return JSON.toJSONString(new R("0","验证码发送失败,请重试!",null));}}/*** @description 登录验证* @author * @date 2023-02-13 14:38:15* @param phone* @param code* @return {@link boolean}*/public boolean checkCode(String phone,String code){String phoneCode ="";try {phoneCode = RedisTools.get(phone + "_code");}catch (Exception e){e.printStackTrace();}//判断验证码是否正确boolean flag = phoneCode.equals(code);return flag;}
}
7、创建工具类,将发送短信的代码放入工具类
发送短信工具类
String account = ""--->查看用户名是登录用户中心->验证码短信->产品总览->APIID
String passwor = ""----> //查看密码请登录用户中心->验证码短信->产品总览->APIKEY
public class CodeTools {/*** @description 发送验证码* @author * @date 2023-02-13 16:04:08* @param phone* @param mobile_code* @return {@link String}*/public static String getCode(String phone,String mobile_code){String postUrl = "http://106.ihuyi.cn/webservice/sms.php?method=Submit";//int mobile_code = (int)((Math.random()*9+1)*100000); //获取随机数//查看用户名是登录用户中心->验证码短信->产品总览->APIIDString account = "";//查看密码请登录用户中心->验证码短信->产品总览->APIKEYString password = "";// 设置短信内容String content = new String("您的验证码是:" + mobile_code + "。请不要把验证码泄露给其他人。");String line, result = "";try {// 创建URL对象URL url = new URL(postUrl);// 创建连接对象HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 同意输出//允许连接提交信息connection.setDoOutput(true);//网页提交方式“GET”、“POST”connection.setRequestMethod("POST");// 设置字符编码connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");connection.setRequestProperty("Connection", "Keep-Alive");StringBuffer sb = new StringBuffer();sb.append("account="+account);sb.append("&password="+password);sb.append("&mobile="+phone);sb.append("&content="+content);// 设置返回数据的数据格式为JSONsb.append("&format=json");// 以各种流的转换请求数据java.io.OutputStream os = connection.getOutputStream();os.write(sb.toString().getBytes());os.close();// 读取请求数据的结果BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));while ((line = in.readLine()) != null) {// 对数据进行拼接result += line + "\n";}in.close();System.out.println(result);} catch (IOException e) {e.printStackTrace(System.out);return null;}// 返回API的返回结果,为JSON,,,,有的可能为XML,,注意自己的设置return JSON.toJSONString(new R("1","验证码已发送,请注意查看!",null));}
}
8、返回值工具类
@Data
public class R<T>{private String code;private String msg;private T data;public R() {}public R(String code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}@Overridepublic String toString() {return "R{" +"code='" + code + '\'' +", msg='" + msg + '\'' +", data=" + data +'}';}
}
deris工具类提连接
链接:https://pan.baidu.com/s/1CCDD496oIGdRfqAIx8OQ2Q?pwd=tewx
提取码:tewx
9、写前端代码验证
登录页面代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="/js/jquery-1.12.4.js"></script><script src="/js/phone.js"></script>
</head>
<body><form action="login.do" method="get">电话:<input type="text" id="phone" name="phone"><span id="sub">获取验证码</span><span id="msg"></span><br>获取验证码:<input type="text" id="code" name="code"><input type="submit" value="登录"></form></body>
</html>
js代码
$(function (){$("#sub").click(function () {let phone = $("#phone").val();$.ajax({"url": "getPhone","type": "post","data": "phone=" + phone,"dataType": "json","success": function (result) {//调用方法var code = result.codevar msg = result.msgif (code==="0"){$("#msg").html(msg);}else if (code==="1"){$("#msg").html(msg);}},"error": function () {alert("校验失败00!")}});})
})相关文章:
java手机短信验证,并存入redis中,验证码时效5分钟
目录 1、注册发送短信账号一个账号 2、打开虚拟机,将redis服务端打开 3、创建springboot工程,导入相关依赖 4、写yml配置 5、创建controller层,并创建controller类 6、创建service层,并创建service类 7、创建工具类&#x…...
kubectl命令控制远程k8s集群(Windows系统、Ubuntu系统、Centos系统)
文章目录1. 本地是linux2. 本地是Windows1. 本地是linux 安装kubectl命令 法一:从master的/usr/bin目录下拷贝kubectl文件到本机/usr/bin目录下法二:GitHub下载kubectl文件 在家目录下创建.kube目录config文件 法一:将master上对应用户的~/.…...
【求解器-COPT】COPT的版本更新中,老版本不能覆盖的问题
【求解器-COPT】COPT的版本更新中,老版本不能覆盖的问题方法1方法2如果license还是找不到作者:刘兴禄 参考网址: COPT的下载和配置步骤如下: 教程 | Windows系统下如何安装COPT求解器并配置许可文件: https://zhuan…...
Vue3.0文档整理:一、简介
1.1:什么是vue? Vue是一款用于构建用户界面的javascript框架;它基于标准HTML、CSS和Javascript构建,并提供了一套声明式、组件化的编程模型,帮助你高效的开发用户界面。 1.2:MVVM工作原理 MVVM指的是model、view和vie…...
vue2 diff算法及虚拟DOM
概括:diff算法,虚拟DOM中采用的算法,把树形结构按照层级分解,只比较同级元素,不同层级的节点只有创建和删除操作。 一、虚拟DOM (1) 什么是虚拟DOM? 虚拟 DOM (Virtual DOM,简称 VDOM) 是一种…...
Ray和极客们的创新之作,2月18日来发现
所在论坛:数据库技术创新&云原生论坛分享时段:2.18 10:30-11:00分享主题:云原生数据库PieCloudDB :Unbreakable安全特性剖析分享嘉宾:王淏舟,拓数派资深研发工程师 由中国开源软件推进联盟PostgreSQL分…...
Dubbo 源码分析 – 集群容错之 Router
1. 简介 上一篇文章分析了集群容错的第一部分 – 服务目录 Directory。服务目录在刷新 Invoker 列表的过程中,会通过 Router 进行服务路由。上一篇文章关于服务路由相关逻辑没有细致分析,一笔带过了,本篇文章将对此进行详细的分析。首先&…...
行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测)
行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测) 目录 行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测) 1. 前言 2. 人体检测数据集说明 3. 基于YOLOv5的人体检测模型训练 4.人体检测模型…...
【图像分类】基于PyTorch搭建LSTM实现MNIST手写数字体识别(单向LSTM,附完整代码和数据集)
写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 提起LSTM大家第一反应是在NLP的数据集上比较常见,不过在图片分类中,它同样也可以使用。我们以比较熟悉的 mnist…...
Kotlin 1.8.0 现已发布,有那些新特性?
文章目录**如何安装 Kotlin 1.8.0****如果您遇到任何问题****更多文章和视频**结语Kotlin 1.8.0 版本现已发布,以下是其部分最大亮点: JVM 的新实验性功能:递归复制或删除目录内容提升了 kotlin-reflect 性能新的-Xdebug编译器选项ÿ…...
likeshop单商户SaaS商城系统—无限多开,搭建多个商城
likeshop单商户SaaS商城系统:适用于多开(SaaS)、B2C、单商户、自营商城场景,完美契合私域流量变现闭环交易使用,系统拥有丰富的营销玩法,强大的分销能力,支持DIY多模板,前后端分离。…...
Bean(Spring)的执行流程和生命周期
Bean(Spring)的执行流程具体的流程就和我们创建Spring基本相似。启动 Spring 容器 -> 实例化 Bean(分配内存空间,从无到有) -> Bean 注册到 Spring 中(存操作) -> 将 Bean 装配到需要的…...
工作记录------PostMan自测文件导入、导出功能
工作记录------PostMan自测文件导入、导出功能 测试文件导出 背景:写了一个文件下载功能,是数据写到excel中,下载,使用PostMan点击send后,返回报文是乱码。 解决办法: 点击send下面的 send and Downlo…...
上海亚商投顾:沪指震荡上行 大消费板块全线走强
上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。市场情绪三大指数今日震荡反弹,沪指全天低开高走,深成指、创业板指均涨超1%。工程机械板块集体大涨&a…...
linux中的图形化UDP调试工具
sokit freeware version: 1.3.1 (GPLv3) website: https://github.com/sinpolib/sokit/ 这是一个TCP / UDP数据包收发和传输工具 linux汉化 默认是英文版本的,如果想使用中文,把软件目录下的sokit.lan_rename重命令为sokit.lan再次打开软件就发现已经…...
前端react面试题指南
概述下 React 中的事件处理逻辑 抹平浏览器差异,实现更好的跨平台。避免垃圾回收,React 引入事件池,在事件池中获取或释放事件对象,避免频繁地去创建和销毁。方便事件统一管理和事务机制。 为了解决跨浏览器兼容性问题࿰…...
深入浅出原核基因表达调控(乳糖操纵子、色氨酸操纵子)
原核基因表达调控 前言 自然界里,能量时有时无,各种生命为了让自己能够活下去,需要适应环境,在不同的环境合成不同的蛋白质。 原核生物体内有很多细胞,细胞里面有很多蛋白质,但是这些蛋白质在这些细胞里…...
10分钟理解Mysql索引
一、索引介绍 索引是什么 官方介绍索引是帮助MySQL高效获取数据的数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。 一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往是存储在磁盘…...
nVisual综合布线可视化管理系统解决方案
一、综合布线管理系统的必要性 如今企事业单位办公人员变化很快,如果还是采用传统方式通过工程竣工图或者网络拓扑图来进行网络维护工作会非常麻烦,并且对管理人员的要求也会很高,管理人员需要清楚的知道工作区的信息点与配线架点之间的对…...
34岁测试工程师被辞退,难道测试岗位真的只是青春饭吗?
一:前言:人生的十字路口静坐反思 入软件测试这一行至今已经10年多,承蒙领导们的照顾与重用,同事的支持与信任,我的职业发展算是相对较好,从入行到各类测试技术岗位,再到测试总监,再…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
TJCTF 2025
还以为是天津的。这个比较容易,虽然绕了点弯,可还是把CP AK了,不过我会的别人也会,还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...
PH热榜 | 2025-06-08
1. Thiings 标语:一套超过1900个免费AI生成的3D图标集合 介绍:Thiings是一个不断扩展的免费AI生成3D图标库,目前已有超过1900个图标。你可以按照主题浏览,生成自己的图标,或者下载整个图标集。所有图标都可以在个人或…...
MySQL体系架构解析(三):MySQL目录与启动配置全解析
MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录,这个目录下存放着许多可执行文件。与其他系统的可执行文件类似,这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中,用…...
