JavaWeb - 黑马旅游网(2):用户注册

项目课程链接:https://www.bilibili.com/video/BV1CE411E7h4
完整课程连接:https://www.bilibili.com/video/BV1uJ411k7wy

1 业务描述

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

在这里插入图片描述
网页中提供多个输入框,并给出对应的提示信息,逐步引导用户根据提示向输入框中填写信息。最终点击下方的 注册 按钮完成用户注册。

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

在这里插入图片描述
在这里插入图片描述

2 业务分析

2.1 业务流程抽象

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

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

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

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

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

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

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

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

3 代码实现

3.1 信息验证与提交

在这里插入图片描述

3.1.1 前端

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

    /*如果此方法:
    	无返回或返回true,则表单提交
    	返回false,则表单不提交
     */
    $(function () {
    	// 当表单提交时调用所有的校验方法
    	$("#registerForm").submit(function () {
    		// 1.发送数据到服务器
    		if (
    				checkUsername() &&			// 用户名校验
    				checkPassword() &&			// 密码校验
    				checkEmail() &&				// 邮箱校验
    				checkName() &&				// 姓名校验
    				checkTelephone() &&			// 手机号校验
    				checkSex() &&				// 性别校验
    				checkBirthday() &&			// 生日校验
    				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);
    })
    
  2. 用户名校验

    // 校验用户名
    function checkUsername() {
    	// 1.获取用户名
    	let username = $("#username").val();
    	// 2.定义正则
    	let reg_username = /^\w{8,20}$/;
    	// 正则:单词字符,以单词开头,以单词结尾,长度8~20位,包含8和20
    	// 3.判断并给出提示信息
    	let flag = reg_username.test(username);
    	if (flag) {		// 校验合法
    		$("#username").css("border", "");
    	} else {		// 校验非法
    		// 输入栏边框变红
    		$("#username").css("border", "2px solid red");
    	}
    	return flag;
    }
    
  3. 密码校验

    // 校验密码
    function checkPassword() {
    	// 1.获取密码
    	let password = $("#password").val();
    	// 2.定义正则
    	let reg_username = /^\w{8,20}$/;
    	// 正则:单词字符,以单词开头,以单词结尾,长度8~20位,包含8和20
    	// 3.判断并给出提示信息
    	let flag = reg_username.test(password);
    	if (flag) {		// 校验合法
    		$("#password").css("border", "");
    	} else {		// 校验非法
    		// 输入栏边框变红
    		$("#password").css("border", "2px solid red");
    	}
    	return flag;
    }
    

校验工作重复性较高,其它校验就不再博客里写了。可以参考我的项目仓库,或者暮光乐鱼的博客

3.1.2 Servlet

/**
 * 用户注册方法
 */
public void register(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // 0.验证码校验
    HttpSession session = request.getSession();
    // 获取客户端浏览器提交的验证码
    String checkCode_browser = request.getParameter("check");
    session.removeAttribute("check");   // 客户端验证码获取即从Session中移除,保证验证码的一次性
    // 获取服务器程序 CheckCodeServlet 生成的验证码
    String checkCode_server = (String) session.getAttribute("CheckCode_Server");
    // 验证码比对
    if (!checkCode_server.equalsIgnoreCase(checkCode_browser)) {        		  			  
        /*比对失败,向浏览器回写信息并退出方法*/
        return;
    }

    // 1.获取用户提交数据
    Map<String, String[]> parameterMap = request.getParameterMap();
    // 2.封装对象
    User user = new User();
    /*利用BeanUtils.populate将表单封装至user对象中*/

    // 3.调用service完成注册
    boolean flag = service.register(user);
    ResultInfo resultInfo = new ResultInfo();

    // 4.响应结果
	ResultInfo resultInfo = new ResultInfo();
	/*向resultInfo填充信息,序列化为json,回写给客户端浏览器*/
}

3.1.3 Service

/**
 * 注册用户
 * @param user User Bean 对象
 * @return boolean
 *      true:注册成功
 *      false:注册失败
 */
@Override
public boolean register(User user) {
    // 1.根据用户名查询用户对象(存在false,不存在true)
    User loginUser = userDao.findByUsername(user.getUsername());
    // 判断loginUser是否为null
    if (loginUser != null) {    // 用户名存在,注册失败
        return false;
    }   // 用户名不存在,注册成功
    // 2.保存用户信息
    // 2.1 设置唯一的激活码
    user.setCode(UuidUtil.getUuid());
    // 2.2 设置激活状态
    user.setStatus("N");    // 初始状态:未激活
    // 2.3 向数据库中写入用户信息
    userDao.save(user);
    // 3.发送激活邮件
    // 3.1 定义邮件内容
    String content = "<a href='http://localhost:80/travel/user/active?code=" +
            user.getCode() + "'>点击激活【黑马旅游网】</a>";
    // 3.2 发送邮件
    MailUtils.sendMail(user.getEmail(), content, "激活邮件");
    return true;
}

3.1.4 Dao

/**
 * 根据用户名查询用户信息
 * @param username String 用户名
 * @return
 *      查询成功:User Bean 对象
 *      查询失败:null
 */
@Override
public User findByUsername(String username) {
    User user = null;
    try {
        // 1.定义sql
        String sql = "SELECT * FROM tab_user WHERE username = ?";
        // 2.执行sql
        user = template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), username);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return user;
}
/**
 * 用户信息保存
 * @param user User Bean 对象
 */
@Override
public void save(User user) {
    // 1.定义sql
    String sql = "INSERT INTO tab_user(" +
            "username, password, name, birthday, sex, telephone, email, status, code) " +
            "VALUES(?,?,?,?,?,?,?,?,?)";
    // 2.执行sql
    template.update(sql, user.getUsername(), user.getPassword(),
            /*一系列getter方法获取fields*/
    );
}

3.2 邮件激活

在这里插入图片描述

3.2.1 Servlet

/**
 * 用户激活方法
 */
public void active(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // 1.获取激活码
    String code = request.getParameter("code");
    if (code != null) {     // 获取激活码
        // 2.调用service完成激活操作
        // UserService service = new UserServiceImpl();
        boolean flag = service.active(code);
        // 3.判断标记
        String msg;
        if (flag) {     // 激活成功
            msg = "激活成功,请<a href='../login.html'>登录</a>";
        } else {        // 激活失败
            msg = "激活失败,请联系管理员";
        }
        // 4.回写响应内容
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(msg);
    }
}

3.2.2 Service

/**
 * 激活用户
 * @param code String 激活码
 * @return
 *      true:激活成功
 *      false:激活失败
 */
@Override
public boolean active(String code) {
    // 1.根据激活码查询用户对象
    User user = userDao.findByCode(code);
    if (user != null) {
        // 2.调用userDao中的修改激活状态方法
        userDao.updateStatus(user);
        return true;
    } else {
        return false;
    }
}

3.2.3 Dao

/**
 * 根据激活码查询用户信息
 * @param code String 激活码
 * @return
 *      查询成功:User Bean 对象
 *      查询失败:null
 */
@Override
public User findByCode(String code) {
    User user = null;
    try {
        String sql = "SELECT * FROM tab_user WHERE code = ?";
        user = template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), code);
    } catch (DataAccessException e) {
        e.printStackTrace();
    }
    return user;
}
/**
 * 更新激活状态
 * @param user User Bean 对象
 */
