JavaWeb - 仿小米商城网(2): 用户注册

1.业务描述

注册业务旨在收集和管理用户的个人信息,是未来提供个性化服务的基础。相应的前端页面如下方静态H5页面图所示:

网页中提供多个输入框,

并给出对应的提示信息,

逐步引导用户根据提示向输入框中填写信息。

最终点击下方的 注册 按钮完成用户注册。

  1. 前端Ajax验证 用户名在输入后鼠标焦点丢失, 请求发送到Servlet, 检测用户是否在数据库存在, 不存在则可以注册, 不存在则可以注册.
  2. 前端Ajax验证 邮箱在输入后鼠标焦点丢失, 请求发送到Servlet, 检测用户是否在数据库存在, 不存在则可以注册, 不存在则可以注册.

注册成功后跳转到成功提示页面

进一步地,为了验证联系方式的有效性,在完成注册功能后,前端还会提示用户执行 激活 操作:通过向用户注册时填写的邮箱发送验证邮件。在邮件正文中引导用户点击相应的超链接完成账户激活,并在激活页面提供登录链接,引导用户登录网站。整个注册业务流程完毕。

2 业务分析

2.1 业务流程抽象

在本案例中,注册业务分为两阶段:

注册阶段:用户根据前端页面的提示信息填写相应内容,进而提交至后台处理,最终将信息保存至数据库。
激活阶段:系统后台自动向用户填写的邮件地址发送一封 激活邮件,邮件中包含一个激活链接。用户通过点击激活链接向服务器发送一个请求,服务器在接收到该请求后,再向用户浏览器回写激活成功信息。

2.2 可能的技术难点与解决策略

1.避免机器人批量注册
添加验证码,优先核对,不满足直接跳出方法。(后续单独写一篇博客分析此功能)

2.如何保证激活用户的唯一性?
在 tab_user 表中添加字段:active_code 。它是一种保证唯一性的序列码,本案例中调用 Java 中的工具类 UUID 生成序列并作为用户的激活码。在用户注册时生成并与用户信息一并写入数据库,同时向用户提交的邮件地址发送一封带有激活码链接的邮件。只有用户在邮件中点击了这个链接,使用带有激活码的URL向服务器发出请求,服务器才能收到用户“发来的”激活码,并在后端完成校验并向用户端浏览器回写响应信息。

3.如何定义和处理激活状态?
在 tab_user 表中添加两个字段:status 。status 用于标注用户是否激活,它只有两种可能的取值:Y(已激活)和 N(未激活)。在用户刚刚提交注册表单时,后端在数据库中添加用户信息时对该字段设为 N,当用户在激活邮件中点击激活链接向服务器发送激活请求时,服务器在核对通过的前提下将该字段修改为 Y。

前端校验用户填写的表单信息:正则表达式校验,这里参考了暮光乐鱼的博客.

非空 :.+
字符集 :^\w{6,20}$
手机号 :1(3|4|5|7|8)\d{9}
邮箱 :^\w+(.\w+)*@\w+(.\w+)+$

3 代码实现

3.1 信息验证与提交

3.1.1 前端

