主頁 > 前端設計 > 基于三層架構+java+jsp+servlet+jQuery+bootstrap——web資源庫專案(注冊功能demo)

基于三層架構+java+jsp+servlet+jQuery+bootstrap——web資源庫專案(注冊功能demo)

2021-09-24 16:33:02 前端設計

文章目錄

  • 專案需求分析
  • 概要設計
  • 三層架構搭建專案結構
    • 三層架構簡介
    • 后端注冊功能實作
      • eclipse配置
      • 創建web專案
      • 用戶表設計與創建資料庫和表
      • 創建用戶物體類
      • 控制層(controller)實作
      • 業務邏輯層(service)實作
      • 資料訪問層(dao)實作
      • 使用jdbc工具類和匯入mysql驅動包
    • 前端注冊功能實作
      • Bootstrap框架下載與使用
      • 前端頁面結構
      • 前端頁面表單驗證
    • 注冊功能綜合測驗

專案需求分析

(1)用戶注冊與登錄模塊:未注冊用戶可以通過注冊用戶資訊,登錄到資源交流平臺,達到相互交流學習的目的,已有賬號密碼的學生或老師可以直接登錄課程資源庫系統,進行資源瀏覽,

  • 學生用戶成功登陸Web資源庫后可以上傳學生資源,收藏和下載系統內所有資源,發布學生帖子和評論所有帖子,關注其他用戶,
  • 教師用戶成功登陸Web資源庫后可以上傳教師資源,收藏和下載系統內所有資源,發布教師帖子和評論所有帖子,關注其他用戶,
  • 管理員用戶具有用戶資訊管理、學生資訊批量匯入、資源管理、交流區管理的權限,

(2)資源瀏覽與下載模塊:用戶可以直接在web資源的首頁查看到所有發布的檔案和圖片,對于共享的資源檔案可以直接下載保存,
(3)資源上傳模塊:用戶可以直接上傳資源檔案,上傳檔案時需要錄入資源的名字,類別,等級和描述,
(4)學習推薦模塊:隨著Web資源庫的內容增加,用戶需要從大量資源檔案中獲取自己想要的資源,學習推薦模塊,是對用戶實施的一個推薦功能,用戶在推薦的目錄檔案中也可以選擇關注自己感興趣的用戶,一起參與討論,
(5)用戶交流區模塊:在論壇中,學生用戶可以直接發貼提問,回復和評論所有帖子,教師用戶可以發帖回答問題,回復和評論所有帖子,幫助學生解決學習上的疑惑,
(6)后臺管理模塊:管理員進行Web資源庫的后臺管理,管理員可以在此模塊管理用戶賬號,進行增刪查改的操作,并且批量匯入學生資訊,同時也要講系統內的資源構件分門別類,洗掉出錯的構件,將優質資源標“優”,將優質的資源摘錄到Web資源庫首頁并且置頂,將交流區的優質回復摘錄到Web資源庫首頁置頂的用戶評論區,對交流區內違規操作的用戶進行禁言處理,

概要設計

經過需求分析后,按照系統實作的功能進行模塊劃分,將相關功能的實作劃分到同一模塊中,
(1)按照管理系統的要求將模塊劃分為六大部分,用戶注冊與登錄模塊,資源瀏覽與下載模塊,資源上傳模塊和推薦學習模塊,用戶交流區模塊,后臺管理模塊,
在這里插入圖片描述

(2)將六個模塊細化

用戶注冊與登錄-注冊注冊成為資源庫的一個用戶,可以共享web資源內容
用戶注冊與登錄-登錄學生用戶、教師用戶和管理員用戶登錄賬號,分別擁有不同的權限
后臺管理-用戶管理對用戶資訊進行管理,批量匯入學生,增刪查改
后臺管理-資源管理對資源資訊進行管理,洗掉出錯的構件,將優質資源標“優”
后臺管理-論壇管理對發布的帖子進行管理,對交流區內違規操作的用戶進行禁言處理
資源瀏覽與下載-資源中心包含所有用戶已經上傳的資源資訊,可以讓用戶瀏覽
資源瀏覽與下載-資源下載將感興趣的內容進行資源下載保存到本地
資源上傳-上傳教師可以上傳教師資源檔案,學生可以上傳個人檔案
推薦學習-資源置頂推薦系統將推薦的資源置頂,讓用戶方便搜索到想要的內容
用戶交流區-論壇帖子匯總了所有學生和教師的帖子,方便大家在論壇內展開討論
用戶交流區-我要發帖學生和教師可以發布個人的帖子,評論他人的帖子,關注其他用戶

三層架構搭建專案結構

三層架構簡介

首先來說,三層架構與MVC的目標一致:都是為了解耦和、提高代碼復用,MVC是一種設計模式,而三層架構是一種軟體架構,

三層架構分為:控制層(controller層即servlet)、業務邏輯層(service層)、資料訪問層(dao層) ,再加上物體類(Model)和表現層(web層即jsp)

物體類(Model)

在Java中,往往將其稱為Entity物體類,資料庫中用于存放資料,而我們通常選擇會用一個專門的類來抽象出資料表的結構,類的屬性就一對一的對應這表的屬性,

