【功能栏】基于session的模拟短信注册功能

框架: spring boot   mybatis-plus    

目录

1.创建user表

​编辑2. mybatis-plus插件

3.导入相关依赖

4.配置文件

 5.前端代码

register.html

style.css

6.后端代码

entity层

mapper层

 sevice层

业务层接口

业务层实现类

controller层

7.调试

1. 未输入手机号的时候,直接点击获取验证码按钮

2.输入手机号,但是格式错误

3.输入手机号,并且格式正确

4.调试的时候验证码错误或者手机重复注册都是还在注册页面

8.代码解析


1.创建user表

注意:  phone这个字段设置的时候最好大于11位

2. mybatis-plus插件

安装了mybatis-plus插件后,可以根据数据库生成代码 

首先连接数据库

然后

 

3.导入相关依赖

muybatis-plus依赖
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version>
</dependency>

4.配置文件

server.port=8001
spring.datasource.url=jdbc:mysql://localhost:3306/test2?serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=1234

 5.前端代码

register.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>register</title><link rel="stylesheet" type="text/css" href="/css/style.css"/>
</head>
<body>
<div class="control"><div class="item"><div class="active">注册</div></div><div class="content"><div style="display: block;"><form action="/user/register" method="post"><p>请输入手机号</p><input type="tel" placeholder="请输入手机号" name="phone" id="phone"/><input type="text" placeholder="请输入验证码" name="code"/><button type="button">获取验证码</button><p>请输入密码</p><input type="password" placeholder="请输入密码" name="password"/><br/><input type="submit" value="注册"/></form><p>已注册,<a href="/user/login" target="top">去登录</a></p></div></div>
</div><script>var btn = document.querySelector('button');var phoneDom = document.getElementById("phone")// 全局变量,定义剩下的秒数var time = 59;// 注册单击事件  X     这里是获取验证码按钮事件btn.addEventListener('click', function () {// btn.send('post',"/user/code")//判断手机号为空if (phoneDom.value !== null && phoneDom.value !== '') {//发送请求,生成二维码let xhr = new XMLHttpRequest();// methods:GET/POST请求方式等,url:请求地址,true异步(可为false同步)xhr.open("GET", "/user/code?phone=" + phoneDom.value, true);xhr.send();                                            // 发送xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200) {   // 成功,接收到数据console.log(xhr.response);                 // 查看返回的数据(可输出 xhr 哈)// 禁用按钮btn.disabled = true;// 开启定时器var timer = setInterval(function () {// 判断剩余秒数if (time == 0) {// 清除定时器和复原按钮clearInterval(timer);btn.disabled = false;btn.innerHTML = '获取验证码';} else {btn.innerHTML = time + '秒';time--;}}, 1000);} else if (xhr.status == 404) {// 失败,页面未找到}}} else {alert("请输入手机号!")}});
</script></body>
</html>

style.css

*{margin: 0;padding: 0;
}
body{background:#65cea7 ;
}
.control{width: 340px;background: white;position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);border-radius: 5px;
}
.item{width: 340px;height: 60px;background: #eeeeee;
}
.item div{width: 340px;height: 60px;display: inline-block;color: black;font-size: 18px;text-align: center;line-height: 60px;cursor: pointer;
}
.content{width: 100%;
}
.content div{margin: 20px 30px;text-align: left;
}
p{color: #4a4a4a;margin-top: 30px;margin-bottom: 6px;font-size: 15px;
}.content input[type="tel"]{width: 100%;height: 40px;border-radius: 3px;border: 1px solid #adadad;padding: 0 10px;box-sizing: border-box;
}
.content  input[type="text"]{width: 55%;height: 40px;border-radius: 3px;border: 1px solid #adadad;padding: 0 10px;box-sizing: border-box;
}.content input[type="password"]{width: 100%;height: 40px;border-radius: 3px;border: 1px solid #adadad;padding: 0 10px;box-sizing: border-box;
}
.content button{margin-top: 40px;width: 40%;height: 40px;border-radius: 5px;color: white;border: 1px solid #adadad;background: cyan;cursor: pointer;letter-spacing: 4px;margin-bottom: 40px;}.content input[type="submit"]{margin-top: 40px;width: 100%;height: 40px;border-radius: 5px;color: white;border: 1px solid #adadad;background: cyan;cursor: pointer;letter-spacing: 4px;margin-bottom: 40px;
}
.active{background: white;
}
.item div:hover{background: #f6f6f6;
}

