书城项目-第二阶段:用户登录和注册功能的介绍

书城项目-第二阶段:用户登录和注册功能的介绍、书城项目-JavaEE三层架构介绍、书城项目-搭建书城项目环境、书城项目-创建数据库和t_user用户表、书城项目-创建数据库表对应的User类、书城项目-JdbcUtils工具类的编写和测试、书城项目-编写BaseDao、书城项目-编写UserDao和测试、书城项目-编写UserService和测试、书城项目-实现用户注册的功能、书城项目-IDEA工具Debug的使用、书城项目-用户登录功能实现

书城第二阶段——用户注册和登陆

1.JavaEE 项目的三层架构

分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级。

web 层          top.qaqaq.web/servlet/controller
service 层       top.qaqaq.service                     Service 接口包 
                 top.qaqaq.service.impl                Service 接口实现类
dao 持久层        top.qaqaq.dao                         Dao 接口包
                 top.qaqaq.dao.impl                    Dao 接口实现类
实体 bean 对象    top.qaqaq.pojo/entity/domain/bean     JavaBean 类
测试包           top.qaqaq.test/junit
工具类           top.qaqaq.utils

搭建书城项目开发环境:

1、先创建书城需要的数据库和表。

# P163 书城项目-创建数据库和t_user用户表

DROP DATABASE IF EXISTS book;

CREATE DATABASE book;

USE book;

CREATE TABLE t_user(
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(20) NOT NULL UNIQUE,
    password VARCHAR(32) NOT NULL,
    email VARCHAR(200)
);

INSERT INTO t_user(username, password, email)
VALUES('admin', 'admin', 'admin@qaqaq.top');

SELECT * FROM t_user;

2、编写数据库表对应的 JavaBean 对象。

package top.qaqaq.pojo;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 1:33
 */
public class User {
    private Integer id;
    private String username;
    private String password;
    private String email;

    public User() {
    }