通过Ajax异步验证用户名是否存在

 $(function(){$("#username").change(function(){//使用ajax 做username 的异步验证 checkUsername?username=xxxx$.get("user.do?action=checkUserName","username="+this.value,function(data){if(data==1){$("#usernameMsg").html("用户名已经存在").css("color","red");$("#registerBtn").attr("disabled",true);}else{$("#usernameMsg").html("用户名可用").css("color","green");$("#registerBtn").removeAttr("disabled");}})});})

通过Ajax验证用户邮箱是否存在

 //异步校验邮箱$(function(){$("#email").change(function(){//使用ajax 做username 的异步验证 checkUsername?username=xxxx$.get("user.do?action=checkUserEmail","username="+this.value,function(data){if(data==1){$("#emailMsg").html("用户名已经存在").css("color","red");$("#registerBtn").attr("disabled",true);}else{$("#emailMsg").html("用户名可用").css("color","green");$("#registerBtn").removeAttr("disabled");}})});})

表单数据验证与提交主函数

 <script>// 单词字符,8-12 用户名校验function checkUsername(){const s = $("#username").val();const check = /^\w{2,20}$/;const flag = check.test(s);if(flag){$("#username").css("border","");}else{$("#username").css("border","1px solid red");}return flag;}// 单词字符,8-12 密码校验function checkPassword(){const s = $("#password").val();const check = /^\w{4,20}$/;const flag = check.test(s);if(flag){$("#password").css("border","");}else{$("#password").css("border","1px solid red");}return flag;}// email校验function checkEmail(){const s = $("#email").val();//定义正则 itcast@163.comconst check = /^\w+@\w+\.\w+$/;const flag = check.test(s);if(flag){$("#email").css("border","");}else {$("#email").css("border","1px solid red");}//TODO 鼠标焦点丢失 使用Ajax验证在数据库中是否存在相同的emailreturn flag;}//校验姓名function checkName(){const s = $("#name").val();let flag = false;if(s!=null){$("#name").css("border","");flag = true;}else {$("#name").css("border","1px solid red");}return flag;}//校验验证码function checkCode(){const s = $("#validateCode").val();let flag = false;if(s!=null){$("#validateCode").css("border","");flag = true;}else {$("#validateCode").css("border","1px solid red");}return flag;}/*如果此方法:无返回或返回true,则表单提交返回false,则表单不提交*/$(function () {// 当表单提交时调用所有的校验方法$("#registerForm").submit(function () {// 1.发送数据到服务器if (checkUsername() &&         // 用户名校验checkPassword() &&          // 密码校验checkEmail() &&              // 邮箱校验checkCode()                  // 验证码校验) {         // 校验成功// 发送AJAX请求,提交表单数据    username=Alex&password=123 ...$.post("user/register", $(this).serialize(), function (data) {// 处理响应数据 data {flag:true/false, errorMsg:"..."}if (data["flag"]) { // 注册成功// 跳转成功页面location.href = "register_ok.html";} else {          // 注册失败// 在注册页面添加提示信息$("#errorMsg").html(data["errorMsg"]);}});} else { // 校验失败}// 2.跳转页面return false;});// 当某一个组件失去焦点时,调用对应的校验方法$("#username").blur(checkUsername);$("#password").blur(checkPassword);$("#email").blur(checkEmail);$("#name").blur(checkName);$("#telephone").blur(checkTelephone);$("#sex").blur(checkSex);$("#birthday").blur(checkBirthday);$("#check").blur(checkCode);})</script>

3.1.2 用户名邮箱校验的Servlet代码


@WebServlet(value = "/user.do")
public class UserServlet extends BaseServlet{/*** 用户登录* @param request* @param response* @return*/public String login(HttpServletRequest request, HttpServletResponse response){//http://localhost:8080/user.do?action=loginreturn "TODO这是用户登录功能";}/*** 验证用户名方法* @param request* @param response* @return*/public String checkUserName(HttpServletRequest request,HttpServletResponse response){IUserService userService  = new UserServiceImpl();User user = new User();//设置用户的 用户名String username = request.getParameter("username");user.setUsername(username);//验证用户是否正确boolean falg = userService.queryDataByUser(user);return  falg==false?"0":"1";}/*** 验证邮箱方法* @param request* @param response* @return*/public String checkUserEmail(HttpServletRequest request,HttpServletResponse response){IUserService userService  = new UserServiceImpl();User user = new User();//设置用户的邮箱地址String email = request.getParameter("email");user.setUsername(email);//传入用户boolean falg = userService.queryDataByUser(user);return  falg==false?"0":"1";}}

3.1.3 用户名邮箱校验的Service代码


public class UserServiceImpl implements IUserService {private IUserDao userDao = new UserDaoImpl();@Overridepublic boolean saveData(User user) {boolean flag = false;//用户名邮箱二次验证User u1 = new User();u1.setUsername(user.getUsername());User u2 = new User();u2.setEmail(user.getEmail());//一个放用户名,一个放邮箱if (!this.queryDataByUser(u1) && this.queryDataByUser(u2)){//密码md5加密后设置回去String md5 = MD5Utils.md5(user.getPassword());user.setPassword(md5);//生成激活码String activeCode = RandomUtils.createActive();user.setCode(activeCode);if (userDao.addDate(user)>=1){//发激活提示邮件EmailUtils.sendEmail(user);flag=true;}}return flag;}@Overridepublic boolean queryDataByUser(User user) {int n = userDao.findDataByUser(user);return n>=1?true:false;}//......
}

3.1.4 用户名邮箱校验的Dao代码


public class UserDaoImpl implements IUserDao {private QueryRunner queryRunner =null;public UserDaoImpl(){queryRunner = new QueryRunner();}@Overridepublic int addDate(User user) {int n =-1;String sql = "insert into tb_user(username,password,email,gender,flag,role,code) values(?,?,?,?,?,?,?)";//装载运行sql语句try {n = queryRunner.update(DBUtils.getConn(), sql,user.getUsername(),user.getPassword(),user.getEmail(),user.getGender(),user.getFlag(),user.getRole(), user.getCode());} catch (SQLException e) {e.printStackTrace();}return n;}@Overridepublic int findDataByUser(User user) {int n =-1;String sql ="select * from tb_user where 1=1";String parms ="";if (user.getEmail()!=null && !user.getEmail().equals("")){sql +=" and email=?";parms = user.getEmail();}else if (user.getUsername()!=null && !user.getUsername().equals("")){sql +=" and username=?";parms = user.getUsername();}else {return n;}try {User u = queryRunner.query(DBUtils.getConn(),sql, parms, new BeanHandler<>(User.class));if (u!=null){n= 10;}} catch (SQLException e) {e.printStackTrace();}return n;}//......
}

3.2 用户注册表单提交

3.2.1注册表单数据验证与提交主函数

/*如果此方法:无返回或返回true,则表单提交返回false,则表单不提交*/$(function () {// 当表单提交时调用所有的校验方法$("#registerForm").submit(function () {// 1.发送数据到服务器if (checkUsername() &&           // 用户名校验checkPassword() &&          // 密码校验checkEmail() &&              // 邮箱校验checkCode()                  // 验证码校验) {         // 校验成功// 发送AJAX请求,提交表单数据    username=Alex&password=123 ...$.post("user.do?action=register", $(this).serialize(), function (data) {var jsObj = JSON.parse(data);// 处理响应数据 data {flag:true/false, errorMsg:"..."}if (jsObj.flag== true) {   // 注册成功// 跳转成功页面location.href = "registerSuccess.html";} else {          // 注册失败// 在注册页面添加提示信息$("#errorMsg").html(data["errorMsg"]);}});} else { // 校验失败}// 2.跳转页面return false;});// 当某一个组件失去焦点时,调用对应的校验方法$("#username").blur(checkUsername);$("#password").blur(checkPassword);$("#email").blur(checkEmail);$("#validateCode").blur(checkCode);})

3.2.2注册表单数据Servlet

/*** 邮箱激活* @param req* @param resp* @return*/
public String activate(HttpServletRequest req, HttpServletResponse resp) {String mesg="用户激活失败,请重试";String emailB64=req.getParameter("e");String email= Base64Utils.decode(emailB64);String codeB64=req.getParameter("c");String code=Base64Utils.decode(codeB64);IUserService userService=new UserServiceImpl();User user=new User();user.setEmail(email);user.setCode(code);//如果有html链接内容输出要设置响应resp.setContentType("text/html;charset=utf-8");user.setFlag(1);if (userService.activate(user)){mesg="用户激活成功,请< a href=' '>登录</ a>";mesg= Constants.FORWARD+"message.html";}return mesg;
}

3.2.3注册用户的Service


@Override
public boolean activate(User user) {int n = userDao.updateUserState(user);return n >= 1 ? true : false;
}

3.2.4注册用户的Dao

/*** 修改用户状态* @param user* @return*/
@Override
public int updateUserState(User user) {int n=-1;String sql="update tb_user set flag=? where code=? and email=?";try {n = queryRunner.update(DBUtils.getConn(), sql,user.getFlag(),user.getCode(), user.getEmail());} catch (SQLException e) {e.printStackTrace();}return n;
}

3.3邮件激活

3.3.1 Servlet


@WebServlet(value = "/user.do")
public class UserServlet extends BaseServlet{//....
/*** 激活方法* @param request* @param response* @return*/public String activate(HttpServletRequest request,HttpServletResponse response){String mesg = "用户激活失败,请重试";String emailB64 = request.getParameter("e");String email = Base64Utils.decode(emailB64);//解密String codeB64 = request.getParameter("c");String code = Base64Utils.decode(codeB64);IUserService userService = new UserServiceImpl();User user = new User();user.setCode(code);user.setEmail(email);//人如果有html内容输出要设置响应response.setContentType("text/hrml;charset=utf-8");user.setFlag(1);if (userService.activete(user)){mesg="用户激活成功,请<a href='login.html'>登录</a>";}return mesg;}//....

3.3.2 Service


public class UserServiceImpl implements IUserService {
//.../*** 激活方法* @param user* @return*/@Overridepublic boolean activete(User user) {int n = userDao.updateUserState(user);return n>1?true:false;}
}
//...

3.3.3 Dao

public class UserDaoImpl implements IUserDao {//...
/*** 修改用户状态方法* @param user* @return*/@Overridepublic int updateUserState(User user) {int n =-1;String sql =  "update tb_user set flag = 1 where code=? and email=?";//装载运行sql语句try {n = queryRunner.update(DBUtils.getConn(), sql,user.getFlag(),user.getEmail(), user.getCode());} catch (SQLException e) {e.printStackTrace();}return n;}//...

va
public class UserDaoImpl implements IUserDao {
//…
/**
* 修改用户状态方法
* @param user
* @return
*/
@Override
public int updateUserState(User user) {
int n =-1;
String sql = “update tb_user set flag = 1 where code=? and email=?”;
//装载运行sql语句
try {
n = queryRunner.update(DBUtils.getConn(), sql,user.getFlag(),user.getEmail(), user.getCode());
} catch (SQLException e) {
e.printStackTrace();
}
return n;
}
//…

JavaWeb - 仿小米商城网(2) 用户注册相关推荐

  1. JavaWeb - 仿小米商城网(3) 登录与退出

    JavaWeb - 仿小米商城网(3) :登录与退出 1 业务描述 接上篇仿小米商城网(2):用户注册,本篇博客将分析和实现用户登录与退出.登录是后台获取当前访客身份的方式,也是提供个性化服务的基础. ...

  2. JavaWeb - 仿小米商城(5):商品详情展示

    JavaWeb - 仿小米商城(5):商品详情展示 1 功能描述 接上篇 JavaWeb - 仿小米商城(4):商品列表形式 本篇博客将分析和实现小米商城商品详情内容的查 询和展示.如下所示: 2 功 ...

  3. 仿小米商城电脑官网-纯HTML+CSS(含轮播图)

    来自作者的话 这是我第一次写博客,也是为了激励自己学习,分享一些前端学习的知识,有写的不好的多多包涵.下面是参考的一些博客的链接 https://blog.csdn.net/weixin_439768 ...

  4. HTML期末大作业~仿小米商城网页设计模板(HTML+CSS+JavaScript)

    HTML期末大作业~基于HTML+CSS+JavaScript仿小米商城(功能齐全) 关于HTML期末网页制作,大作业A+水平 ~仿小米商城网页作业HTML+CSS+JavaScript实现,共有登录 ...

  5. JavaWeb黑马旅游网-学习笔记10【项目代码】

    Java后端 学习路线 笔记汇总表[黑马程序员] JavaWeb黑马旅游网-学习笔记01[准备工作] JavaWeb黑马旅游网-学习笔记02[注册功能] JavaWeb黑马旅游网-学习笔记03[登陆和 ...

  6. 仿yeeyoo 网运行说明文档截图+说明

    仿yeeyoo 网运行说明文档截图+说明 详细截图请下载: http://download.csdn.net/source/655775 源码将在近期服务器稳定后发布,供大家免费下载 此说明只是大略的 ...

  7. HTML期末大作业 仿小米商城网页设计与制作(HTML+CSS+JavaScript) JavaScript期末大作业 web前端期末大作业 dw静态网页

    HTML期末大作业~基于HTML+CSS+JavaScript仿小米商城(功能齐全) 关于HTML期末网页制作,大作业A+水平 ~仿小米商城网页作业HTML+CSS+JavaScript实现,共有登录 ...

  8. Vue2实现仿小米商城练手项目前端篇(2-首页实现)

    缘由 去年寒假里学习了Vue.js,开学后想做一个完整的练手项目实战一下,最后决定模仿小米手机官网做一个网站项目,具体参考了Github上一位作者的项目. 现在已经基本完成了,分享在CSDN作为学习记 ...

  9. 仿小米商城和登录的静态页面

    仿小米商城和登录的静态页面 以下仅为参考,下载学习请前往本人gitee仓库 主页(index).html index.css search.js login.html login.css login. ...

最新文章

  1. Kubernetes — Calico CNI
  2. 推荐系统笔记:基于潜在因子模型的协同过滤(latent factor model)
  3. java 迪杰斯特拉_Java 实现Dikstra迪杰斯特拉算法 关于单源顶点最短路径问题的求解...
  4. 已知两点坐标拾取怎么操作_已知的操作员学习-第4部分
  5. streaming接mysql数据库_[Spark streaming举例]-- 实时统计并且存储到mysql数据库中
  6. 初学UML,画了几个UML图
  7. 自学html多久能找到工作,学web前端需要多久? 自学多长时间能找到工作?
  8. 【渝粤教育】广东开放大学 人类行为与社会环境 形成性考核 (56)
  9. 如何修改maven默认仓库(即repository)的路径
  10. Java基础,使用switch分支实现出计算器计算机功能,简单易理解
  11. 基于vue的h5抽奖活动九宫格转盘及圆形转盘
  12. 程序员520❤七夕情人节表白代码Html+Js+Css花瓣相册网页模板❤程序员表白必备...
  13. 【华为云】 搭建TFP站点心得体会
  14. java项目编码问题解决
  15. 5大原因告诉你,Python程序员为何如此难招!
  16. 【python】math函数库介绍及其例题
  17. 硬核科普:什么是狭义相对论?它有哪些惊人结论?
  18. Ubuntu 18.04 从零开始安装显卡驱动、配置MMDetection3D环境
  19. tensorflow微调vgg16 程序代码汇总
  20. Chemical Space Docking | 定义下一代虚拟筛选技术

热门文章

  1. 假如有三百多万存款,做什么稳健实体生意好?
  2. RFID票务管理系统
  3. 鸿蒙系统操作界面布局,华为鸿蒙操作系统大曝光
  4. 离散数学知识点总结(7):谓词逻辑(一阶逻辑):个体词、谓词、量词、特性谓词;特性谓词的常用场景
  5. 【前端】jQuery手机发送短信验证码定时器
  6. 仿淘宝商城项目(分布式)
  7. 新版本WordPress快速收录推送插件(Fanly Submit)
  8. GNSS基本概念(1):仰角和方位角(Elevation and Azimuth)
  9. 淘宝新开店铺如何提高转换
  10. Lambda架构简介