書城第二階段——用戶注冊和登陸
一、實作的功能
1、登錄頁面

2、注冊頁面

二、JavaEE 專案的三層架構

分層的目的是為了解耦,解耦就是為了降低代碼的耦合度,方便專案后期的維護和升級,
1、idea中提供書城專案需要的包結構
web層 com.zixue.web/servlet/controller
service層 com.zixue.service service介面包
com.zixue.service.impl service介面實作類
dao持久層 com.zixue.dao dao介面包
com.zixue.dao.impl dao介面實作類
物體bean物件 com.zixue.pojo/entity/domain/bean JavaBean類
測驗包 com.zixue.test/junit
工具類 com.zixue.utils

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','admin','[email protected]'); SELECT * FROM t_user;

3、撰寫資料庫表對應的 JavaBean 物件

User.java如下:
package com.zixue.pojo; /** * @author Mr Guo * @create 2020-11-11 10:03 */ 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 + '\'' + '}'; } }
4、撰寫工具類 JdbcUtils
① 匯入資料庫和資料庫連接池需要的jar包

② 在 src 原始碼目錄下撰寫 jdbc.properties 屬性組態檔

③ 撰寫 JdbcUtils 工具類
package com.zixue.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.Map; import java.util.Properties; /** * @author Mr Guo * @create 2020-11-11 10:26 */ 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(); } } /** * 獲取資料庫連接池的連接 * @return 如果回傳null,說明獲取連接失敗;有值就是獲取成功 */ public static Connection getConnection(){ Connection conn = null; try { conn = dataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * 關閉連接,放回資料庫連接池 * @param connection */ public static void close(Connection connection){ if (connection != null){ try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
④ JdbcUtils測驗類
package com.zixue.test; import com.zixue.utils.JdbcUtils; import org.junit.Test; import java.sql.Connection; /** * @author Mr Guo * @create 2020-11-11 10:46 */ public class JdbcUtilsTest { @Test public void testJdbcUtils(){ for (int i = 0; i < 100; i++) { Connection conn = JdbcUtils.getConnection(); System.out.println(conn); JdbcUtils.close(conn); } } }
效果如下:

5、撰寫 BaseDao
① 匯入DBUtils的jar包

②撰寫BaseDao
package com.zixue.dao.impl; import com.zixue.utils.JdbcUtils; 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 java.sql.Connection; import java.sql.SQLException; import java.util.List; /** * @author Mr Guo * @create 2020-11-11 11:01 */ public abstract class BaseDao { //使用DbUtils來操作資料庫 private QueryRunner queryRunner = new QueryRunner(); /** * update()方法用來執行:insert、delete、update陳述句 * @param sql 執行的sql陳述句 * @param args sql對應的引數 * @return 如果回傳-1,說明執行失敗<br/>其它表示受影響的行數 */ public int update(String sql, Object ... args){ Connection conn = JdbcUtils.getConnection(); try { return queryRunner.update(conn, sql, args); } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.close(conn); } return -1; } /** * 查詢回傳一個JavaBean物件 * @param type 回傳物件型別 * @param sql 執行的sql陳述句 * @param args sql對應的引數 * @param <T> 回傳的型別的泛型 * @return 如果回傳null,說明查詢失敗<br/>其它表示查詢到的物件 */ public <T> T queryForOne(Class<T> type, String sql, Object ... args){ Connection conn = JdbcUtils.getConnection(); try { return queryRunner.query(conn, sql, new BeanHandler<T>(type), args); } catch (SQLException e) { e.printStackTrace(); }finally { JdbcUtils.close(conn); } return null; } /** * 查詢回傳多個JavaBean物件的集合 * @param type 回傳物件型別 * @param sql 執行的sql陳述句 * @param args sql對應的引數 * @param <T> 回傳的型別的泛型 * @return 如果回傳null,說明查詢失敗<br/>其它表示查詢到的物件的集合 */ public <T> List<T> queryForList(Class<T> type, String sql, Object ... args){ Connection conn = JdbcUtils.getConnection(); try { return queryRunner.query(conn, sql, new BeanListHandler<T>(type), args); } catch (SQLException e) { e.printStackTrace(); }finally { JdbcUtils.close(conn); } return null; } /** * 執行回傳一行一列的sql陳述句 * @param sql 執行的sql陳述句 * @param args sql對應的引數 * @return 如果回傳nul,查詢失敗<br/>其它查詢成功 */ public Object queryForSingleOne(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; } }
6、撰寫 UserDao 和測驗
UserDao介面:
package com.zixue.dao; import com.zixue.pojo.User; /** * @author Mr Guo * @create 2020-11-11 11:31 */ 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表示操作失敗,其它是受影響的行數 */ public int saveUser(User user); }
UserDaoImpl實作類:
package com.zixue.dao.impl; import com.zixue.dao.UserDao; import com.zixue.pojo.User; /** * @author Mr Guo * @create 2020-11-11 11:37 */ 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()); } }
UserDaoTest測驗類:
package com.zixue.test; import com.sun.media.sound.SoftTuning; import com.zixue.dao.UserDao; import com.zixue.dao.impl.UserDaoImpl; import com.zixue.pojo.User; import org.junit.Test; import static org.junit.Assert.*; /** * @author Mr Guo * @create 2020-11-11 11:44 */ public class UserDaoTest { private UserDao userDao = new UserDaoImpl(); @Test public void queryUserByUsername() { if (userDao.queryUserByUsername("admin") == null){ System.out.println("用戶名可用"); }else{ System.out.println("用戶名已存在"); } } @Test public void queryUserByUsernameAndPassword() { if (userDao.queryUserByUsernameAndPassword("admin", "admin") == null){ System.out.println("用戶名或密碼錯誤"); }else{ System.out.println("登錄成功"); } } @Test public void saveUser() { System.out.println(userDao.saveUser(new User(null, "wzg", "123456", "[email protected]"))); } }
7、撰寫 UserService 和測驗
UserService介面:
package com.zixue.service; import com.zixue.pojo.User; /** * @author Mr Guo * @create 2020-11-11 12:02 */ 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 com.zixue.service.impl; import com.zixue.dao.UserDao; import com.zixue.dao.impl.UserDaoImpl; import com.zixue.pojo.User; import com.zixue.service.UserService; /** * @author Mr Guo * @create 2020-11-11 12:07 */ 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){ return false; } return true; } }
UserServiceTest測驗類:
package com.zixue.test; import com.zixue.pojo.User; import com.zixue.service.UserService; import com.zixue.service.impl.UserServiceImpl; import org.junit.Test; import static org.junit.Assert.*; /** * @author Mr Guo * @create 2020-11-11 12:13 */ public class UserServiceTest { UserService userService = new UserServiceImpl(); @Test public void registUser() { userService.registUser(new User(null, "bbj168", "666666", "[email protected]")); } @Test public void login() { System.out.println(userService.login(new User(null, "admin", "admin", "[email protected]"))); } @Test public void existsUsername() { if(userService.existsUsername("admin444")){ System.out.println("用戶名已存在"); }else{ System.out.println("用戶名可用"); } } }
8、撰寫 web 層
實作用戶注冊的功能:
① 圖解用戶注冊的流程

