zoukankan      html  css  js  c++  java
  • 项目总结一:注册模块

    一、业务逻辑分析

      

    二、原型图

      

    三、实现过程

      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";
        }
  • 相关阅读:
    我渴望自由和成功(愿与君共勉)
    gdb使用 和core dump文件调试
    谷歌浏览器快捷键大全
    Android适屏
    BestCoder Round #33
    NAT&amp;Port Forwarding&amp;Port Triggering
    程序员应该学习的书
    java代码调用rtx发送提醒消息
    js实现excel导出
    一个跨界程序员:不务正业的这几年,我如何让自己的收入翻了十倍(转)
  • 原文地址:https://www.cnblogs.com/xujian2014/p/5520732.html
Copyright © 2011-2022 走看看