Java?Web實(shí)戰(zhàn)之使用三層架構(gòu)與Servlet構(gòu)建登錄注冊(cè)模塊
前言導(dǎo)讀
三層架構(gòu):View(視圖層)Service(業(yè)務(wù)層)DAO(持久層)
- 使用了JDBCtemplate技術(shù),封裝了原生的JDBC技術(shù)操作MySQL數(shù)據(jù)庫(DAO層)
- 實(shí)現(xiàn)了登錄功能和注冊(cè)功能(Service層)
- 使用Servlet操作前端表單提供的數(shù)據(jù),進(jìn)行登錄和注冊(cè),以及完成頁面跳轉(zhuǎn)的需求實(shí)現(xiàn)(View層)
第一步:創(chuàng)建JavaWeb項(xiàng)目,在pom.xml中配置相關(guān)依賴
pom.xml
不要把我的項(xiàng)目名也一起復(fù)制了,只復(fù)制依賴<dependency>和插件部分<build>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>maven_9_11</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>maven_9_11 Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <!-- junit單元測(cè)試--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!--MySQL數(shù)據(jù)庫連接驅(qū)動(dòng)jar包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <!-- servlet依賴支持--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--JDBCTemplate依賴支持,因?yàn)镴DBCTemplate是Spring框架封裝的一個(gè)工具類,因此需要導(dǎo)入Spring相關(guān)依賴--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>5.3.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.8.RELEASE</version> </dependency> </dependencies> <build> <!--配置項(xiàng)目名 --> <finalName>web</finalName> <plugins> <!--配置jetty服務(wù)器插件支持--> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.3.14.v20161028</version> </plugin> <!--配置tomcat服務(wù)器插件支持--> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>8080</port> <path>/</path> <uriEncoding>UTF-8</uriEncoding> <server>tomcat7</server> </configuration> </plugin> </plugins> </build> </project>
第二步:創(chuàng)建數(shù)據(jù)庫表和實(shí)體類并導(dǎo)入JDBCTemplate工具類
數(shù)據(jù)庫表t_user:
這里不介紹如何創(chuàng)建這樣的一個(gè)數(shù)據(jù)庫了(保證user_id為主鍵即可)
User實(shí)體類:
package com.csx.entity; import java.io.Serializable; public class User implements Serializable { private Integer userId; private String userName; private String password; public User(){} public User(Integer userId, String userName, String password) { this.userId = userId; this.userName = userName; this.password = password; } @Override public String toString() { return "User{" + "userId=" + userId + ", userName='" + userName + '\'' + ", password='" + password + '\'' + '}'; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } 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; } }
工具類:
package com.csx.util; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.support.TransactionSynchronizationManager; import javax.sql.DataSource; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; public class JDBCUtils { private static DataSource dataSource =null; static{ try ( InputStream is=JDBCUtils.class.getResourceAsStream("/JDBCUtils.properties") ){ Properties p = new Properties(); p.load(is); dataSource = new DriverManagerDataSource(p.getProperty("url"), p.getProperty("username"), p.getProperty("password")); } catch (Exception e) { throw new RuntimeException(e); } } public static JdbcTemplate getJDBCTemplate(){ //創(chuàng)建JDBCTemplate對(duì)象并傳入數(shù)據(jù)庫連接池 JdbcTemplate template = new JdbcTemplate(dataSource); return template; } /** * 獲取數(shù)據(jù)庫連接池 * @return */ public static DataSource getDataSource(){ return dataSource; } /** * 開始線程綁定 +獲取連接 * @return */ public static Connection startTransaction(){ if (!TransactionSynchronizationManager.isSynchronizationActive()){ TransactionSynchronizationManager.initSynchronization(); } Connection connection =DataSourceUtils.getConnection(dataSource); try { connection.setAutoCommit(false); } catch (SQLException e) { throw new RuntimeException(e); } return connection; } /** * 提交事務(wù) * @param conn */ public static void commit(Connection conn){ try { conn.commit(); } catch (SQLException e) { throw new RuntimeException(e); }finally { clear(conn); } } /** * 回滾事務(wù) * @param conn */ public static void rollback(Connection conn){ try { conn.rollback(); } catch (SQLException e) { throw new RuntimeException(e); }finally { clear(conn); } } /** * 解除線程綁定+釋放資源+歸還連接到線程池 * @param conn */ public static void clear(Connection conn){ //清除線程綁定的資源 TransactionSynchronizationManager.clear(); TransactionSynchronizationManager.unbindResourceIfPossible(dataSource); //歸還數(shù)據(jù)庫連接至連接池 if (conn!=null){//非空判斷,判斷為空再歸還 DataSourceUtils.releaseConnection(conn,dataSource); } } }
在resources資源目錄下創(chuàng)建JDBCUtils.properties目錄
JDBCUtils.properties
url=jdbc:mysql://localhost:3306/csx_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimeZone=Asia/shanghai username=root password=root
第三步:創(chuàng)建DAO層,書寫SQL支持
UserDao接口:
package com.csx.dao; import com.csx.entity.User; public interface UserDao { /** * 根據(jù)用戶名和密碼指定用戶是否存在 * @param userName * @return */ public User selectUserByUserName(String userName,String password); /** * 新增用戶信息 * @param user * @return */ public int insertUser(User user); }
UserDaoImpl實(shí)現(xiàn)類:
package com.csx.dao.impl; import com.csx.dao.UserDao; import com.csx.entity.User; import com.csx.service.UserService; import com.csx.util.JDBCUtils; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import java.util.List; public class UserDaoImpl implements UserDao { private JdbcTemplate template = JDBCUtils.getJDBCTemplate(); /** * 根據(jù)用戶名和密碼指定用戶是否存在 * * @param userName * @param password * @return */ @Override public User selectUserByUserName(String userName, String password) { String sql="select * from t_user where user_name=? and password=? "; List<User> list = template.query(sql, new BeanPropertyRowMapper<>(User.class), userName, password); return list.isEmpty()?null:list.get(0); } /** * 新增用戶信息 * * @param user * @return */ @Override public int insertUser(User user) { String sql="insert into t_user(user_name,password) values(?,?)"; return template.update(sql, user.getUserName(), user.getPassword()); } }
第四步:創(chuàng)建Service層,書寫登錄和注冊(cè)邏輯
UserService接口:
package com.csx.service; public interface UserService { /** * 用戶登錄功能 * @param username * @param password * @return */ public boolean login(String username,String password); /** * 用戶注冊(cè)功能 * @return */ public boolean register(String username,String password); }
UserServiceImpl實(shí)現(xiàn)類:
package com.csx.service.impl; import com.csx.dao.UserDao; import com.csx.dao.impl.UserDaoImpl; import com.csx.entity.User; import com.csx.service.UserService; import com.csx.util.JDBCUtils; import java.sql.Connection; public class UserServiceImpl implements UserService { private UserDao userDao =new UserDaoImpl(); /** * 用戶登錄功能 * * @param username * @param password * @return */ @Override public boolean login(String username, String password) { boolean boo =false; Connection conn =null; try{ conn= JDBCUtils.startTransaction(); //業(yè)務(wù)功能 User user = userDao.selectUserByUserName(username,password); //判斷用戶名是否存在 if (user!=null){ //判斷密碼是否正確 if (user.getPassword().equals(password)){ boo=true; }else { throw new RuntimeException("密碼錯(cuò)誤!"); } }else { throw new RuntimeException("用戶不存在!"); } JDBCUtils.commit(conn); }catch (Exception e){ JDBCUtils.rollback(conn); throw new RuntimeException(e); } return boo; } /** * 用戶注冊(cè)功能 * * @param username * @param password * @return */ @Override public boolean register(String username, String password) { boolean boo=false; Connection conn=null; try { conn = JDBCUtils.startTransaction(); //業(yè)務(wù)功能 User u = userDao.selectUserByUserName(username,password); if (u == null) { User user = new User(null, username, password); userDao.insertUser(user); boo = true; } else { throw new RuntimeException("用戶名重復(fù),注冊(cè)失敗!"); } JDBCUtils.commit(conn); }catch (Exception e){ JDBCUtils.rollback(conn); throw new RuntimeException(e); } return boo; } }
第五步:書寫Servlet接收頁面?zhèn)魅氲臄?shù)據(jù),并響應(yīng)
LoginServlet:
package com.csx.servlet; import com.csx.service.UserService; import com.csx.service.impl.UserServiceImpl; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/login") public class LoginServlet extends HttpServlet { private UserService userService =new UserServiceImpl(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("username"); String pwd =request.getParameter("password"); try { boolean login = userService.login(name, pwd); if (login){ System.out.println("登錄成功!"); response.sendRedirect("login_success.html"); }else { } } catch (Exception e) { System.out.println("登錄失敗"); response.sendRedirect("login_failed.html"); } } }
RegisterServlet:
package com.csx.servlet; import com.csx.service.UserService; import com.csx.service.impl.UserServiceImpl; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/register") public class RegisterServlet extends HttpServlet { private UserService userService =new UserServiceImpl(); @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("username"); String pwd =request.getParameter("password"); try { boolean login = userService.register(name, pwd); if (login){ System.out.println("注冊(cè)成功!"); // response.sendRedirect("register_success.html"); response.sendRedirect("register_success.html"); } } catch (Exception e) { System.out.println("注冊(cè)失敗!"); response.sendRedirect("register_failed.html"); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } }
web.xml配置
創(chuàng)建一個(gè)JavaWeb項(xiàng)目,想要使用注解@WebServlet來配置Servlet路徑映射,需要將webapp目錄下的WBE-INF目錄下的web.xml中配置3.0 以上的配置頭,例如:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> </web-app>
第六步:在webapp目錄下創(chuàng)建HTML頁面
login.html:
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login Form</title> <style> /* 簡(jiǎn)單的樣式來美化表單 */ body { font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f0f0; } .login-form { padding: 20px; background: white; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); } .login-form h2 { margin-bottom: 20px; } .login-form input[type="text"], .login-form input[type="password"] { width: calc(100% - 22px); padding: 10px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 4px; } .login-form input[type="submit"] { background-color: #ff0000; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; } .login-form input[type="submit"]:hover { background-color: #0056b3; } </style> </head> <body> <div class="login-form"> <h2>Login</h2> <form action="/login" method="post"> <label for="username">Username:</label> <input type="text" id="username" name="username" required> <label for="password">Password:</label> <input type="password" id="password" name="password" required> <input type="submit" value="Login"> </form> </div> </body> </html>
login_success.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>登錄成功!</h1> </body> <script>alert('登錄成功!')</script> </html>
login_failed:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>登錄失敗</h1> </body> <script> alert('登錄失敗') </script> </html>
register.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Registration Form</title> <style> /* 簡(jiǎn)單的樣式來美化表單 */ body { font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f0f0; } .registration-form { padding: 20px; background: white; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); } .registration-form h2 { margin-bottom: 20px; } .registration-form input[type="text"], .registration-form input[type="password"] { width: calc(100% - 22px); padding: 10px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 4px; } .registration-form input[type="submit"] { background-color: #28a745; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; } .registration-form input[type="submit"]:hover { background-color: #218838; } </style> </head> <body> <div class="registration-form"> <h2>Registration</h2> <form action="/register" method="post"> <label for="username">Username:</label> <input type="text" id="username" name="username" required> <label for="password">Password:</label> <input type="password" id="password" name="password" required> <input type="submit" value="Register"> </form> </div> </body> </html>
register_success:
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login Form</title> <style> /* 簡(jiǎn)單的樣式來美化表單 */ body { font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f0f0; } .login-form { padding: 20px; background: white; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); } .login-form h2 { margin-bottom: 20px; } .login-form input[type="text"], .login-form input[type="password"] { width: calc(100% - 22px); padding: 10px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 4px; } .login-form input[type="submit"] { background-color: #ff0000; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; } .login-form input[type="submit"]:hover { background-color: #0056b3; } </style> </head> <body> <div class="login-form"> <h2>Login</h2> <form action="/login" method="post"> <label for="username">Username:</label> <input type="text" id="username" name="username" required> <label for="password">Password:</label> <input type="password" id="password" name="password" required> <input type="submit" value="Login"> </form> </div> </body> <script> alert(' 注冊(cè)成功,請(qǐng)登錄!'); </script> </html>
register_failed:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Registration Form</title> <style> /* 簡(jiǎn)單的樣式來美化表單 */ body { font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f0f0; } .registration-form { padding: 20px; background: white; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); } .registration-form h2 { margin-bottom: 20px; } .registration-form input[type="text"], .registration-form input[type="password"] { width: calc(100% - 22px); padding: 10px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 4px; } .registration-form input[type="submit"] { background-color: #28a745; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; } .registration-form input[type="submit"]:hover { background-color: #218838; } </style> </head> <body> <div class="registration-form"> <h2>Registration</h2> <form action="/register" method="post"> <label for="username">Username:</label> <input type="text" id="username" name="username" required> <label for="password">Password:</label> <input type="password" id="password" name="password" required> <input type="submit" value="Register"> </form> </div> </body> <script> alert("注冊(cè)失敗!") </script> </html>
第七步:項(xiàng)目啟動(dòng)與測(cè)試
項(xiàng)目啟動(dòng),參考我的這篇博客:JavaWeb項(xiàng)目啟動(dòng)
運(yùn)行測(cè)試
登錄
登錄失敗
登錄成功
注冊(cè)
注冊(cè)成功
注冊(cè)成功會(huì)直接跳轉(zhuǎn)到登錄頁面
注冊(cè)失敗
注冊(cè)失敗,彈出警告框,并且返回注冊(cè)頁面
總結(jié)
整體結(jié)構(gòu)圖
忽略我沒有在博客書寫的類和html頁面,它們是我自己測(cè)試時(shí)使用的,不影響整體功能執(zhí)行
基于三層架構(gòu)和Servlet進(jìn)行登錄和注冊(cè)功能的實(shí)現(xiàn)項(xiàng)目
總結(jié)
到此這篇關(guān)于Java Web實(shí)戰(zhàn)之使用三層架構(gòu)與Servlet構(gòu)建登錄注冊(cè)模塊的文章就介紹到這了,更多相關(guān)Java Web構(gòu)建登錄注冊(cè)模塊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中處理的轉(zhuǎn)發(fā)與重定向方式
這篇文章主要介紹了SpringBoot中處理的轉(zhuǎn)發(fā)與重定向方式,分別就轉(zhuǎn)發(fā)和重定向做了概念解說,結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11基于ZooKeeper實(shí)現(xiàn)隊(duì)列源碼
這篇文章主要介紹了基于ZooKeeper實(shí)現(xiàn)隊(duì)列源碼的相關(guān)內(nèi)容,包括其實(shí)現(xiàn)原理和應(yīng)用場(chǎng)景,以及對(duì)隊(duì)列的簡(jiǎn)單介紹,具有一定參考價(jià)值,需要的朋友可以了解下。2017-09-09Java 高并發(fā)二:多線程基礎(chǔ)詳細(xì)介紹
本文主要介紹Java 高并發(fā)多線程的知識(shí),這里整理詳細(xì)的資料來解釋線程的知識(shí),有需要的學(xué)習(xí)高并發(fā)的朋友可以參考下2016-09-09JDBC數(shù)據(jù)庫連接過程及驅(qū)動(dòng)加載與設(shè)計(jì)模式詳解
這篇文章主要介紹了JDBC數(shù)據(jù)庫連接過程及驅(qū)動(dòng)加載與設(shè)計(jì)模式詳解,需要的朋友可以參考下2016-10-10