1、项目第二阶段——用户注册和登陆

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

1、JavaEE项目的三层架构

image.png

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

web 层 com.my.book.web/servlet/controller

service 层 com.my.book.service Service接口包

com.my.book.service.impl Service 接口实现类

dao 持久层 com.my.book.dao Dao 接口包

com.my.book.dao.impl Dao 接口实现类

实体 bean 对象 com.my.book.pojo/entity/domain/bean JavaBean 类

测试包 com.my.book.test/junit

工具类 com.my.book.util

搭建书城项目开发环境:

image.png

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

数据库

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,123,adminbook@mybookqq.com);
select * from t_user;

image.png

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

public class User {
​
    private Integer id;
    private  String username;
    private String password;
    private  String 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;
    }
​
    public User(Integer id, String username, String password, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.email = email;
    }
​
    public User() {
    }
}
​

4、编写工具类 JdbcUtils

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

image.png

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

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

4.3、编写 JdbcUtils工具类:

public class JdbcUtils {
    private static DruidDataSource dataSource;
    static {
        try {
            Properties properties = new Properties();
            // 读取 jdbc.properties 属性配置文件
            InputStream inputStream =
            JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            // 从流中加载数据
            properties.load(inputStream);
            // 创建 数据库连接 池
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
            } catch (Exception e) {
                e.printStackTrace();
        }
    }
        /**
        * 获取数据库连接池中的连接
        * 如果返回 null,说明获取连接失败<br/>有值就是获取连接成功
        */
    public static Connection getConnection(){
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }
    /**
    * 关闭连接,放回数据库连接池
    * @param conn
    */
    public static void close(Connection conn){
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
}

4.4、JdbcUtils 测试

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);//记得使用后要关闭
        }
    }
}

image.png

这样表示连接成功

5、编写 BaseDao

5.1、导包

使用前记得导DBUtils 的jar包

5.2、编写 BaseDao:

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 (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(conn);
        }
        return null;
    }
​
​

6、编写 UserDao 和测试

6.1、UserDao 接口:

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);
​
}

6.2、UserDaoImpl 实现类

public class UserDaoImpl extends BaseDao implements UserDao {
​
    //查询根据username
    @Override
    public User queryUserByUsername(String username) {
        String sql = "select 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());
    }
}

6.3UserDao 测试:

public class UserDaoTest {

    UserDao userDao=new UserDaoImpl();
    @Test
    public void queryUserByUsername() {

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

    }

    @Test
    public void saveUser() {
        System.out.println();
    }

    @Test
    public void queryUserByUsernameAndPassword() {
       if(userDao.queryUserByUsernameAndPassword("admin","123")==null){
           System.out.println("用户密码错误,登录失败");
        }else{
           System.out.println("查询成功");
       }
    }

7、编写 UserService 和测

7.1UserService 接口

public interface UserService {
    //注册用户
    public void registUser(User user);
    //登录
    public User login(User user);

    //检查用户是否可用
    //true表示用户名存在
    public boolean existsUsername(String username);
}

7.2、UserServiceImpl 实现类:

public class UserServiceImpl implements UserService{

  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;
    }
}

7.3、UserService 测试:

public class UserServiceTest {

    UserService userService=new UserServiceImpl();
    @Test
    public void registUser() {
        userService.registUser(new User(null,"pjh","666","pjh@qq.com"));
        userService.registUser(new User(null,"zjt","555","zjt@qq.com"));
    }

    @Test
    public void login() {
        System.out.println(userService.login(new User(null,"pjh","666","pjh@qq.com")));
    }

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

8、编写 web 层

8.1、实现用户注册的功能

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3qk9sxKp-1655786599875)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/923c4af974284258b04bfde5f0bb7bb5~tplv-k3u1fbpfcp-watermark.image?)]

8.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、修改注册表单的提交地址和请求方式

在这里插入图片描述

8.1.3、编写 RegistServlet 程序

public class RegistServlet extends HttpServlet {
    private UserService userService=new UserServiceImpl();



    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String email = req.getParameter("email");
        String code = req.getParameter("code");
    //要求验证码为ABCD
        if("abcd".equalsIgnoreCase(code)){
            //正确
            //检查用户名是否可用
            if(userService.existsUsername(username)){
                //不可用
                System.out.println("用户名["+username+"]已存在");
                // 跳回注册页面
                req.getRequestDispatcher("/pages/user/regist.html").forward(req,resp);
            }else{
                //可用,调用service保存到数据库
                userService.registUser(new User(null,username,password,email));
                //  跳转到注册成功register——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);
        }

    }
}

8.2、IDEA 中 Debug 调试的使

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

1、断点,只需要在代码需要停的行的左边上单击,就可以添加和取消

2、Debug 启动 Tomcat

8.2.2、测试工具栏:

image.png

8.2.3、其他常用调试相关按钮:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RmvlwHn4-1655786599880)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/90cbef1cc21440d298e409ba1d5e4beb~tplv-k3u1fbpfcp-watermark.image?)]

8.3、用户登录功能的实现:

8.3.1、图解用户登录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y1WrD7Rn-1655786599882)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f59a48a310d8419ba6f25d47783f2c3c~tplv-k3u1fbpfcp-watermark.image?)]

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

1、添加 base 标

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

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

image.png

8.3.3、LoginServlet 程序
public class LoginServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //  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);
        }
    }
}

总结

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

需求 1:用户注册

需求如下:

1)访问注册页面

2)填写注册信息,提交给服务器

3)服务器应该保存用户

4)当用户已经存在----提示用户注册 失败,用户名已存在

5)当用户不存在-----注册成功

需求 2:用户登陆

需求如下:

1)访问登陆页面

2)填写用户名密码后提交

3)服务器判断用户是否存在

4)如果登陆失败 —>>>> 返回用户名或者密码错误信息

5)如果登录成功 —>>>>

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值