项目总结一:注册模块
2016-05-23 20:44
761 查看
一、业务逻辑分析
二、原型图
三、实现过程
1、创建用户模块相关类
User:作为实体类与数据库表对应。
UserDao:封装了数据库的基本操作。
UserService:封装了业务功能,每个方法对应一个业务功能,例如注册方法、登录方法等。
UserServlet:用来接收客户端请求,处理与web相关的问题,例如获取客户端的请求参数,然后转发或重定向。
2、regist.jsp页面功能实现
注册从regist.jsp页面开始。我们需要在regist.jsp页面中对表单数据使用JQuery进行校验。当用户在文本框中输入数据后,光标离开文件框时对数据进行校验!如果校验未通过,会在文本框后台显示错误信息。用户名校验:
用户名不能为空;
用户名长度必须在3 ~ 20之间;
用户名已被注册(需要异步访问服务器)。
登录密码校验:
密码不能为空;
密码长度必须在3 ~ 10之间;
确认密码校验:
确认密码不能为空;
两次输入不一致;
Email校验:
Email不能为空;
Email格式错误(/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/);
Email已被注册(需要异步访问服务器);
验证码校验:
验证码不能为空;
验证码错误(需要异步访问服务器);
当点击“立即注册”按钮时,还要对表单每项进行校验!因为一开始可能填写了正确的验证码,所以光标离开时没有错误,但用户又点击了“换一张”链接,这时填入的验证码就是错误的了,所以我们需要在提交表单时再次进行校验。
UserServlet对前端异步请求的支持
3、UserServlet#regist()
当表单校验通过后,客户端会请求UserServlet#regist() 方法。regist()方法的工作内容如下:封装表单数据到User对象中;
对User对象数据进行服务器端校验;
如果校验失败,把错误信息保存到Map中;
把Map保存到request中;
把user保存到request,用来在表单中回显;
转发到regist.jsp页面,return;
调用UserService#regist(User)方法完成注册;
对user进行数据补全:uid、activationCode、status;
通过userDao的add(User)方法完成向数据库表插入记录;
使用TxQueryRunner的update()完成插入记录;
发送激活邮件。
保存成功信息,转发到msg.jsp。
/** * 注册功能 * @param req * @param resp * @return * @throws ServletException * @throws IOException */ public String regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* * 1. 封装表单数据到User对象 */ User formUser = CommonUtils.toBean(req.getParameterMap(), User.class); /* * 2. 校验之, 如果校验失败,保存错误信息,返回到regist.jsp显示 */ Map<String,String> errors = validateRegist(formUser, req.getSession()); if(errors.size() > 0) { req.setAttribute("form", formUser); req.setAttribute("errors", errors); return "f:/jsps/user/regist.jsp"; } /* * 3. 使用service完成业务 */ userService.regist(formUser); /* * 4. 保存成功信息,转发到msg.jsp显示! */ req.setAttribute("code", "success"); req.setAttribute("msg", "注册功能,请马上到邮箱激活!"); return "f:/jsps/msg.jsp"; }
/* * 注册校验 * 对表单的字段进行逐个校验,如果有错误,使用当前字段名称为key,错误信息为value,保存到map中 * 返回map */ private Map<String,String> validateRegist(User formUser, HttpSession session) { Map<String,String> errors = new HashMap<String,String>(); /* * 1. 校验登录名 */ String loginname = formUser.getLoginname(); if(loginname == null || loginname.trim().isEmpty()) { errors.put("loginname", "用户名不能为空!"); } else if(loginname.length() < 3 || loginname.length() > 20) { errors.put("loginname", "用户名长度必须在3~20之间!"); } else if(!userService.ajaxValidateLoginname(loginname)) { errors.put("loginname", "用户名已被注册!"); } /* * 2. 校验登录密码 */ String loginpass = formUser.getLoginpass(); if(loginpass == null || loginpass.trim().isEmpty()) { errors.put("loginpass", "密码不能为空!"); } else if(loginpass.length() < 3 || loginpass.length() > 20) { errors.put("loginpass", "密码长度必须在3~20之间!"); } /* * 3. 确认密码校验 */ String reloginpass = formUser.getReloginpass(); if(reloginpass == null || reloginpass.trim().isEmpty()) { errors.put("reloginpass", "确认密码不能为空!"); } else if(!reloginpass.equals(loginpass)) { errors.put("reloginpass", "两次输入不一致!"); } /* * 4. 校验email */ String email = formUser.getEmail(); if(email == null || email.trim().isEmpty()) { errors.put("email", "Email不能为空!"); } else if(!email.matches("^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\\.[a-zA-Z0-9_-]{2,3}){1,2})$")) { errors.put("email", "Email格式错误!"); } else if(!userService.ajaxValidateEmail(email)) { errors.put("email", "Email已被注册!"); } /* * 5. 验证码校验 */ String verifyCode = formUser.getVerifyCode(); String vcode = (String) session.getAttribute("vCode"); if(verifyCode == null || verifyCode.trim().isEmpty()) { errors.put("verifyCode", "验证码不能为空!"); } else if(!verifyCode.equalsIgnoreCase(vcode)) { errors.put("verifyCode", "验证码错误!"); } return errors; }
4、用户激活
激活页面是在用户的邮箱里,是在注册成功时发送到用户邮箱中的。这里的超链接地址为:"http://localhost:8080/login_regist/UserServlet?method=activation&activationCode=xxx",
其中method=activation表示调用UserServlet的activation()方法;其中activationCode就是用户注册成功后生成的唯一激活码!通过唯一的activationCode可以在表中查询出User,如果没有查询到User,那么说明激活码无效;如果查询到了,把User的status修改为true,就表示激活成功。
激活功能的代码实现:
1、首先是发送邮件到注册的邮箱
/* * 3. 发邮件 */ /* * 把配置文件内容加载到prop中 */ Properties prop = new Properties(); try { prop.load(this.getClass().getClassLoader().getResourceAsStream("email_template.properties")); } catch (IOException e1) { throw new RuntimeException(e1); } /* * 登录邮件服务器,得到session */ String host = prop.getProperty("host");//服务器主机名 String name = prop.getProperty("username");//登录名 String pass = prop.getProperty("password");//登录密码 Session session = MailUtils.createSession(host, name, pass); /* * 创建Mail对象 */ String from = prop.getProperty("from"); String to = user.getEmail(); String subject = prop.getProperty("subject"); // MessageForm.format方法会把第一个参数中的{0},使用第二个参数来替换。 String content = MessageFormat.format(prop.getProperty("content"), user.getActivationCode()); Mail mail = new Mail(from, to, subject, content); /* * 发送邮件 */ try { MailUtils.send(session, mail); } catch (MessagingException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } }
2、用户点击上面的超链接,会访问UserServlet#activation()方法
如下所示:
/** * 激活功能 * @param req * @param resp * @return * @throws ServletException * @throws IOException */ public String activation(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* * 1. 获取参数激活码 * 2. 用激活码调用service方法完成激活 * > service方法有可能抛出异常, 把异常信息拿来,保存到request中,转发到msg.jsp显示 * 3. 保存成功信息到request,转发到msg.jsp显示。 */ String code = req.getParameter("activationCode"); try { userService.activatioin(code); req.setAttribute("code", "success");//通知msg.jsp显示对号 req.setAttribute("msg", "恭喜,激活成功,请马上登录!"); } catch (UserException e) { // 说明service抛出了异常 req.setAttribute("msg", e.getMessage()); req.setAttribute("code", "error");//通知msg.jsp显示X } return "f:/jsps/msg.jsp"; }
相关文章推荐
- curator的使用(将Zookeeper封装的客户端)
- 面试为什么别人会问你一些你看起来比职位要难一些的问题
- 面试为什么别人会问你一些你看起来比职位要难一些的问题
- Android基于google ZXing的简化版BarCodeTest实现二维码的扫描及简单的网页跳转
- map 的用法(待补充)
- 字符编码历史(字符编码详解)
- Android imageView图片按比例缩放
- 无向图的深度优先遍历和广度优先遍历(递归)
- 30天C#基础巩固------面向鸭子编程,关于string和File的练习
- bzoj 1875: [SDOI2009]HH去散步(矩阵优化DP)
- LK源码解析 3 thread.c
- Ruby on Rails 使用 Ajax
- hacker常用的运行小助手
- 代码训练营——java读取文件中内容
- java ArrayList Vector LinkedList的区别
- 第十三周项目二 抽象类动物这样叫
- sdut 2878 Circle 高斯消元
- Astar Round2A
- Genymotion如何启动网络连接
- python中内置函数locals()和gloabls()解析