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ù)庫(kù)(DAO層)
- 實(shí)現(xiàn)了登錄功能和注冊(cè)功能(Service層)
- 使用Servlet操作前端表單提供的數(shù)據(jù),進(jìn)行登錄和注冊(cè),以及完成頁(yè)面跳轉(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ù)庫(kù)連接驅(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ù)庫(kù)表和實(shí)體類并導(dǎo)入JDBCTemplate工具類
數(shù)據(jù)庫(kù)表t_user:
這里不介紹如何創(chuàng)建這樣的一個(gè)數(shù)據(jù)庫(kù)了(保證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ù)庫(kù)連接池
JdbcTemplate template = new JdbcTemplate(dataSource);
return template;
}
/**
* 獲取數(shù)據(jù)庫(kù)連接池
* @return
*/
public static DataSource getDataSource(){
return dataSource;
}
/**
* 開(kāi)始線程綁定 +獲取連接
* @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ù)庫(kù)連接至連接池
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層,書(shū)寫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層,書(shū)寫登錄和注冊(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;
}
}
第五步:書(shū)寫Servlet接收頁(yè)面?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來(lái)配置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頁(yè)面
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)單的樣式來(lái)美化表單 */
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)單的樣式來(lái)美化表單 */
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)單的樣式來(lái)美化表單 */
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)單的樣式來(lái)美化表單 */
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)到登錄頁(yè)面
注冊(cè)失敗
注冊(cè)失敗,彈出警告框,并且返回注冊(cè)頁(yè)面
總結(jié)
整體結(jié)構(gòu)圖
忽略我沒(méi)有在博客書(shū)寫的類和html頁(yè)面,它們是我自己測(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)文章
IDEA搭建dubbo項(xiàng)目的過(guò)程及存在的問(wèn)題
這篇文章主要介紹了IDEA搭建dubbo項(xiàng)目及存在的問(wèn)題小結(jié),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
SpringBoot中處理的轉(zhuǎn)發(fā)與重定向方式
這篇文章主要介紹了SpringBoot中處理的轉(zhuǎn)發(fā)與重定向方式,分別就轉(zhuǎn)發(fā)和重定向做了概念解說(shuō),結(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-09
Java 高并發(fā)二:多線程基礎(chǔ)詳細(xì)介紹
本文主要介紹Java 高并發(fā)多線程的知識(shí),這里整理詳細(xì)的資料來(lái)解釋線程的知識(shí),有需要的學(xué)習(xí)高并發(fā)的朋友可以參考下2016-09-09
JDBC數(shù)據(jù)庫(kù)連接過(guò)程及驅(qū)動(dòng)加載與設(shè)計(jì)模式詳解
這篇文章主要介紹了JDBC數(shù)據(jù)庫(kù)連接過(guò)程及驅(qū)動(dòng)加載與設(shè)計(jì)模式詳解,需要的朋友可以參考下2016-10-10

