每一个软件或者网站都会有这个让人恶心但又不可或缺的功能
zhezhongyun 2025-01-19 01:52 95 浏览
不论是网站,桌面软件亦或者是app都会涉及到这个功能,让用户觉得恶心,更让程序员恶心的功能。你不会想的到的,它就是——注册和登陆!
别不信,我给你一分析你就懂了。
首先,作为用户,我是极不愿意注册的,那么麻烦,要填一堆信息,还经常把密码忘了,关键是每个网站都有一个账号密码,混乱,混乱你懂吗?而且所有的网站等你注册后就会跟踪你的信息和浏览习惯,后台大数据计算你的喜欢,给你推送广告什么的,隐私,呵呵,你有什么隐私……
其次,作为程序员,我艹,真不想爆粗口,这个注册和登陆的逻辑是有多麻烦?只有在码代码的我和天知道!真是bi了狗狗的感觉……
我们今天就实现一个商用版的最简单的注册,让看官您感受一下它是又多恶心!
如果你是一个正在学习的编程小白,那么你能实现个注册登录基本你就快出师了!
不信? 因为注册和登陆会用到以下技术
前端:html5和css是必须的,javascript或者jQuary做校验是必须的,麻烦的还可能使用Josn和Ajax异步交互跟后台校验,正则表达式写的66的才行,这几个个基本的技术,各个要杠杠的好,不然怎么写校验和布局??
后端:没有框架你能写吗?所以得会个框架ssm或者ssh或者其他,或者你是asp,php程序员,但是基本的逻辑绝不亚于前台判断,是的,前台明明判断好了,后台还要重新判断一遍,你说变态不?
数据库:嘿嘿,这个玩意,你数据库原理不懂怎么设计表,sql语句写的不顺怎么能行!主键约束要注意吗?唯一约束要注意吗?非空吗?默认值吗?数据冗余吗?查询速度可以不?算了,咱就不说大数据和集群了,那更麻烦……
什么?你说实际中这些都是分工做的,呵呵,少年你不是太年轻就是公司太好了,很多时候作为程序员的你都得懂,否则……“这你都不会,你不是工程师吗?”对的,别人就这么说你,而且你不懂得话怎么融合美工给的html和dba给的数据库语句?
废话不多说,我上我的demo给你们看看吧:
前端html页面和js校验:
显示页面和代码实现:
逻辑:
用户输入的非空吗?
用户随便乱输入数据吗?
用户输入的账号密码长度合适吗?
用户输入的是合格的邮箱吗?
//表单校验
$(function () {
//默认emi获得焦点
$("#e").select();
//失去焦点是校验数据
$("#e").change(function () {
var emil = $("#e").val();
if (emil == null || emil == "") {
$("#emailp").html("登陆邮箱不能为空");
$("#e").css("border", "1px #F22C03 solid");
$('#s').attr('disabled',"true");
} else {
var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
if (!filter.test(emil)) {
$("#emailp").html("邮箱格式不正确");
$("#e").css("border", "1px #F22C03 solid");
$('#s').attr('disabled',"true");
} else {
$("#emailp").html("");
$("#e").css("border", "1px #ccc solid");
}
}
});
$("#p").change(function () {
var password = $("#p").val();
if (password == null || password == "") {
$("#passwordp").html("请输入用户密码");
$("#p").css("border", "1px #F22C03 solid");
$('#s').attr('disabled',"true");
} else {
if(password.length<6||password.length>12){
$("#passwordp").html("密码只能是6到12位字母或数字");
$("#p").css("border", "1px #F22C03 solid");
$('#s').attr('disabled',"true");
}else{
$("#passwordp").html("");
$("#p").css("border", "1px #ccc solid");
//设置submit可用并设置可用样式
$('#s').removeAttr("disabled"); //移除disabled属性
$('#s').css("opacity",1);
}
}
});
});
前端注册实现:
页面代码和实现:
js校验逻辑:
非空吗?
随便输入吗?
用户名密码或者确认密码长度对吗?
密码和确认密码一样吗?
邮箱格式对吗?
//表单校验
$(function () {
//默认emil获得焦点
$("#e").select();
//失去焦点是校验数据
$("#e").blur(function () {
var emil = $("#e").val();
if (emil == null || emil == "") {
$("#emailp").html("邮箱不能为空");
$("#e").css("border", "1px #F22C03 solid");
$('#s').attr('disabled',"true");
}else {
var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
if (!filter.test(emil)) {
$("#emailp").html("邮箱格式不正确");
$("#e").css("border", "1px #F22C03 solid");
$('#s').attr('disabled',"true");
} else {
$("#emailp").html("");
$("#e").css("border", "1px #ccc solid");
}
}
});
$("#p").blur(function () {
var password = $("#p").val();
if (password == null || password == "") {
$("#passwordp").html("请输入用户密码");
$("#p").css("border", "1px #F22C03 solid");
$('#s').attr('disabled',"true");
}else {
if(password.length<6||password.length>12){
$("#passwordp").html("密码只能是6到12位字母或数字");
$("#p").css("border", "1px #F22C03 solid");
$('#s').attr('disabled',"true");
}else{
$("#passwordp").html("");
$("#p").css("border", "1px #ccc solid");
}
}
});
$("#p1").blur(function () {
var password1 = $("#p1").val();
if (password1 == null || password1 == "") {
$("#password1p").html("请再次输入用户密码");
$("#p1").css("border", "1px #F22C03 solid");
$('#s').attr('disabled',"true");
}else {
if(password1.length<6||password1.length>12){
$("#password1p").html("密码只能是6到12位字母或数字");
$("#p1").css("border", "1px #F22C03 solid");
$('#s').attr('disabled',"true");
}else{
$("#password1p").html("");
$("#p1").css("border", "1px #ccc solid");
//设置submit可用并设置可用样式
$('#s').removeAttr("disabled"); //移除disabled属性
$('#s').css("opacity",1);
}
}
});
});
后台实现:
逻辑:
判断所有字段非空否?
判断所有字段长度合适否?
判断邮箱可用否?可用就发送验证邮件
等用户去邮箱验证成功则登陆到主页,否则注册数据临时保留在临时表
等等等等的,我都懒得写……够了够了
附带代码自己看:
@Controller
@RequestMapping("/")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private CheckuserMapper checkuserMapper;
/*用户注册*/
@RequestMapping("register")
public String userRegister(){
return "register";
}
/*用户注册提交表单*/
@RequestMapping("registerForm")
public String userRegisterForm(String email, String password, String password1, Model model){
//数据校验
if(StringUtil.isEmpty(email,password,password1)){
model.addAttribute("msg","请填写内容哦~");
return "register";
}else {
if(!password.equals(password1)){
model.addAttribute("msg","两次填写的密码不一致!");
return "register";
}else {
//验证是否注册过
User user = userService.getUserByUser(new User(email.trim(),password.trim()));
if(user==null){
//没注册过则先将这个数据放到临时用户表,等邮箱验证通过后再插入到用户表
Checkuser checkuser = new Checkuser(email.trim(),password.trim());
//插入之前先删除,防止数据冗余
checkuserMapper.deleteByEmail(email.trim());
checkuserMapper.insertSelective(checkuser);
//邮箱验证
String title="欢迎注册优选网,在这里,花最少的钱,品味最优质的生活";
String path ="http://localhost:8080/youxuan/registerEmail/"+checkuser.getId();
String content="<a href='"+path+"'>确认注册优选网吗?点击跳转到优选网首页!</a>" +
"如不能点击请复制此链接到浏览器打开<a href='"+path+"'>"+path+"</a>";
try {
new MailUtil(checkuser.getUseremil(),title,content).sendEmil();
} catch (MessagingException e) {
model.addAttribute("msg","邮件发送失败,服务器出现内部错误!");
return "register";
}
//跳转邮箱页面
model.addAttribute("useremail",checkuser.getUseremil());
return "redirect:registerSendEmail";
}else {
model.addAttribute("msg","此邮箱已经注册过了");
return "register";
}
}
}
}
@RequestMapping("registerSendEmail")
public String registerSendEmail(Model model,String useremail){
model.addAttribute("useremail",useremail);
return "registerSendEmail";
}
//邮箱注册
@RequestMapping("registerEmail/{id}")
public String registerEmail(Model model, @PathVariable("id") Integer id, HttpSession session){
//查询临时用户表,数据存在则插入用户表
Checkuser checkuser = checkuserMapper.selectByPrimaryKey(id);
if(checkuser!=null){
//插入用户表,实现注册
//插入数据前,判断
User user1 = new User();
user1.setName(checkuser.getUseremil());
user1.setEmail(checkuser.getUseremil());
user1.setPassword(checkuser.getPassword());
user1.setType(1);
User user = userService.getUserByUser(user1);
//为空时表示第一次注册,插入数据
if(user==null){
userService.addUser(user1);
}
//不为为空则不插入,
//写入seseion域
session.setAttribute("user",user1);
// //返回注册成功页
return "registerSucceed";
}else {
model.addAttribute("msg","未知的错误发生了");
return "register";
}
}
@RequestMapping("login")
public String userLogin(Model model){
return "login";
}
@RequestMapping("loginForm")
public String userLoginForm(String email, String password, HttpSession session,Model model){
if(StringUtil.notEmpty(email,password)){
//不为空是判断是否存在用户
User user = userService.getUserByUser(new User(email,password));
if(user==null){
model.addAttribute("msg","用户名或密码错误,请重新输入!");
return "login";
}else{
session.setAttribute("user",user);
//成功登陆,,进入主页
return "amidnIndex";
}
}else {
model.addAttribute("msg","用户名或密码不能为空!");
return "login";
}
}
}
引用邮箱自动发送功能的类的代码:
/**
* 发送邮件测试代码
*
*/
public class MailUtil {
private String receiveEmial;//接收的邮箱
private String title;//邮件标题
private String content;//邮件内容
public MailUtil(String receiveEmial, String title, String content) {
this.receiveEmial = receiveEmial;
this.title = title;
this.content = content;
}
public void sendEmil() throws MessagingException {
// 配置发送邮件的环境属性
final Properties props = new Properties();
/*
* 可用的属性: mail.store.protocol / mail.transport.protocol / mail.host /
* mail.user / mail.from
*/
// 表示SMTP发送邮件,需要进行身份验证
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.host", "smtp.163.com");
// 发件人的账号
props.put("mail.user", "你的邮箱@163.com");
// 访问SMTP服务时需要提供的密码
props.put("mail.password", "你的密码");
// 构建授权信息,用于进行SMTP进行身份验证
Authenticator authenticator = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 用户名、密码
String userName = props.getProperty("mail.user");
String password = props.getProperty("mail.password");
return new PasswordAuthentication(userName, password);
}
};
// 使用环境属性和授权信息,创建邮件会话
Session mailSession = Session.getInstance(props, authenticator);
// 创建邮件消息
MimeMessage message = new MimeMessage(mailSession);
// 设置发件人
InternetAddress form = new InternetAddress(
props.getProperty("mail.user"));
message.setFrom(form);
// // 设置收件人
// InternetAddress to = new InternetAddress("测试邮箱@qq.com");
// message.setRecipient(RecipientType.TO, to);
// 设置抄送
InternetAddress cc = new InternetAddress("抄送邮箱@163.com");
message.setRecipient(RecipientType.CC, cc);
// 设置密送,其他的收件人不能看到密送的邮件地址
InternetAddress bcc = new InternetAddress(receiveEmial);
message.setRecipient(RecipientType.CC, bcc);
// 设置邮件标题
message.setSubject(title);
// 设置邮件的内容体
// message.setContent("<a href='http://www.xuantaobao.cn'>测试的HTML邮件</a>", "text/html;charset=UTF-8");
message.setContent(content,"text/html;charset=UTF-8");
// 发送邮件
Transport.send(message);
}
}
其他应用bean,service,mapper,dao的代码就不在这写了,我发github吧。写的恶心了
郑重声明:我这个实现只是一个demo,用的是邮箱注册,你可以试试短信注册(需要有个短信的接口,一般要购买,短信一条几分到几毛钱),我写的逻辑只是一部分,没有涵盖整个的注册流程,正常商用用登陆注册要比这个麻烦的多,所以你看着恶心吗?
恶心到你就记得点赞吧,嘿嘿,啊哈哈哈
相关推荐
- Python入门学习记录之一:变量_python怎么用变量
 - 
        