Model物體類需要被dao層,service層和web層參考,

資料訪問層(dao)

主要是存放對資料類的訪問,即對資料庫的添加、洗掉、修改、更新等基本操作

dao就是根據業務需求,構造SQL陳述句,構造引數,呼叫幫助類,獲取結果,dao層被service層呼叫

業務邏輯層(service)

service層好比是橋梁,將web表示層與dao資料訪問層之間聯系起來,所要負責的,就是處理涉及業務邏輯相關的問題,比如在呼叫訪問資料庫之前,先處理資料、判斷資料,

后端注冊功能實作

eclipse配置

雙擊eclipse,選擇自己的作業空間
在這里插入圖片描述

設定作業空間的字符編碼

在這里插入圖片描述
在這里插入圖片描述

設定JSP的字符編碼

在這里插入圖片描述

配置tomcat服務器

在這里插入圖片描述
在這里插入圖片描述

創建web專案

按Ctrl+N輸入dynamic web project

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

用戶表設計與創建資料庫和表

用戶表設計

學生,教師都有個人資訊(姓名,性別,年齡,生日),但教師不包含班級欄位,但它們都有賬號資訊以及身份標識,管理員只有賬號資訊,身份標識,

注冊時一般只需提供賬號,密碼,身份標識,如果是學生還需要提供班級,而個人資訊是通過登錄后通過個人資訊修改的,

為了簡單起見,可以把學生,教師,管理員放在一張表中,共有的欄位設定為不可為空(賬號,密碼,身份標識),不共有的設定可以為空,表如下

user表

欄位名稱型別約束描述
user_idvarchar(20)NOT NULL PRIMARY KEY用戶ID
user_passwordvarchar(20)NOT NULL用戶密碼
user_namevarchar(20)NULL用戶姓名(默認為空)
user_sexvarchar(10)NULL用戶性別(默認為空)
user_birthdaydate()NULL用戶生日(默認為空)
user_classvarchar(20)NULL班級
user_levelvarchar(20)NOT NULL用戶標識

使用mysql命令列創建資料庫和表

CREATE DATABASE web_resource;
CREATE TABLE `user` (
  `user_id` varchar(20) NOT NULL,
  `user_password` varchar(20) NOT NULL,
   `user_name` varchar(20)  NULL,
  `user_sex` varchar(10) DEFAULT NULL,
  `user_birthday` date DEFAULT NULL,
  `user_class` varchar(20) DEFAULT NULL,
  `user_level` varchar(20) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

創建用戶物體類

滑鼠左鍵java檔案夾按Ctrl+N輸入class

在這里插入圖片描述

輸入存放物體類的包名和類名后finish

在這里插入圖片描述

user.java代碼如下

public class User {
    private String userId;
    private String userPassword;
    private String userName;
    private String userSex;
    private String userBirthday;
    private String userClass;
    private String userLevel;
	public User() {
		super();
	}
	public User(String userId, String userPassword, String userName, String userSex, String userBirthday,
			String userClass, String userLevel) {
		super();
		this.userId = userId;
		this.userPassword = userPassword;
		this.userName = userName;
		this.userSex = userSex;
		this.userBirthday = userBirthday;
		this.userClass = userClass;
		this.userLevel = userLevel;
	}
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getUserPassword() {
		return userPassword;
	}
	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserSex() {
		return userSex;
	}
	public void setUserSex(String userSex) {
		this.userSex = userSex;
	}
	public String getUserBirthday() {
		return userBirthday;
	}
	public void setUserBirthday(String userBirthday) {
		this.userBirthday = userBirthday;
	}
	public String getUserClass() {
		return userClass;
	}
	public void setUserClass(String userClass) {
		this.userClass = userClass;
	}
	public String getUserLevel() {
		return userLevel;
	}
	public void setUserLevel(String userLevel) {
		this.userLevel = userLevel;
	}
	@Override
	public String toString() {
		return "User [userId=" + userId + ", userPassword=" + userPassword + ", userName=" + userName + ", userSex="
				+ userSex + ", userBirthday=" + userBirthday + ", userClass=" + userClass + ", userLevel=" + userLevel
				+ "]";
	}
}

控制層(controller)實作

滑鼠左鍵java檔案夾按Ctrl+N輸入servlet

輸入存放servlet的包名(com.zhuo.controller),由于注冊是和用戶相關的,還可以建一個子目錄user,這樣可以和后面各種型別的servlet進行區分,然后輸入類名后next

在這里插入圖片描述

修改URL映射,這樣瀏覽器可以通過地址欄訪問注冊的servlet

在這里插入圖片描述

RegisterServlet.java代碼如下

public class RegisterServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/* 設定字符編碼,解決中文亂碼問題 */
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		/* 接收客戶端資訊 */
		String userId = request.getParameter("userId");
		String userPassword = request.getParameter("userPassword");
		String userName = request.getParameter("userName");
		String userLevel = request.getParameter("userLevel");
		String userClass = request.getParameter("userClass");
		/* 創建用戶物體,并把請求引數設定為用戶物體成員變數值 */
		User user = new User();
		user.setUserId(userId);
		user.setUserPassword(userPassword);
		user.setUserName(userName);
		user.setUserLevel(userLevel);
		user.setUserClass(userClass);
		// 創建用戶service層介面的實作類物件
		UserServiceImpl userServiceImpl = new UserServiceImpl();
		/* 呼叫業務邏輯方法注冊用戶 */
		int i = 0;
		try {
			i = userServiceImpl.register(user);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		/* 若i>0,則重定向到login.jsp */
		if (i > 0) {
			response.sendRedirect("views/before/login.jsp");
		}
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}
}

