【功能栏】基于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.hqwc.cn/news/177892.html

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

相关文章

uniapp Android如何打开常用系统设置页面?

uniapp Android 如何打开常用系统设置页面&#xff1f; 在使用App过程时&#xff0c;有时候会对一些权限获取&#xff0c;比如打开蓝牙、打开通知栏通知等设置&#xff0c;我们如何快速跳转到需要的设置页面&#xff1f; 文章目录 uniapp Android 如何打开常用系统设置页面&…

开发程序员的宝藏工具/网站

博主在这里收录各式各样的工具/网站&#xff0c;都是一些能够帮助开发、提高效率的好东西 博主会不断更新&#xff0c;更加欢迎大家把自己觉得好用的分享在评论区 记得收藏起来&#xff0c;免得以后找不到了 1.文本对比 在线文本差异对比,文本比对、文本比较工具 能够将两边的…

MySQL--视图、存储过程、触发器

1、视图 1、定义&#xff1a; 所谓的视图是一种虚拟存在的表&#xff0c;视图中的数据并不在数据库中实际存在&#xff0c;就是视图只保存了查询的SQL逻辑&#xff0c;不保存查询的结果&#xff0c;所以在创建视图的时候&#xff0c;主要的工作就是落在创建这条SQL查询语句的时…

Python爬虫的七个常用技巧总结,这些你一定得知道!

文章目录 前言1、基本抓取网页2、使用代理IP3、Cookies处理4、伪装成浏览器5、验证码的处理6、gzip压缩7、多线程并发抓取关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战…

Redis Hotkey?3招定位+5招解决

作者总结分享 Redis Hotkey 定位和解决方法的优缺点。 作者&#xff1a;贲绍华&#xff0c;爱可生研发中心工程师&#xff0c;负责项目的需求与维护工作。其他身份&#xff1a;柯基铲屎官。 爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用&#xff0c;转载请联系…

LoadRunner脚本编写之三(事务函数)

关于脚本的这块&#xff0c;前两篇都在讲C语言&#xff0c;其实&#xff0c;要整理点实用的东西挺难&#xff0c;在应用中多对录制的脚本分析&#xff0c;但对于新手学脚本确实无从下手。 先贴一个脚本&#xff1a; 完整代码&#xff1a; 重点代码部分&#xff1a; Action(…

做一个Springboot文件上传-阿里云

概述 这个模块是用来上传头像以及文章封面的&#xff0c;图片的值是一个地址字符串&#xff0c;一般存放在本地或阿里云服务中 1、本地文件上传 我们将文件保存在一个本地的文件夹下&#xff0c;由于可能两个人上传不同图片但是却同名的图片&#xff0c;那么就会一个人的图片就…

腾讯待办停止运营怎么办?导出的ics文件数据怎么打开查看

待办提醒类工具是日常办公及生活中必不可少的工具&#xff0c;使用待办提醒类工具可以记录很多容易忘记的事情&#xff0c;其可以帮助大家轻松管理各项事务和提高办事的效率。而随着工作的不断变动&#xff0c;大家选择待办提醒类工具也会不断的发生改变。 比如就拿我自己的使…

时间序列预测(5) — ARIMA模型原理

目录 1 ARIMA模型简介 1.1 ARIMA模型原理 1.2 ARIMA模型适用条件 1.3 模型基本步骤 2 差分&#xff08;Differencing&#xff09; 2.1 差分运算的作用 2.2 差分运算 2.3 差分的阶数 2.4 差分的滞后 2.5 差分运算使用注意点 3 数据的平稳性 3.1 数据平稳性的概念 3…

R语言爬虫程序自动爬取图片并下载

R语言本身并不适合用来爬取数据&#xff0c;它更适合进行统计分析和数据可视化。而Python的requests&#xff0c;BeautifulSoup&#xff0c;Scrapy等库则更适合用来爬取网页数据。如果你想要在R中获取网页内容&#xff0c;你可以使用rvest包。 以下是一个简单的使用rvest包爬取…

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

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

unity UGUI无限循环滚动居中

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