写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...
 
- python变量命名规则——来自小白的总结
 - 
        
python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...
 
- Python入门学习教程:第 2 章 变量与数据类型
 - 
        
2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...
 
- 绘制学术论文中的“三线表”具体指导
 - 
        
在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...
 
- Python基础语法知识--变量和数据类型
 - 
        
学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...
 
- 一文搞懂 Python 中的所有标点符号
 - 
        
反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...
 
- Python变量类型和运算符_python中变量的含义
 - 
        
别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...
 
- 从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序
 - 
        
在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...
 
- Python中下划线 ‘_’ 的用法,你知道几种
 - 
        
Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...
 
- 解锁Shell编程:变量_shell $变量
 - 
        
引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...
 
- 一文学会Python的变量命名规则!_python的变量命名有哪些要求
 - 
        
目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...
 
- 更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for
 - 
        
src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...
 
- C++第五课:变量的命名规则_c++中变量的命名规则
 - 
        
变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....
 
- Rust编程-核心篇-不安全编程_rust安全性
 - 
        
Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...
 
- 探秘 Python 内存管理:背后的神奇机制
 - 
        
在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...
 
- 一周热门
 
- 最近发表
 
- 标签列表
 - 
- HTML 教程 (33)
 - HTML 简介 (35)
 - HTML 实例/测验 (32)
 - HTML 测验 (32)
 - JavaScript 和 HTML DOM 参考手册 (32)
 - HTML 拓展阅读 (30)
 - HTML文本框样式 (31)
 - HTML滚动条样式 (34)
 - HTML5 浏览器支持 (33)
 - HTML5 新元素 (33)
 - HTML5 WebSocket (30)
 - HTML5 代码规范 (32)
 - HTML5 标签 (717)
 - HTML5 标签 (已废弃) (75)
 - HTML5电子书 (32)
 - HTML5开发工具 (34)
 - HTML5小游戏源码 (34)
 - HTML5模板下载 (30)
 - HTTP 状态消息 (33)
 - HTTP 方法:GET 对比 POST (33)
 - 键盘快捷键 (35)
 - 标签 (226)
 - opacity 属性 (32)
 - transition 属性 (33)
 - 1-1. 变量声明 (31)
 
 