RegisterServlet的主要作用就是接受客戶提交的表單(通過注冊頁面提交),然后把引數封裝到物體類中,之后就可以以物體類作用引數呼叫service層業務邏輯處理方法,通過回傳值判斷是否注冊成功

業務邏輯層(service)實作

service層分為介面和介面的實作類,為了要定義介面呢?直接用類不行嗎?

我們知道介面是空實作,具體實作由子類繼承,那么這樣的好處就是當我們擴展業務功能時,只需在介面添加即可,具體的實作交給子類實作,由于介面只包含方法簽名,而不包含復雜的邏輯代碼,很容易就可以看出有什么業務功能

定義介面

滑鼠左鍵java檔案夾按Ctrl+N輸入interface

輸入存放service層的介面包名和介面名后finish

在這里插入圖片描述

在UserService.java中添加一個注冊的抽象方法

	// 注冊用戶
	public int register(User user) throws SQLException;

定義介面的實作類

滑鼠左鍵java檔案夾按Ctrl+N輸入class

輸入存放service層的介面實作類的包名和類名并繼承UserService介面后finish

在這里插入圖片描述

在UserServiceImpl實作類中重寫介面的register方法

      
      /*
	  * 創建用戶dao層介面的實作類,并賦給介面物件變數,
	  *  實作上轉型,也就面向介面編程,而不關心它的 實作類是誰
	  */
		UserDao userDao = new UserDaoImpl();
		@Override
		public int register(User user) throws SQLException {
			//把用戶插入到資料庫中
			int i = userDao.insertUser(user);
			return i;
		}

實作類中重寫的register方法,主要功能是封裝了底層操作(即對資料庫的增刪改查),只提現業務功能(即注冊)

資料訪問層(dao)實作

dao層和service層類似,就不再重復闡述了

定義介面

滑鼠左鍵java檔案夾按Ctrl+N輸入interface

輸入存放dao層介面的包名(com.zhuo.dao)和類名后finish

在UserDao.java中添加一個插入用戶到資料庫抽象方法

	// 把用戶插入到資料庫中
	public int insertUser(User user) throws SQLException;

定義介面的實作類

輸入存放dao層的介面實作類的包名和類名并繼承UserDao介面后finish

在這里插入圖片描述

在UserDaoImpl實作類中重寫介面的insertUser方法

	   //存放查詢資料庫回傳的結果集
		ResultSet resultSet;
		@Override
		public int insertUser(User user) throws SQLException {
			//sql插入陳述句
			String sql = "insert into user (user_id, user_password, user_name, "
					+ "user_sex, user_birthday,  user_class, user_level) "
					+ "values(?,?,?,?,?,?,?);";
			// 呼叫jdbc工具類執行sql陳述句,如果操作成功,i就是操作成功的條數(即i > 0)
			int i = JDBCUtil.executeUpdate(sql, user.getUserId(), 
					user.getUserPassword(), user.getUserName(),
					user.getUserSex(), user.getUserBirthday(), 
					user.getUserClass(), user.getUserLevel());
			return i;
		}

實作類UserDaoImpl重寫了介面的insertUser方法,主要功能是呼叫jdbc工具執行sql插入陳述句添加用戶

使用jdbc工具類和匯入mysql驅動包

創建jdbc工具類

滑鼠左鍵java檔案夾按Ctrl+N輸入class

輸入存放工具類的包名和類名后finish

在這里插入圖片描述

JDBCUtil.java代碼如下