@Override
public void updateStatus(User user) {
    String sql = "UPDATE tab_user SET status = 'Y' WHERE uid = ?";
    template.update(sql, user.getUid());
}

部分代码并未完全展示,完整代码可以参考我的 GitHub 仓库

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaWeb中,实现用户注册可以通过以下步骤: 1. 创建一个用于用户注册的JSP页面,该页面包含一个表单,用于输入用户名和密码。可以参考引用中的注册界面代码。 2. 在JavaWeb项目中创建一个Servlet,用于处理用户注册逻辑。该Servlet接收用户提交的表单数据,并将用户名和密码插入到数据库中。可以参考引用中的UserRegister Servlet代码。 3. 在Servlet中连接数据库,并执行插入数据的操作。可以使用JDBC或其他框架进行数据库操作。 4. 在web.xml文件中配置Servlet的映射,使其能够被正确访问到。 5. 当用户在注册界面填写完用户名和密码后,点击注册按钮,表单数据将被提交到注册Servlet中进行处理。 6. 注册Servlet将接收到的用户名和密码插入到数据库中。 7. 注册成功后,可以跳转到登录界面,让用户输入刚刚注册的账号密码进行登录。 需要注意的是,以上步骤是一种常见的实现方式,具体实现还需要根据具体需求进行调整和完善。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [JavaWeb实现简单的用户注册登录(入门级)](https://blog.csdn.net/shn111/article/details/120934457)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值