6.后端代码

entity层

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("user")
public class User implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Integer id;private String phone;private String password;private String  code;

mapper层

@Mapper
public interface UserMapper extends BaseMapper<User> {}

 sevice层

业务层接口

public interface IUserService extends IService<User> {String register(User user, HttpSession session);String sendCode(String phone, HttpSession session);
}

业务层实现类

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Autowiredprivate UserMapper userMapper;@Overridepublic String sendCode(String phone, HttpSession session) {//这里手机号码为空则报空指针,判断不严谨if (StringUtils.hasText(phone) && RegexUtil.isMobile(phone)) {//生成验证码String yzmCode = RandomUtil.randomNumbers(6);//保存验证码到sessionsession.setAttribute("yzmCode", yzmCode);System.out.println("发送短信验证码成功" + yzmCode);return "发送短信验证码成功!验证码是:" + yzmCode;} else {return "手机号格式错误";}}@Overridepublic String register(User user, HttpSession session) {//判断输入手机号的格式if (StringUtils.hasText(user.getPhone()) && RegexUtil.isMobile(user.getPhone())) {//从session拿出缓存的验证码Object cacheCode = session.getAttribute("yzmCode");String code = user.getCode();if (cacheCode == null || !cacheCode.equals(code)) {return "html/register";}//3.根据手机号查询用户User user1 = query().eq("phone", user.getPhone()).one();if (user1 == null) {userMapper.insert(user);return "html/login";}session.setAttribute("user1", user1);return "html/register";}return "html/register";}
}

controller层

@Controller
@RequestMapping("user")
public class UserController {@Autowiredprivate IUserService userService;@RequestMapping("/code")@ResponseBodypublic String sendCode(String phone, HttpSession session) {return userService.sendCode(phone, session);}@RequestMapping("/register")public String register(User user, HttpSession session) {return userService.register(user, session);}
}

工具类(utils)

public class RegexUtil {public static boolean isMobile(String str) {Pattern p = null;Matcher m = null;boolean b = false;p = Pattern.compile("^[1][3,4,5,8][0-9]{9}$"); // 验证手机号m = p.matcher(str);b = m.matches();return b;}
}

 

7.调试

前端页面

1. 未输入手机号的时候,直接点击获取验证码按钮

2.输入手机号,但是格式错误

3.输入手机号,并且格式正确

 

验证码是模拟生成的

 String yzmCode = RandomUtil.randomNumbers(6);

4.调试的时候验证码错误或者手机重复注册都是还在注册页面

8.代码解析

实体类

实体类的属性对应数据user表字段

控制层主要写了两个接口

一个是发送验证码接口,当我们点击前端页面获取验证码按钮的时候,这个接口响应

获取验证码事件

这里主要使用了ajax技术

<script>var btn = document.querySelector('button');var phoneDom = document.getElementById("phone")// 全局变量,定义剩下的秒数var time = 59;// 注册单击事件  X     这里是获取验证码按钮事件btn.addEventListener('click', function () {// btn.send('post',"/user/code")//判断手机号为空if (phoneDom.value !== null && phoneDom.value !== '') {//发送请求,生成验证码let xhr = new XMLHttpRequest();// methods:GET/POST请求方式等,url:请求地址,true异步(可为false同步)xhr.open("GET", "/user/code?phone=" + phoneDom.value, true);xhr.send();                                            // 发送xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200) {   // 成功,接收到数据console.log(xhr.response);                 // 查看返回的数据(可输出 xhr 哈)// 禁用按钮btn.disabled = true;// 开启定时器var timer = setInterval(function () {// 判断剩余秒数if (time == 0) {// 清除定时器和复原按钮clearInterval(timer);btn.disabled = false;btn.innerHTML = '获取验证码';} else {btn.innerHTML = time + '秒';time--;}}, 1000);} else if (xhr.status == 404) {// 失败,页面未找到}}} else {alert("请输入手机号!")}});
</script>

控制层调用service的接口里的一个方法

实现类实现该方法

方法如下 