② 修改 regist.html 和 regist_success.html 頁面
給regist.html頁面添加base標簽:



修改注冊表單的提交地址和請求方式:
給regist_success.html頁面添加base標簽:

修改 base 標簽對頁面中所有相對路徑的影響(瀏覽器 F12,哪個報紅,改哪個):


③ 撰寫 RegistServlet 程式
package com.zixue.web; import com.zixue.pojo.User; import com.zixue.service.UserService; import com.zixue.service.impl.UserServiceImpl; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author Mr Guo * @create 2020-11-11 13:25 */ public class RegistServlet extends HttpServlet { 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"); String email = req.getParameter("email"); String code = req.getParameter("code"); //2.檢查驗證碼是否正確 === 寫死:abcde if ("abcde".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)); //跳轉到注冊成功頁面 req.getRequestDispatcher("/pages/user/regist_success.html").forward(req, resp); } }else{ System.out.println("驗證碼["+ code +"]錯誤"); //跳回注冊頁面 req.getRequestDispatcher("/pages/user/regist.html").forward(req, resp); } }
9、IDEA 中 Debug 除錯的使用
9.1、Debug 除錯代碼,首先需要兩個元素:斷點 + Debug 啟動服務器
① 斷點,只需要在代碼需要停的行的左邊上單擊,就可以添加和取消
② Debug 啟動 Tomcat 運行代碼:

9.2、測驗工具列:

:讓代碼向下執行一行,
:可以進入當前方法體內(自己寫的代碼,非框架原始碼)
:跳到當前方法體外,
:強制進入當前方法體內
:停到當前游標所在行,相當于臨時斷點,
9.3、變數視窗
變數視窗:它可以查看當前方法范圍內所有有效的變數,
9.4、方法呼叫堆疊視窗
①方法呼叫堆疊可以查看當前執行緒有哪些方法呼叫資訊
②下面的呼叫上一行的方法

9.5、其他常用除錯相關按鈕:

10、用戶登錄功能的實作
10.1、圖解用戶登錄

10.2、修改 login.html 頁面和 login_success.html 頁面
10.2.1、添加base標簽

10.2.2、修改 base 標簽對頁面中所有相對路徑的影響(瀏覽器 F12,哪個報紅,改哪個)


10.2.3、修改 login.html 表單的提交地址和請求方式

10.3、撰寫LoginServlet程式
package com.zixue.web; import com.zixue.pojo.User; import com.zixue.service.UserService; import com.zixue.service.impl.UserServiceImpl; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author Mr Guo * @create 2020-11-11 15:23 */ 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"); //2.呼叫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{ //登錄成功,跳到登錄成功頁面 req.getRequestDispatcher("/pages/user/login_success.html").forward(req, resp); } } }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/210986.html
標籤:Java