    public User(Integer id, String username, String password, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.email = email;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

3、编写工具类 JdbcUtils

3.1、导入需要的 jar 包(数据库和连接池需要):

druid-1.1.9.jar
mysql-connector-java-5.1.7-bin.jar


以下是测试需要:
hamcrest-core-1.3.jar
junit-4.12.jar

3.2、在 src resources源码目录下编写 jdbc.properties 属性配置文件:

username=root
password=123456
url=jdbc:mysql://localhost:3306/book
driverClassName=com.mysql.cj.jdbc.Driver
initialSize=5
maxActive=10

3.3、编写 JdbcUtils 工具类:

package top.qaqaq.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 1:36
 */
public class JdbcUtils {

    private static DruidDataSource dataSource;

    static {
        try {
            Properties properties = new Properties();
            // 读取 jdbc.properties属性配置文件
            // 注意 较新的idea需要把jdbc.properties放入resources文件夹中
            InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            // 从流中加载数据
            properties.load(inputStream);
            // 创建 数据库连接 池
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库连接池中的连接
     *
     * @return 如果返回null,说明获取连接失败 有值就是获取连接成功
     */
    public static Connection getConnection() {

        Connection conn = null;

        try {
            conn = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return conn;
    }

    /**
     * 关闭连接,放回数据库连接池
     *
     * @param conn
     */
    public static void close(Connection conn) {
        if (conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

}

3.4、JdbcUtils 测试

package top.qaqaq.test;

import org.junit.Test;
import top.qaqaq.utils.JdbcUtils;

import java.sql.Connection;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 2:16
 */
public class JdbcUtilsTest {

    @Test
    public void testJdbcUtils(){
        for (int i = 0; i < 100; i++) {
            Connection connection = JdbcUtils.getConnection();
            System.out.println(connection);
            JdbcUtils.close(connection);
        }
    }
}

4、编写 BaseDao

4.1、导入 DBUtils 的 jar 包

commons-dbutils-1.3.jar

4.2、编写 BaseDao:

package top.qaqaq.dao.impl;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import top.qaqaq.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 2:22
 */
public abstract class BaseDao {

    //使用DbUtils操作数据库
    private QueryRunner queryRunner = new QueryRunner();

    /**
     * update() 方法用来执行:Insert\Update\Delete语句
     * @return 如果返回-1,说明执行失败 返回其他表示影响的行数
     */
    public int update(String sql, Object ...args){
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner.update(connection,sql,args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(connection);
        }
        return -1;
    }

    /**
     * 查询返回一个javaBean的sql语句
     * @param type  返回的对象类型
     * @param sql   执行的sql语句
     * @param args  sql对应的参数值
     * @param <T>   返回的类型的泛型
     * @return
     */
    public <T> T queryForOne(Class<T> type,String sql,Object ...args){
        Connection con = JdbcUtils.getConnection();
        try {
            return queryRunner.query(con,sql,new BeanHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(con);
        }
        return null;
    }

    /**
     * 查询返回多个javaBean的sql语句
     * @param type  返回的对象类型
     * @param sql   执行的sql语句
     * @param args  sql对应的参数值
     * @param <T>   返回的类型的泛型
     * @return
     */
    public <T> List<T> queryForList(Class<T> type, String sql, Object ...args){
        Connection con = JdbcUtils.getConnection();
        try {
            return queryRunner.query(con,sql,new BeanListHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(con);
        }
        return null;
    }

    /**
     * 执行返回一行一列的sql语句
     * @param sql   执行的sql语句
     * @param args  sql对应的参数值
     * @return
     */
    public Object queryForSingleValue(String sql, Object ...args){
        Connection conn = JdbcUtils.getConnection();

        try {
            return queryRunner.query(conn,sql, new ScalarHandler(),args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(conn);
        }
        return null;
    }
}

5、编写 UserDao 和测试

UserDao 接口:

package top.qaqaq.dao;

import top.qaqaq.pojo.User;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 3:04
 */
public interface UserDao {

    /**
     * 根据用户名查询用户信息
     * @param username  用户名
     * @return  如果返回null,说明没有这个用户。反之亦然
     */
    public User queryUserByUsername(String username);

    /**
     * 根据 用户名和密码查询用户信息
     * @param username
     * @param password
     * @return  如果返回null,说明用户名或密码错误。反之亦然
     */
    public User queryUserByUsernameAndPassword(String username,String password);

    /**
     * 保存用户信息
     * @param user
     * @return  返回-1表示操作失败,其他是sql语句影响的行数
     */
    public int saveUser(User user);
}

UserDaoImpl 实现类:

package top.qaqaq.dao.impl;

import top.qaqaq.dao.UserDao;
import top.qaqaq.pojo.User;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 3:12
 */
public class UserDaoImpl extends BaseDao implements UserDao {
    @Override
    public User queryUserByUsername(String username) {
        String sql = "select id,username,password,email from t_user where username = ?";
        return queryForOne(User.class, sql, username);
    }

    @Override
    public User queryUserByUsernameAndPassword(String username, String password) {
        String sql = "select id,username,password,email from t_user where username = ? and password = ?";
        return queryForOne(User.class, sql, username,password);
    }

    @Override
    public int saveUser(User user) {
        String sql = "insert into t_user(username,password,email) values(?,?,?)";
        return update(sql, user.getUsername(), user.getPassword(), user.getEmail());
    }
}

UserDao 测试:

package top.qaqaq.test;

import org.junit.Test;
import top.qaqaq.dao.UserDao;
import top.qaqaq.dao.impl.UserDaoImpl;
import top.qaqaq.pojo.User;

import static org.junit.Assert.*;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 3:31
 */
public class UserDaoTest {

    UserDao userDao = new UserDaoImpl();

    @Test
    public void queryUserByUsername() {
        System.out.println(userDao.queryUserByUsername("admin"));

        if (userDao.queryUserByUsername("admin1234") == null){
            System.out.println("用户名可用!");
        } else {
            System.out.println("用户名已存在!");
        }
    }

    @Test
    public void queryUserByUsernameAndPassword() {
        System.out.println(userDao.queryUserByUsernameAndPassword("admin","admin"));

        if (userDao.queryUserByUsernameAndPassword("admin","admin1234") == null){
            System.out.println("用户名或密码错误,登陆失败");
        } else {
            System.out.println("查询成功");
        }
    }

    @Test
    public void saveUser() {
        System.out.println(userDao.saveUser(new User(null,"qaqaq","123456","123456@qq.com")));

    }
}

6、编写 UserService 和测试

UserService 接口:

package top.qaqaq.service;

import top.qaqaq.pojo.User;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 4:58
 */
public interface UserService {

    /**
     * 注册用户
     * @param user
     */
    public void registUser(User user);

    /**
     * 登陆
     * @param user
     * @return  如果返回null,说明登录失败,返回有值,是登录成功
     */
    public User login(User user);

    /**
     * 检查 用户名是否可用
     * @param username
     * @return  返回true表示用户名已存在,返回false表示用户名可用
     */
    public boolean existsUsername(String username);
}

UserServiceImpl 实现类:

package top.qaqaq.service.impl;

import top.qaqaq.dao.UserDao;
import top.qaqaq.dao.impl.UserDaoImpl;
import top.qaqaq.pojo.User;
import top.qaqaq.service.UserService;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 5:34
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoImpl();

    @Override
    public void registUser(User user) {
        userDao.saveUser(user);

    }

    @Override
    public User login(User user) {
        return userDao.queryUserByUsernameAndPassword(user.getUsername(), user.getPassword());

    }

    @Override
    public boolean existsUsername(String username) {
        if (userDao.queryUserByUsername(username) == null){
            // 等于null,说明没查到,没查到表示可用
            return false;
        }
        return true;
    }
}

UserService 测试:

package top.qaqaq.test;

import org.junit.Test;
import top.qaqaq.pojo.User;
import top.qaqaq.service.UserService;
import top.qaqaq.service.impl.UserServiceImpl;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 5:45
 */
public class UserServiceTest {

    UserService userService = new UserServiceImpl();

    @Test
    public void registUser(){
        userService.registUser(new User(null,"qqqqq","123456","123456@qq.com"));
        userService.registUser(new User(null,"qq123","123456","123456@qq.com"));
    }

    @Test
    public void login(){
        System.out.println(userService.login(new User(null,"qqqqq","123456",null)));
    }

    @Test
    public void existsUsername(){
        if (userService.existsUsername("qqqqqq")){
            System.out.println("用户名已存在!");
        } else {
            System.out.println("用户名可用!");
        }
    }
}

7、编写 web 层

7.1、实现用户注册的功能

7.1.1、图解用户注册的流程:

7.1.2、修改 regist.html 和 regist_success.html 页面

1、添加 base 标签

<!--写 base 标签,永远固定相对路径跳转的结果-->
<base href="http://localhost:8080/book/">

2、修改 base 标签对页面中所有相对路径的影响(浏览器 F12,哪个报红,改哪个)

以下是几个修改的示例:
<link type="text/css" rel="stylesheet" href="static/css/style.css" >
<script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>

3、修改注册表单的提交地址和请求方式

regist.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>尚硅谷会员注册页面</title>
	<!-- 写base便签,永远固定相对路径跳转的结果 -->
	<base href="http://localhost:8080/JavaWeb_Code_Book/">
	<link type="text/css" rel="stylesheet" href="static/css/style.css" >
	<script type="text/javascript" src="static/script/jquery-3.6.1.js"></script>
	<script type="text/javascript">
		// 页面加载完成之后
		$(function () {
			// 给注册绑定单击事件
			$("#sub_btn").click(function () {
				// 验证用户名:必须由字母,数字下划线组成,并且长度为 5 到 12 位
				//1 获取用户名输入框里的内容
				var usernameText = $("#username").val();
				//2 创建正则表达式对象
				var usernamePatt = /^\w{5,12}$/;
				//3 使用test方法验证
				if (!usernamePatt.test(usernameText)){
					//4 提示用户结果
					$("span.errorMsg").text("用户名不合法!");

					return false;
				}

				// 验证密码:必须由字母,数字下划线组成,并且长度为 5 到 12 位
				//1 获取用户名输入框里的内容
				var passwordText = $("#password").val();
				//2 创建正则表达式对象
				var passwordPatt = /^\w{5,12}$/;
				//3 使用test方法验证
				if (!passwordPatt.test(passwordText)){
					//4 提示用户结果
					$("span.errorMsg").text("密码不合法!");

					return false;
				}

				// 验证确认密码:和密码相同
				//1 获取确认密码内容
				var repwdText = $("#repwd").val();
				//2 和密码相比较
				if (repwdText != passwordText){
					//3 提示用户
					$("span.errorMsg").text("确认密码和密码不一致!");

					return false;
				}

				// 邮箱验证:xxxxx@xxx.com
				//1 获取邮箱里的内同
				var emailText = $("#email").val();
				//2 创建正则表达式对象
				var emailPatt = /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;
				//3 使用test方法验证是否合法
				if (!emailPatt.test(emailText)){
					//4 提示用户
					$("span.errorMsg").text("邮箱格式不合法!");

					return false;
				}

				// 验证码:现在只需要验证用户已输入。因为还没讲到服务器。验证码生成。
				var codeText = $("#code").val();

				// 去掉验证码前后空格
				alert("去空格前:[" + codeText + "]");
				codeText = $.trim(codeText);
				alert("去空格前:[" + codeText + "]");

				if (codeText == null || codeText == ""){
					//4 提示用户
					$("span.errorMsg").text("验证码不能为空!");

					return false;
				}

				$("span.errorMsg").text("");
			})
		})
	</script>
<style type="text/css">
	.login_form{
		height:420px;
		margin-top: 25px;
	}
	
</style>
</head>
<body>
		<div id="login_header">
			<img class="logo_img" alt="" src="static/img/logo.gif" >
		</div>
		
			<div class="login_banner">
			
				<div id="l_content">
					<span class="login_word">欢迎注册</span>
				</div>
				
				<div id="content">
					<div class="login_form">
						<div class="login_box">
							<div class="tit">
								<h1>注册尚硅谷会员</h1>
								<span class="errorMsg"></span>
							</div>
							<div class="form">
								<form action="registServlet" method="post">
									<label>用户名称:</label>
									<input class="itxt" type="text" placeholder="请输入用户名"
										   autocomplete="off" tabindex="1" name="username" id="username" />
									<br />
									<br />
									<label>用户密码:</label>
									<input class="itxt" type="password" placeholder="请输入密码"
										   autocomplete="off" tabindex="1" name="password" id="password" />
									<br />
									<br />
									<label>确认密码:</label>
									<input class="itxt" type="password" placeholder="确认密码"
										   autocomplete="off" tabindex="1" name="repwd" id="repwd" />
									<br />
									<br />
									<label>电子邮件:</label>
									<input class="itxt" type="text" placeholder="请输入邮箱地址"
										   autocomplete="off" tabindex="1" name="email" id="email" />
									<br />
									<br />
									<label>验证码:</label>
									<input class="itxt" type="text" name="code" style="width: 150px;" id="code"/>
									<img alt="" src="static/img/code.bmp" style="float: right; margin-right: 40px">
									<br />
									<br />
									<input type="submit" value="注册" id="sub_btn" />
									
								</form>
							</div>
							
						</div>
					</div>
				</div>
			</div>
		<div id="bottom">
			<span>
				尚硅谷书城.Copyright &copy;2015
			</span>
		</div>
</body>
</html>
regist_success.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>尚硅谷会员注册页面</title>
	<!-- 写base便签,永远固定相对路径跳转的结果 -->
	<base href="http://localhost:8080/JavaWeb_Code_Book/">
<link type="text/css" rel="stylesheet" href="static/css/style.css" >
<style type="text/css">
	h1 {
		text-align: center;
		margin-top: 200px;
	}
	
	h1 a {
		color:red;
	}
</style>
</head>
<body>
		<div id="header">
				<img class="logo_img" alt="" src="static/img/logo.gif" >
				<span class="wel_word"></span>
				<div>
					<span>欢迎<span class="um_span">韩总</span>光临尚硅谷书城</span>
					<a href="../order/order.html">我的订单</a>
					<a href="../../index.html">注销</a>&nbsp;&nbsp;
					<a href="../../index.html">返回</a>
				</div>
		</div>
		
		<div id="main">
		
			<h1>注册成功! <a href="index.html">转到主页</a></h1>
	
		</div>
		
		<div id="bottom">
			<span>
				尚硅谷书城.Copyright &copy;2015
			</span>
		</div>
</body>
</html>

7.1.3、编写 RegistServlet 程序

package top.qaqaq.web;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import top.qaqaq.pojo.User;
import top.qaqaq.service.UserService;
import top.qaqaq.service.impl.UserServiceImpl;

import java.io.IOException;

/**
 * @author RichieZhang
 * @create 2022-12-06 下午 9:16
 */
public class RegistServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        super.doPost(req, resp);

        // 1、获取请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String email = req.getParameter("email");
        String code = req.getParameter("code");

        // 2、检查 验证码是否正确   === 写死,要求验证码为:abcde
        if ("abcde".equalsIgnoreCase(code)) {
            // 3、检查 用户名是否可用
            if (userService.existsUsername(username)) {
                System.out.println("用户名[" + username + "]已存在");
                // 跳回注册页面
                req.getRequestDispatcher("/pages/user/regist.html").forward(req, resp);
            } else {
                // 可用
                // 调用 Sservice 保存到数据库
                userService.registUser(new User(null,username,password,email));

                // 跳到注册成功页面 regist_success.html
                req.getRequestDispatcher("/pages/user/regist_success.html").forward(req, resp);
            }
        } else {
            System.out.println("验证码[" + code + "]错误");
            req.getRequestDispatcher("/pages/user/regist.html").forward(req, resp);
        }


    }
}

7.2、IDEA 中 Debug 调试的使用

7.2.1、Debug 调试代码,首先需要两个元素:断点 + Debug 启动服务器

1、断点,只需要在代码需要停的行的左边上单击,就可以添加和取消
2、Debug 启动 Tomcat 运行代码:

7.2.2、测试工具栏:

让代码往下执行一行。

可以进入当前方法体内(自己写的代码,非框架源码)

跳出当前方法体外

强制进入当前方法体内

停在光标所在行(相当于临时断点)

7.2.3、变量窗口

变量窗口:它可以查看当前方法范围内所有有效的变量。

7.2.4、方法调用栈窗口

1、方法调用栈可以查看当前线程有哪些方法调用信息
2、下面的调用上一行的方法

其他常用调试相关按钮:

7.3、用户登录功能的实现

7.3.1、图解用户登录

7.3.2、修改 login.html 页面和 login_success.html 页面

1、添加 base 标签

<!--写 base 标签,永远固定相对路径跳转的结果-->
<base href="http://localhost:8080/book/">

2、修改 base 标签对页面中所有相对路径的影响(浏览器 F12,哪个报红,改哪个)

以下是几个修改的示例:
<link type="text/css" rel="stylesheet" href="static/css/style.css" >
<script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>

3、修改 login.html 表单的提交地址和请求方式

7.3.3、LoginServlet 程序

package top.qaqaq.web;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import top.qaqaq.pojo.User;
import top.qaqaq.service.UserService;
import top.qaqaq.service.impl.UserServiceImpl;

import java.io.IOException;

/**
 * @author RichieZhang
 * @create 2022-12-07 上午 11:51
 */
public class LoginServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        super.doPost(req, resp);

        //1. 获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 调用 userService.login() 登录处理业务
        User loginUser = userService.login(new User(null, username, password, null));
        // 如果等于null,说明登录 失败!
        if (loginUser == null){
            // 跳回登录页面
            req.getRequestDispatcher("/pages/user/login.html").forward(req,resp);
        } else {
            // 登录 成功
            // 跳到成功页面Login_success.html
            req.getRequestDispatcher("/pages/user/login_success.html").forward(req,resp);
        }


    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">
    <servlet>
        <servlet-name>RegistServlet</servlet-name>
        <servlet-class>top.qaqaq.web.RegistServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RegistServlet</servlet-name>
        <url-pattern>/registServlet</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>top.qaqaq.web.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/loginServlet</url-pattern>
    </servlet-mapping>
</web-app>

2.项目阶段二:用户注册和登陆的实现。

需求 1:用户注册
需求如下:
1)访问注册页面
2)填写注册信息,提交给服务器
3)服务器应该保存用户
4)当用户已经存在—-提示用户注册 失败,用户名已存在
5)当用户不存在—–注册成功

需求 2:用户登陆
需求如下:
1)访问登陆页面
2)填写用户名密码后提交
3)服务器判断用户是否存在
4)如果登陆失败 —>>>> 返回用户名或者密码错误信息
5)如果登录成功 —>>>> 返回登陆成功 信息

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