public class JDBCUtil {
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/web_resource?useUnicode=true&characterEncoding=utf-8";
    private static final String USER = "root";
    private static final String PASSWORD = "12345";
    private static Connection ct;
    private static PreparedStatement ps;
    private static ResultSet rs;
    static {
        // 1.加載驅動,只需要加載一次,所以放到靜態代碼塊中
        try {
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    /**
     * 描述:封裝一個方法可以獲得連接,目的可以在其他地方之接呼叫
     */
    public static Connection getConnection() {
        try {

            ct = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ct;
    }
    /**
     * 描述:封裝一個方法可以完成查詢操作
     *
     * @param sql 要查詢的sql陳述句
     * @param obj 占位符的具體內容
     * @return ResultSet 將查詢到的結果回傳
     */
    public static ResultSet executeQuery(String sql, Object... obj) {
        // 1.得到連接
        ct = getConnection();
        // 2.創鍵發送物件
        try {
            ps = ct.prepareStatement(sql);
            // 處理占位符問題
            if (obj != null) {

                for (int i = 0; i < obj.length; i++) {
                    ps.setObject(i + 1, obj[i]);
                }
            }
            rs = ps.executeQuery();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return rs;
    }
    /**
     * 描述:封裝一個方法可以完成DDL,DML操作
     *
     * @param sql 要操作的sql陳述句
     * @param obj 占位符
     * @return
     */
    public static int executeUpdate(String sql, Object... obj) {
        // 1.得到連接
        ct = getConnection();
        // 2.創鍵發送物件
        try {
            ps = ct.prepareStatement(sql);
            // 處理占位符問題
            if (obj != null) {
                for (int i = 0; i < obj.length; i++) {
                    ps.setObject(i + 1, obj[i]);
                }
            }
            int in = ps.executeUpdate();
            close(ct, ps, null);
            return in;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }
    /**
     * 描述:封裝一個關閉資源的方法
     *
     * @param ct 連接物件
     * @param ps 發送sql陳述句物件
     * @param rs 回傳值物件
     */
    public static void close(Connection ct, PreparedStatement ps, ResultSet rs) {

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (ct != null) {
            try {
                ct.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    // 給外部一個訪問ct,和ps的方法
    public static Connection getCt() {
        return ct;
    }
    public static PreparedStatement getPs() {
        return ps;
    }
}

JDBCUtil工具類只需把常量PASSWORD修改為自己的mysql密碼即可

匯入mysql驅動包

要想連接資料庫,需要加載mysql驅動包

jar包下載地址:https://repo1.maven.org/maven2/mysql/mysql-connector-java/

選擇對應自己的mysql版本,下載好之后復制到WEB-INF的lib檔案夾即可

在這里插入圖片描述

至此后臺主要的功能都實作了,等到撰寫前臺代碼時會加些前臺表單驗證的servlet(驗證碼,檢查用戶是否存在),

到目前為止的專案結構如下

在這里插入圖片描述

前端注冊功能實作

前端頁面包含結構(html,jsp),樣式(css即表現),行為(javascript),

Bootstrap框架下載與使用

我們主要的部分是結構(表單)和行為(驗證表單),而樣式不是重點,可以使用一些開源的css框架或者使用自己喜歡的樣式,這些在網上都可以找到,我使用的Bootstrap框架

Bootstrap框架下載

Bootstrap有壓縮版的,也有沒壓縮版的,如果有興趣可以下載沒壓縮版的閱讀原始碼
Bootstrap下載

Bootstrap框架使用

前端代碼一般是放在webapp目錄下,可以在webapp目錄下創建一個views檔案夾,存放前端代碼

左擊webapp按Ctrl+N輸入folder后next

在這里插入圖片描述

輸入檔案夾名views后finish

在這里插入圖片描述

前端分為前臺和后臺,還可以在views檔案下繼續細分為前臺(before檔案夾),后臺(after檔案夾),這樣可以保持專案結構簡潔清晰

由于bootstrap框架,前臺,后臺都會用的到,所以可以在views檔案夾創建一個css子檔案夾存放bootstrap,然后在html檔案中的head標簽內添加參考即可,我的參考如下

<link
	href="${pageContext.request.contextPath}/views/css/bootstrap.min.css"
	rel="stylesheet">

在EL運算式通過page域獲取請求域,然后通過請求域獲取專案名即contextPath,這樣就可以參考到這個檔案

前端頁面結構

注冊頁面主要的結構就是表單,里面包含一些組件(文本框,密碼框,選擇框,提交按鈕)

左擊before檔案夾按Ctrl輸入jsp,創建register.jsp,添加如下代碼

<body class="gray-bg">
	<div class="middle-box text-center loginscreen   animated fadeInDown">
		<div>
			<h3>注冊Resource library+</h3>
			<form class="m-t" role="form"
				action="${pageContext.request.contextPath}/register"
				onsubmit="return checkRegisterForm(this);" method="post">
				<div class="form-group">
					<p>
						<input type="text" class="form-control" name="userId"
							onfocus="focusItem(this)" 
							onblur="checkBlurRegisterItem(this)"
							placeholder="賬號" required><span></span>
					</p>
				</div>
				<div class="form-group">
					<p>
						<input type="password" class="form-control" 
						name="userPassword" onfocus="focusItem(this)" 
						onblur="checkBlurRegisterItem(this)" placeholder="密碼" 
						required><span></span>
					</p>
				</div>
				<div class="form-group">
					<p>
						<input type="password" class="form-control"
							onfocus="focusItem(this)" 
							onblur="checkBlurRegisterItem(this)"
							name="userPasswordConfirm" placeholder="確認密碼" 
							required> <span></span>
					</p>
				</div>
				<div class="form-group">
					<p>
						<input type="text" class="form-control" name="userName"
							onfocus="focusItem(this)" 
							onblur="checkBlurRegisterItem(this)"
							placeholder="姓名" required><span></span>
					</p>
				</div>
				<div class="form-group">
					<select class="form-control" id="user_level" name="userLevel">
						<option value="學生">學生</option>
						<option value="教師">教師</option>
					</select>
				</div>
				<br>
				<div class="form-group" id="student_class_form">
					<p>
						<input type="text" class="form-control" id="student_class"
							name="userClass" onfocus="focusItem(this)"
							onblur="checkBlurRegisterItem(this)" 
							placeholder="班級" required>
						<span></span>
					</p>
				</div>
				<div class="form-group">
					<p>
						<input class="form-control" type="text" name="veryCode" 
						value="" onfocus="focusItem(this)" 
						onblur="checkBlurRegisterItem(this)" placeholder="驗證碼" />
						<img height="25" src="${pageContext.request.contextPath}/getcode" 
						alt="看不清,換一張" onclick="change(this)"><span></span>
					</p>
				</div>
				<button type="submit" class="btn btn-primary block full-width m-b">
				注冊
				</button>
				<p class="text-muted text-center">
					<small>已經有一個賬戶?</small>
				</p>
				<a class="btn btn-sm btn-white btn-block" href="login.jsp">登錄</a>
			</form>
		</div>
	</div>
</body>

html代碼結構就不詳細說明了,不懂得可以查檔案,這里主要講一下重要的內容

我們給表單,組件,圖片系結的事件處理onfocus(獲取焦點事觸發),onblur(失去焦點時觸發),onsubmit(提交表單時觸發),onclick(點擊時觸發)

后面在js會給出處理函式,就不詳細說明了

在驗證碼的文本框input標簽后添加一個img標簽來顯示驗證碼圖片,src屬性指定的是生成驗證的servlet,下面來說驗證碼的實作

驗證碼的實作

驗證碼是通過在img標簽中的src屬性指定為servlet的url,這樣servlet就會把驗證碼通過輸出流回應給客戶端,下面給出生成驗證碼的servlet

創建servlet的方式在前面我已經講過了,這里就不再重復了

在controller層的user包下創建CodeServlet.java,添加如下代碼

	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 呼叫工具類生成的驗證碼和驗證碼圖片
		Map<String, Object> codeMap = CodeUtil.generateCodeAndPic();
		/* 將四位數字的驗證碼保存到Session中
		 * 這樣當客戶提交時,會從session中獲取生成的驗證碼并與用戶
		 * 輸入的驗證碼進行匹配 */
		HttpSession session = req.getSession();
		session.setAttribute("code", codeMap.get("code").toString());
		// 禁止影像快取,
		resp.setHeader("Pragma", "no-cache");
		resp.setHeader("Cache-Control", "no-cache");
		resp.setDateHeader("Expires", -1);
		resp.setContentType("image/jpeg");
		// 將影像輸出到Servlet輸出流中,
		ServletOutputStream sos;
		try {
			sos = resp.getOutputStream();
			ImageIO.write((RenderedImage) codeMap.get("codePic"), "jpeg", sos);
			sos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

通過上面代碼我們知道,真正生成驗證碼的是工具類CodeUtil,而servlet主要功能呼叫工具類的方法生成驗證碼并放在session中,起到封裝的作用,然后通過輸出流回應給客戶端

在utils包下創建工具類CodeUtil,代碼如下

public class CodeUtil {
    private static int width = 100;// 定義圖片的width
    private static int height = 20;// 定義圖片的height
    private static int codeCount = 4;// 定義圖片上顯示驗證碼的個數
    private static int xx = 15;
    private static int fontHeight = 18;
    private static  int codeY = 16;
    private static char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
            'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
    
    /**
     * 生成一個map集合
     * code為生成的驗證碼
     * codePic為生成的驗證碼BufferedImage物件
     * @return
     */
    public static Map<String,Object> generateCodeAndPic() {
        // 定義影像buffer
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // Graphics2D gd = buffImg.createGraphics();
        // Graphics2D gd = (Graphics2D) buffImg.getGraphics();
        Graphics gd = buffImg.getGraphics();
        // 創建一個亂數生成器類
        Random random = new Random();
        // 將影像填充為白色
        gd.setColor(Color.WHITE);
        gd.fillRect(0, 0, width, height);
        // 創建字體,字體的大小應該根據圖片的高度來定,
        Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
        // 設定字體,
        gd.setFont(font);
        // 畫邊框,
        gd.setColor(Color.BLACK);
        gd.drawRect(0, 0, width - 1, height - 1);
        // 隨機產生40條干擾線,使圖象中的認證碼不易被其它程式探測到,
        gd.setColor(Color.BLACK);
        for (int i = 0; i < 30; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            gd.drawLine(x, y, x + xl, y + yl);
        }
        // randomCode用于保存隨機產生的驗證碼,以便用戶登錄后進行驗證,
        StringBuffer randomCode = new StringBuffer();
        int red = 0, green = 0, blue = 0;
        // 隨機產生codeCount數字的驗證碼,
        for (int i = 0; i < codeCount; i++) {
            // 得到隨機產生的驗證碼數字,
            String code = String.valueOf(codeSequence[random.nextInt(36)]);
            // 產生隨機的顏色分量來構造顏色值,這樣輸出的每位數字的顏色值都將不同,
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);
            // 用隨機產生的顏色將驗證碼繪制到影像中,
            gd.setColor(new Color(red, green, blue));
            gd.drawString(code, (i + 1) * xx, codeY);
            // 將產生的四個隨機陣列合在一起,
            randomCode.append(code);
        }
        Map<String,Object> map  =new HashMap<String,Object>();
        //存放驗證碼
        map.put("code", randomCode);
        //存放生成的驗證碼BufferedImage物件
        map.put("codePic", buffImg);
        return map;
    }
}

完成到這里我們就可以測驗驗證碼的功能了,啟動專案,在瀏覽器地址欄輸入http://localhost:8080/web_resource/views/before/register.jsp

重繪頁面,也就是在請求一次servlet,這樣驗證碼就跟著改變,后面會在js實作點擊圖片更改驗證碼

效果如下

在這里插入圖片描述

前端頁面表單驗證

瀏覽器對所有get請求都有快取功能,而請求js是get請求,所以可以把全部的js代碼單獨放在一個js檔案中,這樣瀏覽器只需請求一次js,效率就提高了

在views檔案夾下創建js子檔案夾存放js代碼

下面給出的所有js代碼都放在一個js檔案中,我的是function.js,在頁面結構的body標簽之前參考即可,我的參考如下

<script src="${pageContext.request.contextPath}/views/js/function.js"></script>
</body>

使用js點擊圖片改變驗證碼

可以通過js實作點擊圖片改變驗證碼,這很簡單,在img標簽中想更改圖片,其實就改變src的屬性值,

但是我們請求的是一個servlet,所以url不能改,能改的只有查詢串(即請求引數),

請求引數要各不相同,使用Date類獲取本地當前系統時間就可以實作,js代碼如下

// 改變驗證碼圖片
function change(img) {
	img.src = getWebRootPath() + "/getcode?" + new Date().getTime();
}

這里使用的獲取web根路徑的函式,js代碼如下

// 獲取根路徑
function getWebRootPath() {
	var a = window.document.location.href;//
	var b = window.document.location.pathname;
	var pos = a.indexOf(b);
	var path = a.substring(0, pos);
	a = a.substring(a.indexOf("/") + 2, a.length);
	a = a.substring(a.indexOf("/") + 1, a.length);
	var pathName = a.substring(0, a.indexOf("/"));
	return path + "/" + pathName;
}

在注冊頁面結構中已經在img標簽中使用了onclick點擊事件函式,呼叫的正是change函式,所有可以直接測驗了

效果如下

在這里插入圖片描述

使用jQuery動態改變班級欄位

jQuery是js庫,它可以簡化我們對DOM的操作

有兩個版本的 jQuery 可供下載:

  • Production version - 用于實際的網站中,已被精簡和壓縮,
  • Development version - 用于測驗和開發(未壓縮,是可讀的代碼)

這兩個版本都可以從 jQuery.com 下載,

在views檔案夾的js子檔案夾中添加jQuery,然后在head標簽中進行參考即可,我的參考如下

<script
	src="${pageContext.request.contextPath}/views/js/jquery-2.1.1.js"></script>

當在選擇框選擇學生時有班級文本框,但選擇教師時是沒有班級文本框的,下面通過jQuery實作這種效果,代碼如下

/* 通過id獲取選擇框物件并系結事件change函式,引數為匿名函式
* 匿名函式當change執行時便會執行,這樣當選擇框值改變時便會執行匿名函式*/
$("#user_level").change(function() {
			if ($('#user_level').val() == "學生") {
				// 通過id獲取存放班級文本框容器div并呼叫可顯函式
				$('#student_class_form').show();
			} else {
				// 呼叫隱藏函式
				$('#student_class_form').hide();
				// 獲取班級文本框并設定值可以為空
				$('#student_class').attr("required", false);
			}
		});

測驗效果

在這里插入圖片描述

使用jQuery和Ajax異步驗證表單

jQuery前面已經介紹過了,這里主要講一下Ajax技術

簡短地說,AJAX 是與服務器交換資料的,在不多載整個網頁的情況下,AJAX 通過后臺加載資料,并在網頁上進行顯示,

用戶注冊時用的賬號可能已經是注冊過,由于賬號是唯一的(即主鍵),這時如果不在客戶端先進行檢測的就提交表單到服務器就會報錯

同理,用戶在表單輸入的驗證碼也需要在客戶端先進行檢測

要想在不把表單資料發送到服務器的情況下驗證用戶名是否存在,驗證碼是否輸入正確,就需要使用Ajax

它可以請求服務器(servlet)獲取資料,然后通過后臺判斷資料并進行相應處理,而不是加載整個網頁(重繪,或者跳轉頁面)

下面驗證賬號是否存在的js核心代碼,如下

// 驗證賬號是否存在的servlet路徑
var url = getWebRootPath() + "/check_user_id?id=" + encodeURI($(obj).val()) + "&" + new Date().getTime();
/*.get() 方法通過 HTTP GET 請求從服務器上請求資料,
* 可選的匿名函式引數是請求成功后所執行的函式名,*/
$.get(url, function(data) {
// 服務器回傳false則用戶名已存在
if (data == "false") {
	// 在頁面顯示提示資訊
	msgBox.html('賬號不能使用!');
	msgBox.addClass('error');
	// 標記改為false,阻止表單提交
	flagId = false;
} else {
		flagId = true;
		}
});

這里只是單獨給出來說明驗證賬號的原理,實際運行需要添加到事件函式中才能運行,后面會給出完整代碼

同樣的驗證用戶輸入的驗證碼是否正確也是通過Ajax請求servlet,接受服務端回應的資訊來判斷對不對,這里代碼就不再給出

在注冊頁面結構中,已經給表單組件系結了onblur(失去焦點時執行)事件,且事件處理函式都是一樣的checkBlurRegisterItem(this)

這樣就可以在這里集中驗證表單是否為空,密碼和確認密碼是否一樣,賬號是否已存在,驗證碼是否正確了,完整代碼如下

//標記位,只有有一個為false,則阻止表單提交
var flagId = false;
var flagPassword = false;
var flagPasswordConfirm = false;
var flagName = false;
var flagClass = true;
var flagCode = false;
function checkBlurRegisterItem(obj) {
	// 獲取表單組件的下一個元素(即span),用來提示資訊
	var msgBox = $(obj).next('span');
	/* 通過表單組件的name屬性來判斷是那個組件*/
	switch ($(obj).attr('name')) {
		/* 檢測文本框是否為空,若不為空則驗證賬號是否存在*/
		case "userId":
		    // 獲取賬號文本框值,判斷是否為空
			if (obj.value == "") {
				// 設定span元素的值
				msgBox.html('賬號不能為空');
				// 給span元素添加類屬性的值,后面會使用行內樣式修改顯示
				msgBox.addClass('error');
				// 標記改為false,阻止表單提交
				flagId = false;
			} else {
				// 驗證賬號是否存在的servlet路徑
				var url = getWebRootPath() + "/check_user_id?id=" + encodeURI($(obj).val()) + "&" + new Date().getTime();
				/*.get() 方法通過 HTTP GET 請求從服務器上請求資料,
				* 可選的匿名函式引數是請求成功后所執行的函式名,*/
				$.get(url, function(data) {
					// 服務器回傳false則用戶名已存在
					if (data == "false") {
						// 在頁面顯示提示資訊
						msgBox.html('賬號不能使用!');
						msgBox.addClass('error');
						// 標記改為false,阻止表單提交
						flagId = false;
					} else {
						flagId = true;
					}
				});
			}
			break;
		/* 判斷密碼框是否為空*/
		case "userPassword":
			if (obj.value == "") {
				msgBox.html('密碼不能為空');
				msgBox.addClass('error');
				flagPassword = false;
			} else {
				flagPassword = true;
			}
			break;
		/* 判斷密碼和確認密碼是否相同*/
		case "userPasswordConfirm":
			if (obj.value == "") {
				msgBox.html('確認密碼不能為空');
				msgBox.addClass('error');
				flagPasswordConfirm = false;
			} else if ($(obj).val() != $('input[name="userPassword"]').val()) {
				msgBox.html('兩次輸入的密碼不一致');
				msgBox.addClass('error');
				flagPasswordConfirm = false;
			} else {
				flagPasswordConfirm = true;
			}
			break;
		/* 判斷姓名是否為空*/
		case "userName":
			if (obj.value == "") {
				msgBox.html('姓名不能為空');
				msgBox.addClass('error');
				flagName = false;
			} else {
				flagName = true;
			}
			break;
		// 判斷班級是否為空
		case "userClass":
			if (obj.value == "") {
				msgBox.html('班級不能為空');
				msgBox.addClass('error');
			}
			break;
		/* 判斷驗證碼是否為空,若不為空則判斷是否正確*/
		case "veryCode":
			var numshow = $(obj).next().next();
			if (obj.value == "") {
				numshow.html('驗證碼不能為空');
				numshow.addClass('error');
				flagCode = false;
			} else {
				var url = getWebRootPath() + "/check_user_code?num=" + encodeURI($(obj).val()) + "&" + new Date().getTime();
				$.get(url, function(data) {
					if (data == "false") {
						numshow.html('驗證碼輸入有誤');
						numshow.addClass('error');
						flagCode = false;
					} else {
						flagCode = true;
					}
				});
			}
			break;
	}
}

驗證賬號是否存在以及驗證是否正確都是請求servlet來判斷,下面分別給出

檢測驗證碼是否正確的servlet

在controller層的user包下創建CheckUserCode.java,代碼如下

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 接收客戶端資訊(即驗證碼)
		String num = request.getParameter("num");
		/* 從session獲取生成的驗證碼 */
		HttpSession session = request.getSession();
		String sysCode = (String) session.getAttribute("code");
		// 獲取輸出流
		PrintWriter out = response.getWriter();
		/* 判斷用戶輸入的驗證和生成的驗證碼是否相同
		 * 若相同則回應true,否則回應false */
		if (sysCode.equals(num)) {
			out.print("true");
		} else {
			out.print("false");
		}
		out.close();
	}

完成到這步,就可以進行小測驗,檢查驗證碼效果,由于撰寫了servlet需要重啟專案

測驗效果

在這里插入圖片描述

提示不太醒目,我們可以在注冊頁面中添加行內樣式來修改一下,只需在head標簽添加以下代碼即可

<style>
.form-group p .error {
	display: inline-block;
	border: 1px solid #ff855a;
	background-color: #ffe8e0;
	height: 25px;
	line-height: 25px;
	padding: 0px 20px;
	margin-left: 20px;
}
</style>

檢測賬號是否存在的servlet

在controller層的user包中創建CheckUserId.java,代碼如下

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/* 設定字符編碼,解決中文亂碼問題 */
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=utf-8");
		// 接收客戶端資訊(即賬號)
		String id = request.getParameter("id");
		//創建用戶service層介面的實作類
		UserServiceImpl userServiceImpl = new UserServiceImpl();
		/* 呼叫業務邏輯方法檢查用戶是否重復,若查到則回傳count>0 */
		int count = 0;
		try {
			count = userServiceImpl.checkIdRepeated(id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		// 獲取輸出流物件
		PrintWriter out = response.getWriter();
		/* 向客戶發送查找成功或失敗的標記 */
		if(count > 0 ){
			out.print("false");
		}else{
			out.print("true");
		}
		out.close();
	}

代碼的功能注釋已經詳細說明,這里我們在說明一下之前搭建的三層架構:

顯然這里檢查賬號是否存在的servlet是處于控制層,而就是說檢查賬號不是它實作的,它只是起到控制作用,比如它呼叫了service層的業務邏輯方法checkIdRepeated

下面我們只需要在service層的UserService介面中添加檢查賬號是否存在的業務功能,然后在UserServiceImpl實作類中重寫即可

在介面中添加的業務邏輯方法如下

	// 檢查賬號是否存在
	public int checkIdRepeated(String userId) throws SQLException;

在實作類重寫介面方法

	@Override
	public int checkIdRepeated(String userId) throws SQLException {
		// 通過賬號在資料庫進行檢索
		int i = userDao.selectById(userId);
		return i;
	}

dao層的實作和service層是一樣的,這里我就直接給出代碼

在dao層的UserDao介面中添加檢索賬號的抽象方法

    // 通過賬號在資料庫進行檢索
	public int selectById(String userId) throws SQLException;

在dao層的UserDaoImpl實作類中重寫介面方法

	@Override
	public int selectById(String userId) throws SQLException {
		// sql檢索陳述句
		String sql = "select * from user where user_id=?";
		// 呼叫jdbc工具類執行sql陳述句,如果操作成功,i就是操作成功的條數(即i > 0)
		resultSet = JDBCUtil.executeQuery(sql, userId);
		int i = 0;
		if (resultSet.next()) {
			i = 1;
		}
		return i;
	}

至此,檢查賬號是否存在的代碼已經全部撰寫完成,測驗之前需要重啟專案,同時需要在資料庫中添加一個賬號

在這里插入圖片描述

測驗效果

在這里插入圖片描述

在前面我們給表單組件系結了失去焦點時執行的函式checkRegisterForm(this),我們知道如果表單組件輸入為空等等,則會顯示一個提示框

但是如果用戶再次點擊表單組件時,提示資訊不會消失,所以我們還得給所有表單系結一個獲取焦點時執行的事件函式focusItem(this),然后再js撰寫處理邏輯即可,代碼如下

function focusItem(obj) {
  /*  由于驗證input組件還有img元素,它的下下元素才是span
	所以要單獨處理*/
	if ($(obj).attr('name') == 'veryCode') {
		// 把span元素的值啥為空,并把類屬性刪掉
		$(obj).next().next().html('').removeClass('error');
	} else {
		// 把span元素的值啥為空,并把類屬性刪掉
		$(obj).next('span').html('').removeClass('error');
	}
}

這里就不再演示效果了,等到驗證注冊功能時會看到這個效果的

我們撰寫了表單組件的失去焦點和獲取焦點的js事件函式,但是當點擊提交時表單還需要驗證一次,這里只需給form表單組件系結一個事件onsubmit,處理函式為checkRegisterForm(this),代碼如下

function checkRegisterForm(form) {
	// 獲取所有input組件,回傳一個陣列包含input標簽的陣列(即物件)
	var elements = form.getElementsByTagName('input');
	
	/* 遍歷input標簽*/
	for (var i = 0; i < elements.length; i++) {
		// 判斷input物件是否為null
		if (elements[i] != null) {
			// 檢查input是否有onblur屬性
			if (elements[i].getAttribute("onblur")) {
				checkBlurRegisterItem(elements[i]);
			}
		}
	}
    /*判斷所有組件的標記,若為false,則說明有的組件為慷訓者輸入有誤
	* 直接 return false 阻止表單提交*/
	if (flagId && flagPassword && flagPasswordConfirm &&
		flagName && flagClass && flagCode) {
		return true;
	} else {
		return false;
	}
}

通過獲取所有input標簽并回傳一個包含input物件的陣列,然后遍歷判斷input標簽是否包含onblur屬性,若有則呼叫失去焦點時執行的函式checkBlurRegisterItem

注冊功能綜合測驗

ok,大功告成,到現在注冊功能所有代碼均撰寫完成,現在就可以來測驗注冊功能了

測驗效果

在這里插入圖片描述

在這里插入圖片描述

教師注冊效果就不再演示了,下一篇會更新在此三層架構完善登錄功能

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/302638.html

標籤:其他

上一篇:美食杰專案首頁--部分功能代碼以及簡介

下一篇:Unity WebView 插件??(十五)特定模塊 WebGL網頁視圖—WebGLWebView

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more