 @Overridepublic String sendCode(String phone, HttpSession session) {//这里手机号码为空则报空指针,判断不严谨if (StringUtils.hasText(phone) && RegexUtil.isMobile(phone)) {//生成验证码String yzmCode = RandomUtil.randomNumbers(6);//保存验证码到sessionsession.setAttribute("yzmCode", yzmCode);System.out.println("发送短信验证码成功" + yzmCode);return "发送短信验证码成功!验证码是:" + yzmCode;} else {return "手机号格式错误";}}

1.首先判断手机号的格式

2.如果手机号格式不为空,且手机号格式正确

通过随机生成验证码,这里只是简单的模拟短信验证码,真正的实现这里可以调用相关的方法

3.将验证码保存到session中

4.在控制台输出该验证码

一个是注册接口

  @Overridepublic String register(User user, HttpSession session) {//判断输入手机号的格式if (StringUtils.hasText(user.getPhone()) && RegexUtil.isMobile(user.getPhone())) {//从session拿出缓存的验证码Object cacheCode = session.getAttribute("yzmCode");String code = user.getCode();if (cacheCode == null || !cacheCode.equals(code)) {return "html/register";}//3.根据手机号查询用户User user1 = query().eq("phone", user.getPhone()).one();if (user1 == null) {userMapper.insert(user);return "html/login";}return "html/register";}return "html/register";}
}

1.判断手机号格式

2.判断输入的验证码和session保存的验证码是否相等

3.根据手机号查询该用户是否存在

  User user1 = query().eq("phone", user.getPhone()).one();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/143180.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unity UGUI无限循环滚动居中

最近在做一个ui循环滚动的功能&#xff0c;网上找了半天脚本感觉都和我实际需求不太符合&#xff0c;自己花费一些时间完成了这个功能记录一下。下面开始正题 &#xff0c;我是采用unity自带组件Scroll View来完成&#xff0c;首先设置Scroll View如下图 面板层级结构如下 然…

C语言每日一题(29)合并两个有序链表

力扣网 21合并两个有序链表 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 思路分析 最基本的一种思路就是&#xff0c;遍历两个链表&#xff0c;将对应结点的值进行比较&#xff0c;题目要求是要升序排…

二部图问题

目录 一、介绍 二、染色算法的实现 三、无权二部图中的最大匹配 四、有权二部图中的最大匹配 五、稳定婚配问题 一、介绍 二部图是一种特殊的图&#xff0c;其中所有的节点可以被分成两个不相交的集合&#xff0c;使得图中的每条边连接的两个节点分属于不同的集合。换句话…

什么是GIL锁,有什么作用?python的垃圾回收机制是什么样的?解释为什么计算密集型用多进程,io密集型用多线程。

1 什么是gil锁&#xff0c;有什么作用&#xff1f; 2 python的垃圾回收机制是什么样的&#xff1f; 3 解释为什么计算密集型用多进程&#xff0c;io密集型用多线程。 1 什么是gil锁&#xff0c;有什么作用&#xff1f; 1 GIL&#xff1a;Global Interpreter Lock又称全局解释器…

基于安卓android微信小程序的食谱大全系统

项目介绍 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个开发过程首先对食谱大全进行需求分析&#xff0c;得出食谱大全主要功能。接着对食谱大全进行总体设计和详细设计。总体设…

源码升级gcc

wget https://ftp.gnu.org/gnu/gcc/gcc-8.1.0/gcc-8.1.0.tar.gztar -xzf gcc-8.1.0.tar.gzcd gcc-8.1.0/打开/contrib/download_prerequisites&#xff0c;查看依赖的库 wget http://mirror.linux-ia64.org/gnu/gcc/infrastructure/mpfr-3.1.4.tar.bz2 & wget http://mir…

实现高值医疗耗材智能化管理的RFID医疗柜解决方案

一、行业背景 医疗物资管理面临着一系列问题&#xff0c;如高值耗材种类激增导致准入标准弱化、信息追踪困难、管理责任不明确等&#xff0c;医院内部设备、财务和临床科室相互独立&#xff0c;兼容性不佳&#xff0c;高值耗材储备不足&#xff0c;缺乏合理的预警机制&#xf…

Java 21:最新特性、性能改进和语言发展

文章目录 模式匹配和模式变量新的记录类型生产者接口本地类型推断的扩展新的垃圾收集器动态CDS档案G1垃圾收集器的增强Java语言的持续发展性能改进和JEPJava 21的部署和使用Java 21的生态系统结语 &#x1f389;欢迎来到Java学习路线专栏~Java 21&#xff1a;最新特性、性能改进…

Postman接口Mock Servier服务器

近期在复习Postman的基础知识&#xff0c;在小破站上跟着百里老师系统复习了一遍&#xff0c;也做了一些笔记&#xff0c;希望可以给大家一点点启发。 应用场景&#xff1a;后端的接口还没有开发完成&#xff0c;前端的业务需要调用后端的接口&#xff0c;可以使用mock模拟。 一…

Android高级实践分享

以下是我学习过程中&#xff0c;觉得比较好的Android进阶高级实践&#xff0c;分享给大家&#xff0c;可能有些东西差异化比较大了&#xff0c;但是我也想经过这些实践&#xff0c;踩踩坑。等我搞完&#xff0c;给大家出一下实践教程 Android进阶之旅&#xff1a; https://ww…

终于有人把VMware虚拟机三种网络模式讲清楚了!

前段时间VMware更新了&#xff0c;你用上最新版了吗&#xff1f; 有几个网工在操作中遇到过各种各样的问题。 比如说由于公司服务器重启导致出现下面的问题&#xff1a;在Xshell里连接虚拟机映射时连接失败&#xff1b;能够连接上虚拟机的映射地址&#xff0c;但git pull时报…

电子电机行业万界星空科技MES解决方案

现在电子电机行业规模越来越大&#xff0c;也伴随着生产和管理成本走向变高的现象。针对这个问题&#xff0c;mes系统就成为各电子电机制造业的最优选择。 电子机电行业MES涵盖了从原材料采购到最终产品交付的整个过程&#xff0c;包括生产计划、物料管理、生产过程监控、质量…

CleanMyMac X“断网激活”真的可以吗?

CleanMyMac X帮助Mac系统进行垃圾清理&#xff0c;清除多余的缓存、应用程序等&#xff0c;在提高工作效率上起了很大的作用。但是随着对软件的需求不断增加&#xff0c;很多人开始研究通过捷径破解正版软件&#xff0c;但是是否能成功呢&#xff1f;今天小编就为大家揭开“断网…

【常见SQL报错及解决办法】个人记录,自用

ORA-00942: 表或视图不存在 现象&#xff1a;明明已经新建了视图&#xff0c;并提交了&#xff0c;直接查询的时候还是报了这个错 解决&#xff1a;视图名那加双引号&#xff0c;与建立的时候保持一致 --SELECT * FROM VIEW_NAME 报错&#xff0c;需要加双引号 SELECT * FR…

7-爬虫-中间件和下载中间件(加代理,加请求头,加cookie)、scrapy集成selenium、源码去重规则(布隆过滤器)、分布式爬虫

0 持久化(pipelines.py)使用步骤 1 爬虫中间件和下载中间件 1.1 爬虫中间件(一般不用) 1.2 下载中间件&#xff08;代理&#xff0c;加请求头&#xff0c;加cookie&#xff09; 1.2.1 加请求头(加到请求对象中) 1.2.2 加cookie 1.2.3 加代理 2 scrapy集成selenium 3 源码去重…

C++ 动态规划 DP教程 (一)思考过程(*/ω\*)

动态规划是一种思维方法&#xff0c;大家首先要做的就是接受这种思维方法&#xff0c;认同他&#xff0c;然后再去运用它解决新问题。 动态规划是用递推的思路去解决问题。 首先确定问题做一件什么事情&#xff1f; 对这件事情分步完成&#xff0c;分成很多步。 如果我们把整件…

【SpringBoot】序列化和反序列化介绍

一、认识序列化和反序列化 Serialization&#xff08;序列化&#xff09;是一种将对象以一连串的字节描述的过程&#xff1b;deserialization&#xff08;反序列化&#xff09;是一种将这些字节重建成一个对象的过程。将程序中的对象&#xff0c;放入文件中保存就是序列化&…

回顾 — SFA:简化快速 AlexNet(模糊分类)

模糊图像的样本 一、说明 在本文回顾了基于深度学习的模糊图像分类&#xff08;SFA&#xff09;。在本文中&#xff1a;Simplified-Fast-AlexNet (SFA)旨在对图像是否因散焦模糊、高斯模糊、雾霾模糊或运动模糊而模糊进行分类。 二、大纲 图像模糊建模简要概述简化快速 AlexNet…

vscode 快速打印console.log

第一步 输入这些 {// Print Selected Variabl 为自定义快捷键中需要使用的name&#xff0c;可以自行修改"Print Selected Variable": {"body": ["\nconsole.log("," %c $CLIPBOARD: ,"," background-color: #3756d4; padding:…