主頁 > 前端設計 > 基于javaweb的web資源庫專案——后臺用戶管理demo

基于javaweb的web資源庫專案——后臺用戶管理demo

2021-09-30 08:35:40 前端設計

<iframe id="m1RwAPLM-1632887571101" src="https://player.bilibili.com/player.html?aid=718300599" allowfullscreen="true" data-mediaembed="bilibili"></iframe>

基于javaweb的web資源庫專案——后臺用戶管理實作

文章目錄

  • 后臺整體頁面結構
  • 后臺歡迎頁面結構
  • 用戶管理實作
    • 在頁面上顯示所有學生資訊并分頁
      • 后臺學生管理頁面
      • 后端實作
    • 洗掉學生和批量洗掉學生
      • 后端實作
      • 前端實作
    • 修改學生
      • 后端實作
      • 后臺學生修改頁面
    • 添加單個學生
      • 后臺添加學生頁面
      • 后端實作
    • 批量添加學生
      • jQuery easyUI的使用
      • 在后臺學生管理頁面使用easyUI
      • 后端實作
        • 使用第三方工具上傳

后臺整體頁面結構

用戶分為學生,教師,管理員,而管理員登錄時會跳轉到后臺的歡迎頁面,

通過觀察可以知道不管是歡迎頁面,還是學生或教師以及后面的資源等的管理頁面都有相同的頁面結構,如下所示
在這里插入圖片描述

那么這樣就可以把相同的頁面結構單獨抽取成一個jsp,然后在不同的頁面結構的jsp中通過include指令包含它,這樣可以實作代碼復用,

后臺的所有頁面以及處理后臺的處于控制層的servlet都是要做權限控制,到后面會用過濾器實作,這里就先不講

過濾器實作的原理就是過濾路徑,所有需要有一個路徑標識,在這里使用manage路徑標識

在after檔案夾中創建子檔案夾manage,然后再manage中創建相同的頁面結構admin_menu.jsp,代碼如下

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>web資源庫管理系統</title>
<link rel="stylesheet" type="text/css"
	href="${pageContext.request.contextPath}/views/css/common.css" />
<link rel="stylesheet" type="text/css"
	href="${pageContext.request.contextPath}/views/css/main.css" />
</head>
<body>
	<div class="topbar-wrap white">
		<div class="topbar-inner clearfix">
			<div class="topbar-logo-wrap clearfix">
				<ul class="navbar-list clearfix">
					<li><a class="on"
						href="${pageContext.request.contextPath}/views/after/manage/admin_index.jsp">首頁</a></li>
					<li><a
						href="${pageContext.request.contextPath}/views/before/manage/index.jsp"
						target="_blank">網站首頁</a></li>
				</ul>
			</div>
			<div class="top-info-wrap">
				<ul class="top-info-list clearfix">
					<li><a href="#">管理員:${name.userName}</a></li>
					<li><a
						href="${pageContext.request.contextPath}/manage/admin_logout">退出</a></li>
				</ul>
			</div>
		</div>
	</div>
	<div class="container clearfix">
		<div class="sidebar-wrap">
			<div class="sidebar-title">
				<h1>選單</h1>
			</div>
			<div class="sidebar-content">
				<ul class="sidebar-list">
					<li><a href="#"><i class="icon-font">&#xe003;</i>用戶管理</a>
						<ul class="sub-menu">
							<li><a
								href="${pageContext.request.contextPath}/manage/admin_do_student_select"><i
									class="icon-font">&#xe008;</i>學生管理</a></li>
							<li><a
								href="${pageContext.request.contextPath}/manage/admin_do_teacher_select"><i
									class="icon-font">&#xe006;</i>教師管理</a></li>
						</ul></li>
					<li><a href="#"><i class="icon-font">&#xe003;</i>資源管理</a>
						<ul class="sub-menu">
							<li><a
								href="${pageContext.request.contextPath}/manage/admin_do_resource_select"><i
									class="icon-font">&#xe046;</i>資源管理</a></li>
							<li><a
								href="${pageContext.request.contextPath}/manage/admin_do_category_select"><i
									class="icon-font">&#xe045;</i>類別管理</a></li>
						</ul></li>
					<li><a href="#"><i class="icon-font">&#xe003;</i>論壇管理</a>
						<ul class="sub-menu">
							<li><a
								href="${pageContext.request.contextPath}/manage/admin_do_post_select"><i
									class="icon-font">&#xe012;</i>帖子管理</a></li>
							<li><a
								href="${pageContext.request.contextPath}/manage/admin_do_comment_select"><i
									class="icon-font">&#xe052;</i>評論管理</a></li>
						</ul></li>
				</ul>
			</div>
		</div>

后臺歡迎頁面結構

前面給了后臺都有的整體的頁面結構,現在只需在歡迎頁面中使用include指令包含即可

在manage檔案夾中創建后臺歡迎頁面admin_index.jsp,代碼如下

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="admin_menu.jsp"%>
<div class="main-wrap">
	<div class="crumb-wrap">
		<div class="crumb-list">
			<div class="crumb-list">
				<i class="icon-font"></i> <a
					href="${pageContext.request.contextPath}/views/after/manage/admin_index.jsp">首頁
				</a>
			</div>
			<div align="center" style="padding-top: 250px;">
				<font color="red" size="10">歡迎使用Web資源庫管理系統</font>
			</div>
		</div>
	</div>
</div>
</body>
</html>

在資料庫中添加一個管理員賬號
在這里插入圖片描述

啟動專案,在瀏覽器輸入http://localhost:8080/web_resource/views/before/login.jsp登錄賬號,效果如下

在這里插入圖片描述

用戶管理實作

用戶管理要實作功能如下

  • 在頁面上顯示所有用戶資訊并且要實作分頁
  • 可以對用戶進行增刪改查,批量洗掉,學生還可以批量添加學生

在頁面上顯示所有學生資訊并分頁

后臺學生管理頁面

同樣的,學生管理頁面也是使用include指令包含整體的頁面結構

后臺學生管理頁面使用了JSTL核心標簽庫,我們只需要匯入該Jar包后,在頁面中使用taglib指令將其匯入即可使用

jar包下載地址

在manage檔案夾下創建admin_student.jsp,代碼如下

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ include file="admin_menu.jsp"%>
<div class="main-wrap">
	<div class="crumb-wrap">
		<div class="crumb-list">
			<i class="icon-font"></i><a
				href="${pageContext.request.contextPath}/views/after/manage/admin_index.jsp">首頁</a><span
				class="crumb-step">&gt;</span><span class="crumb-name">學生管理</span>
		</div>
	</div>
	<div class="search-wrap">
		<div class="search-content">
			<form action="admin_do_student_select" method="get">
				<table class="search-tab">
					<tr>
						<th width="70">關鍵字:</th>
						<td><input class="common-text" placeholder="關鍵字"
							name="keywords" id="" type="text"></td>
						<td><input class="btn btn-primary btn2" name="sub" value="查詢"
							type="submit"></td>
					</tr>
				</table>
			</form>
		</div>
	</div>
	<div id="register" class="result-wrap">
		<form action="admin_do_student_delete" id="delectForm" method="post">
			<div class="result-title">
				<div class="result-list">
					<a
						href="${pageContext.request.contextPath}/views/after/manage/admin_student_add.jsp">
						<i class="icon-font"></i>添加學生
					</a> <a href="javascript:openAddRegisterDialog()"> <i
						class="icon-font"></i>批量添加學生
					</a> <a id="batchDel"
						href="javascript:deleteMore('你確定洗掉這些用戶嗎?', 'delectForm')"> <i
						class="icon-font"></i>批量洗掉
					</a>
				</div>
			</div>
			<div class="result-content">
				<table class="result-tab" width="100%">
					<tr>
						<th class="tc" width="5%"><input class="allChoose" name=""
							onclick="selAll(this)" type="checkbox"></th>
						<th>賬號</th>
						<th>姓名</th>
						<th>性別</th>
						<th>生日</th>
						<th>班級</th>
						<th>操作</th>
					</tr>
					<c:forEach var="u" items="${userlist}">
						<tr>
							<td class="tc"><input name="id[]" value="${u.userId}"
								type="checkbox"></td>
							<td>${u.userId }</td>
							<td>${u.userName  }</td>
							<td>${u.userSex }</td>
							<td>${u.userBirthday  }</td>
							<td>${u.userClass  }</td>
							<td><a class="link-update"
								href="${pageContext.request.contextPath}/manage/admin_to_student_update?id=${u.userId}&currentPage=${currentPage}">修改</a>
								<a class="link-del"
								href="javascript:Delete('你確定要洗掉用戶【${u.userName} 】嗎?', '${pageContext.request.contextPath}/manage/admin_do_student_delete?id=${u.userId}&currentPage=${currentPage }')">洗掉</a>
							</td>
						</tr>
					</c:forEach>
				</table>
				<div class="list-page">
					共 ${totalStudent} 條記錄, 當前 ${currentPage} / ${totalPage} 頁 <a
						href="admin_do_student_select?currentPage=1">首頁</a> <a
						href="admin_do_student_select?currentPage=${currentPage - 1 < 1 ? 1 : currentPage-1}">上一頁</a>
					<a
						href="admin_do_student_select?currentPage=${currentPage + 1 > totalPage ? totalPage : currentPage + 1}">下一頁</a>
					<a href="admin_do_student_select?currentPage=${totalPage}">尾頁</a>
				</div>
			</div>
		</form>
	</div>
</div>
<script src="${pageContext.request.contextPath}/views/js/function.js"></script>
</body>
</html>

代碼就不詳細說明了,主要講一下遍歷學生資訊

在servlet中會呼叫業務邏輯層獲取到了用戶點擊某一頁的學生資訊存放在list集合中,并且放在了請求域中,那么在jsp頁面中就可以使用EL運算式使用它

在 jsp頁面中需要遍歷集合,就需要使用JSTL的forEach標簽,item屬性的值是list集合物件,而var屬性的值是物件變數名

也就是說每遍歷一次var屬性的值都是不同的物件,這樣就可以通過EL運算式獲取物件的屬性值了

后端實作

資料訪問層(dao)實作

檢索用戶點擊的某一頁的學生記錄或檢索用戶搜索的學生姓名獲取的學生記錄

在頁面上顯示所有學生資訊并分頁,換句話說也就是當用戶點擊某一頁時只檢索那一頁學生記錄,那么在底層中就不能使用下面這條mysql陳述句

sql = "select * from user where user_level='學生'";

我們知道"select * from user where user_level=‘學生’ 會獲取所有學生記錄,但這不是我們想要的,

那么要怎么實作分頁呢?只需在上面那條陳述句添加一個限制結果即可,如下

sql = "select * from user where user_level='學生' limit ?, ?";

limit是限制子句,第一個引數是資料庫中的記錄行數,第二引數是獲取的記錄條數,也就是從第一個引數中的行數開始檢索,而第二個引數是檢索的記錄條數

很顯然獲取的記錄條數就是每頁顯示的條數,而記錄行數剛好等于(當前頁 * 每頁顯示的條數)

用戶除了通過點擊頁數來檢索資訊還之外還可以通過姓名來檢索,可以添加一個通配符進行過濾即(like運算子),如下

sql = "select * from user where user_level='學生' and user_name like ? limit ?, ?";

通過上面的分析,只需要提供三個引數(當前頁,用戶搜索時提供的關鍵字(姓名),每一頁的條數),完整代碼如下

在dao層中的UserDao介面添加檢索用戶點擊某一頁的學生資訊或檢索關鍵詞的學生資訊的抽象方法,如下

	// 檢索用戶點擊某一頁的學生資訊或檢索關鍵詞的學生資訊
	public ArrayList<User> selectAllStudent(int currentPage, int count, String keyword) throws SQLException;

在dao層的實作類UserDaoImpl中重寫介面方法selectAllStudent,如下

	@Override
	public ArrayList<User> selectAllStudent(int currentPage, int count, String keyword) throws SQLException {
		// 存放所有學生的list集合
		ArrayList<User> listUser = new ArrayList<User>();
		String sql = "";
		if (keyword != null) {  // 用戶通過關鍵字檢索學生
			sql = "select * from user where user_level='學生' and user_name like ?  limit ?, ?";
			resultSet = JDBCUtil.executeQuery(sql, "%" + keyword + "%", (currentPage - 1) * count, count);
		} else { //用戶通過分頁檢索學生資訊
			sql = "select * from user where user_level='學生'  limit ?, ?";
			resultSet = JDBCUtil.executeQuery(sql, (currentPage - 1) * count, count);
		}
		while (resultSet.next()) {
			User user = new User(resultSet.getString("user_id"), resultSet.getString("user_password"),
					resultSet.getString("user_name"), resultSet.getString("user_sex"),
					resultSet.getString("user_birthday"), resultSet.getString("user_class"),
					resultSet.getString("user_level"));
			listUser.add(user);
		}
		return listUser;
	}

檢索所有學生記錄總數以及總頁數

除了要實作分頁,我們知道還得在頁面上顯示多少條記錄,以及有幾頁,如下

sql = "select count(*) from user where user_level='學生'"

這條sql陳述句會檢索并回傳所有學生記錄條數,也就是在頁面上顯示多少條記錄,而總頁數恰等于(總學生記錄條數 / 每一頁的記錄條數)

同理,用戶還可以通過關鍵字來檢索,只需在上面這條sql陳述句中添加通配符(like運算子)即可,如下

sql = "select count(*) from user where user_level='學生' and user_name like ?"

通過上面的分析,只需要提供兩個引數(用戶搜索時提供的關鍵字(姓名),每一頁的條數),完整代碼如下

在dao層的UserDao介面中添加檢索所有學生記錄總數并算出總頁數的抽象方法,如下

   // 檢索所有學生記錄總數并算出總頁數
	public int[] selectStudentTotal(int count, String keyword) throws SQLException;

在dao層的UserDaoImpl實作類中重寫介面的selectStudentTotal方法,如下

	@Override
	public int[] selectStudentTotal(int count, String keyword) throws SQLException {
		String sql = "";
		// 0 學生記錄數 1 頁數
		int array[] = { 0, 1 };
		if (keyword != null) { // 通過關鍵詞來檢索學生記錄數及頁數
			sql = "select count(*) from user where user_level='學生' and user_name like ?";
			resultSet = JDBCUtil.executeQuery(sql, "%" + keyword + "%");
		} else { // 通過分頁來檢索學生記錄數及頁數
			sql = "select count(*) from user where user_level='學生'";
			resultSet = JDBCUtil.executeQuery(sql);
		}
		while (resultSet.next()) {
			array[0] = resultSet.getInt(1);
			if (array[0] % count == 0) {
				array[1] = array[0] / count;
			} else {
				array[1] = array[0] / count + 1;
			}
		}
		return array;
	}

業務邏輯層(service)實作

通過dao層的分析,可以知道service層要實作兩個業務功能,它們封裝了dao層操作,只提現業務

獲取所有學生記錄總數以及總頁數

在service層的UserService中添加獲取所有學生記錄總數以及總頁數業務抽象方法,如下

	// 獲取所有學生記錄總數以及頁數
	public int[] getStudentPageTotal(int count, String keyword) throws SQLException;

在service層的實作類UserServiceImpl中重寫介面getStudentPageTotal方法,如下

	@Override
	public int[] getStudentPageTotal(int count, String keyword) throws SQLException {
		// 檢索所有學生記錄總數并算出總頁數
		int[] array = userDao.selectStudentTotal(count, keyword);
		return array;
	}

獲取用戶點擊的某一頁的學生記錄或用戶搜索的學生姓名獲取的學生記錄

在service層的UserService中添加獲取用戶點擊的某一頁的學生記錄或用戶搜索的學生姓名獲取的學生記錄的抽象方法,如下

	// 獲取用戶點擊某一頁的學生記錄或搜索的學習記錄
	public ArrayList<User> getAllStudentInfo(int currentPage, int count, String keyword) throws SQLException;

在service層的實作類UserServiceImpl中重寫介面方法getAllStudentInfo,如下

	@Override
	public ArrayList<User> getAllStudentInfo(int currentPage, int count, String keyword) throws SQLException {
		// 檢索用戶點擊的某一頁的學生記錄或檢索用戶搜索的學生姓名獲取的學生記錄
		ArrayList<User> listUser = userDao.selectAllStudent(currentPage, count, keyword);
		return listUser;
	}

控制層(controller)實作

控制層主要功能就是接受客戶端的資料,然后作為引數呼叫業務邏輯層獲取資料,并把資料呈現在頁面中

在控制層(controller)中的user包下創建DoStudentSelect.java,代碼如下

package com.zhuo.controller.user;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;

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 com.zhuo.entity.User;
import com.zhuo.service.impl.UserServiceImpl;

@WebServlet("/manage/admin_do_student_select")
public class DoStudentSelect extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 當前頁
		int currentPage = 1;
		// 每頁顯示條數
		int count = 5;
		// 初始化,array[0]=學生總數,array[1]=總頁數,后面會被覆寫
		int array[] = { 0, 0 };
		// 獲取用戶指定的頁面
		String cp = request.getParameter("currentPage");
		// 接收用戶搜索的關鍵字
		String keyword = request.getParameter("keywords");
		/* 用戶如果有指定當前頁,則把字串轉化為int型 */
		if (cp != null) {
			currentPage = Integer.parseInt(cp);
		}
		// 創建用戶service層介面的實作類
		UserServiceImpl userServiceImpl = new UserServiceImpl();
		/*
		 * 呼叫業務邏輯方法獲取學生記錄總數并算出總頁數 即(array[0]=學生總數,array[1]=總頁數(學生總數/每頁顯示條數)
		 */
		try {
			array = userServiceImpl.getStudentPageTotal(count, keyword);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		/* 呼叫業務邏輯方法獲取用戶點擊的某一頁的學生資訊 */
		ArrayList<User> listUser = null;
		try {
			listUser = userServiceImpl.getAllStudentInfo(currentPage, count, keyword);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		/* 放到請求物件域里,這樣在jsp就可以通el運算式獲取 */
		request.setAttribute("userlist", listUser);
		request.setAttribute("totalStudent", array[0]);
		request.setAttribute("totalPage", array[1]);
		request.setAttribute("currentPage", currentPage);
		// 請求轉發到學生管理頁面
		request.getRequestDispatcher("/views/after/manage/admin_student.jsp").forward(request, response);
	}
}

完成到這里,前后端功能就都實作了,測驗前需要在資料庫中添加學生資訊,然后啟動專案

在這里插入圖片描述

在這里插入圖片描述

洗掉學生和批量洗掉學生

后端實作

洗掉學生功能的實作,無非就是在servlet中通過request請求獲取用戶賬號id,然后呼叫業務功能洗掉學生,而業務功能是封裝了底層的sql操作,也就是一條delete陳述句

批量洗掉學生的實作,在servlet中獲取的是用戶賬號id陣列,只需遍歷呼叫業務邏輯方法即可

控制層實作

在控制層的user包下創建DoStudentDelect.java,代碼如下

package com.zhuo.controller.user;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;

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 com.zhuo.service.impl.UserServiceImpl;

@WebServlet("/manage/admin_do_student_delete")
public class DoStudentDelete extends HttpServlet {
	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();
		/* 呼叫業務邏輯方法洗掉學生 */
		int count = 0;
		try {
			count = userServiceImpl.removeStudentInfo(id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		/* 成功或失敗重定向到哪里 */
		if (count > 0) {
			response.sendRedirect("admin_do_student_select?currentPage=" + request.getParameter("currentPage"));
		} else {
			PrintWriter out = response.getWriter();
			out.write("<script>");
			out.write("alert('洗掉失敗')");
			out.write("location.href='admin_do_student_select?currentPage=" + request.getParameter("currentPage"));
			out.write("</script>");
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/* 設定字符編碼,解決中文亂碼問題 */
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=utf-8");
		/* 接收客戶端資訊 */
		String ids[] = request.getParameterValues("id[]");
		// 創建用戶service層介面的實作類
		UserServiceImpl userServiceImpl = new UserServiceImpl();
		int count = 0;
		/* 遍歷學生id程序中,呼叫業務邏輯方法洗掉學生 */
		for (int i = 0; i < ids.length; i++) {
			try {
				count = userServiceImpl.removeStudentInfo(ids[i]);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		/* 成功或失敗重定向到哪里 */
		if (count > 0) {
			response.sendRedirect("admin_do_student_select");
		} else {
			PrintWriter out = response.getWriter();
			out.write("<script>");
			out.write("alert('批量洗掉失敗')");
			out.write(
					"location.href='admin_do_student_select?currentPage=" + request.getParameter("currentPage") + "'");
			out.write("</script>");
		}
	}
}

通過上面的servlet可以知道,洗掉單個學生用的是get請求,也就是用戶點擊洗掉按鈕時會傳給servlet一個用戶id

批量洗掉學生資訊用的是post請求,顯然在頁面中需要提供表單,

在前面的學生管理頁面中,遍歷學生記錄的代碼恰好就放在form表單中,并且遍歷時還在表格中每一行的第一列提供了checkbox復選框,使用了EL運算式把checkbox的value設定為用戶id

這樣每一行的復選框就和每一行的用戶對應了,當用戶提交表單時會把選中的每一個復選框中的value值提交給servlet,這樣就可以實作批量洗掉學生記錄

業務邏輯層實作

在業務邏輯層的UserService介面中添加洗掉學生的業務邏輯抽象方法,如下

	// 洗掉學生
	public int removeStudentInfo(String userId) throws SQLException;

在業務邏輯層的實作類UserServiceImpl中重寫介面方法removeStudentInfo,如下

	@Override
	public int removeStudentInfo(String userId) throws SQLException {
		// 洗掉學生
		int i = userDao.deleteStudent(userId);
		return i;
	}

資料訪問層實作

在資料訪問層的UserDao介面中添加洗掉學生記錄的抽象方法,如下

	// 洗掉學生記錄
	public int deleteStudent(String userId) throws SQLException;

在資料訪問層的實作類UserDaoImpl中重寫介面方法deleteStudent,如下

	@Override
	public int deleteStudent(String userId) throws SQLException {
		// sql洗掉陳述句
		String sql = "delete from user where user_id=?";
		// 呼叫jdbc工具類執行sql陳述句
		int i = JDBCUtil.executeUpdate(sql, userId);
		return i;
	}

前端實作

用戶點擊洗掉和點擊批量洗掉都是通過js實作的,下面分別介紹

洗掉單個用戶

洗掉單個用戶是get請求,即當用戶點擊洗掉會發送get請求,那么只需使用超鏈接并把href的屬性值設定洗掉學生的servlet路徑即可

但是洗掉時需要提示一個對話框,詢問用戶是否洗掉,那么就需要使用confirm方法,代碼如下

/* 洗掉單個學生*/
function Delete(message, url) {
	// 確認提示框,若是則請求對應的url
	if (confirm(message)) {
		location.href = url;
	}
}

當用戶點擊洗掉便會執行這段j代碼,第一個引數是提示資訊,第二個引數是請求的servlet,這些引數在學生管理頁面中已給出

批量洗掉用戶

批量洗掉用戶是post請求,是通過表單提交的,所以js代碼需要獲取表單物件

checkbox復選框中的name屬性值都是id[],這樣在js通過name屬性值獲取就是checkbox物件陣列,那么就需要遍歷這些物件陣列,并檢查checkbox有沒有被選中,若沒被選中,則禁止提交表單,代碼如下

/* 批量洗掉所有學生*/
function deleteMore(message, formName) {
	// 確認提示框
	if (confirm(message)) {
		// 獲取表單物件
		var form = document.getElementById(formName);
		// 標識表單是否可以提交
		var flag = false;
		// 獲取所有checkbox物件
		var a = document.getElementsByName('id[]');
		/*遍歷checkbox物件,檢查checked值是否為true(即是否被選中)
		若未被選中,則禁止提交表單*/
		for (var i = 0; i < a.length; i++) {
			if (a[i].checked) {
				flag = true;
				break;
			}
		}
		/*判斷標識是否為true,若為true,則提交表單*/
		if (flag) {
			form.submit();
		} else {
			alert("請選擇學生后在批量洗掉!");
		}
	}
}

通過全選復選框選中所有checkbox

checkbox即可以通過點擊每一個復選框,也可以通過一個全選復選框來選擇所有的復選框,代碼如下

/*全選復選框*/
function selAll(o) { // o為全選按鈕物件
    // 獲取所有checkbox
	var a = document.getElementsByName('id[]');
	/*遍歷所有checkbox,并把checked值設定和全選復選框一樣*/
	for (var i = 0; i < a.length; i++) {
		a[i].checked = o.checked;
	}
}

到這里就可以測驗洗掉功能了,啟動專案

在這里插入圖片描述

修改學生

修改學生以及后面添加學生是和前面是類似,這里就不再說得那么詳細了,不懂得可以看注釋

后端實作

當點擊修改頁面時會請求servlet,servlet會通過request獲取賬號id并作為業務邏輯方法的引數被呼叫得到用戶資料,并放到請求域中,之后跳轉到學生修改頁面

在控制層的user包下創建ToStudentUpdate.java,代碼如下

package com.zhuo.controller.user;

import java.io.IOException;
import java.sql.SQLException;

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 com.zhuo.entity.User;
import com.zhuo.service.impl.UserServiceImpl;

@WebServlet("/manage/admin_to_student_update")
public class ToStudentUpdate extends HttpServlet {
	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();
		// 創建用戶物體
		User user = null;
		/* 呼叫業務邏輯方法獲取學生資訊 */
		try {
			user = userServiceImpl.getStudentInfo(id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		// 把學生的資訊放入請求作用域
		request.setAttribute("user", user);
		// 從請求域獲取到的當前頁放入請求作用域中
		request.setAttribute("currentPage", request.getParameter("currentPage"));
		// 請求轉發到學生資訊修改頁面
		request.getRequestDispatcher("/views/after/manage/admin_student_modify.jsp").forward(request, response);
	}
}

在業務邏輯層的UserService介面中添加獲取學生資訊的業務邏輯抽象方法,如下

	// 獲取學生資訊
	public User getStudentInfo(String userId) throws SQLException;

在業務邏輯層的實作類UserServiceImpl中重寫介面方法getStudentInfo,如下

	@Override
	public User getStudentInfo(String userId) throws SQLException {
		// 檢索學生資訊
		User user = userDao.selectStudent(userId);
		return user;
	}

在資料訪問層的UserDao介面中添加檢索學生資訊的抽象方法,如下

	// 檢索學生資訊
	public User selectStudent(String id) throws SQLException;

在資料訪問層的實作類UserDaoImpl中重寫介面方法selectStudent,如下

	@Override
	public User selectStudent(String id) throws SQLException {
		// sql檢索陳述句
		String sql = "select m.*, DATE_FORMAT(m.user_birthday, '%Y-%m-%d')birthday  from user m where USER_ID=?";
		// 呼叫jdbc工具類執行sql陳述句
		resultSet = JDBCUtil.executeQuery(sql, id);
		// 創建物體類
		User user = null;
		while (resultSet.next()) {
			user = new User(resultSet.getString("user_id"), resultSet.getString("user_password"),
					resultSet.getString("user_name"), resultSet.getString("user_sex"),
					resultSet.getString("user_birthday"), resultSet.getString("user_class"),
					resultSet.getString("user_level"));
		}
		return user;
	}

上面實作了獲取學生資訊跳轉的修改頁面,但還需要一個處理用戶提交修改學生資訊的servlet

處理修改頁面的servlet和獲取學生資訊是類似,區別是底層執行的update陳述句

在controller層的user包下創建DoStudentUpdate,代碼如下

package com.zhuo.controller.user;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;

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 com.zhuo.entity.User;
import com.zhuo.service.UserService;
import com.zhuo.service.impl.UserServiceImpl;

@WebServlet("/manage/admin_do_student_update")
public class DoStudentUpdate extends HttpServlet {
	protected void doPost(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 userSex = request.getParameter("userSex");
		String userBirthday = request.getParameter("userBirthday");
		String userClass = request.getParameter("userClass");
		String userLevel = request.getParameter("userLevel");
		// 創建用戶物體
		User user = new User(userId, userPassword, userName, userSex, userBirthday, userClass, userLevel);
		// 創建用戶service層介面的實作類
		UserServiceImpl userServiceImpl = new UserServiceImpl();
		/* 呼叫業務邏輯方法修改學生資訊 */
		int count = 0;
		try {
			count = userServiceImpl.modifyStudentInfo(user);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		/* 成功或失敗重定向到哪里 */
		if (count > 0) {
			response.sendRedirect("admin_do_student_select?currentPage=" + request.getParameter("currentPage"));
		} else {
			PrintWriter out = response.getWriter();
			out.write("<script>");
			out.write("alert('用戶修改失敗')");
			out.write("location.href='admin_to_student_update?id=" + userId + "'");
			out.write("</script>");
		}
	}
}

在service層的UserService介面中添加修改學生資訊的業務邏輯抽象方法如下

	// 修改學資訊
	public int modifyStudentInfo(User user) throws SQLException;

在service層的實作類UserServiceImpl中重寫介面方法modifyStudentInfo,如下

	@Override
	public int modifyStudentInfo(User user) throws SQLException{
		// 更新學生資訊
		int i = userDao.updateStudent(user);
		return i;
	}

在dao層的UserDao介面中添加更新學生資訊的抽象方法,如下

	// 更新學生資訊
	public int updateStudent(User user) throws SQLException;

在dao層的實作類UserDaoImpl中重寫介面方法updateStudent,如下

	@Override
	public int updateStudent(User user) throws SQLException {
		// sql更新陳述句
		String sql = "update user set user_name=?, user_password=?,user_sex=?,user_birthday=DATE_FORMAT(?, '%y-%m-%d'),user_class=? where user_id = ?";
		int i = JDBCUtil.executeUpdate(sql, user.getUserName(), user.getUserPassword(), user.getUserSex(),
				user.getUserBirthday(), user.getUserClass(), user.getUserId());
		return i;
	}

至此后端修改功能均已完成,現在撰寫前端代碼

后臺學生修改頁面

在manage檔案下創建admin_student_modify.jsp,代碼如下

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="admin_menu.jsp"%>
<div class="main-wrap">
	<div class="crumb-wrap">
		<div class="crumb-list">
			<i class="icon-font"> </i><a
				href="${pageContext.request.contextPath}/views/after/manage/admin_index.jsp">首頁</a>
			<span class="crumb-step">&gt;</span> <a class="crumb-name"
				href="${pageContext.request.contextPath}/manage/admin_do_student_select">學生管理</a>
			<span class="crumb-step">&gt;</span><span>修改用戶</span>
		</div>
	</div>
	<div class="result-wrap">
		<div class="result-content">
			<form
				action="${pageContext.request.contextPath}/manage/admin_do_student_update"
				method="post" id="myform" name="myform">
				<input type="hidden" name="userId" value="${user.userId }">
				<input type="hidden" name="currentPage" value="${currentPage }">
				<table class="insert-tab" width="100%">
					<tbody>
						<tr>
							<th><i class="require-red">*</i>學生姓名:</th>
							<td><input class="common-text required" id="title"
								name="userName" size="50" value="${user.userName }" type="text">
							</td>
						</tr>
						<tr>
							<th><i class="require-red">*</i>登錄密碼:</th>
							<td><input class="common-text required" id="title"
								name="userPassword" size="50" value="${user.userPassword }"
								type="text"></td>
						</tr>
						<tr>
							<th>性別:</th>
							<td><input type="radio" name="userSex" value='男'
								${user.userSex=='男'?"checked":"" }><input
								type="radio" name="userSex" value='女'
								${user.userSex=='女'?"checked":"" }></td>
						</tr>
						<tr>
							<th>出生日期:</th>
							<td><input class="common-text" name="userBirthday" size="50"
								value="${user.userBirthday }" type="text"></td>
						</tr>
						<tr>
							<th><i class="require-red">*</i>班級:</th>
							<td><input class="common-text required" id="title"
								name="userClass" size="50" value="${user.userClass }"
								type="text"></td>
						</tr>
						<tr>
							<th></th>
							<td><input class="btn btn-primary btn6 mr10" value="提交"
								type="submit"> <input class="btn btn6"
								onClick="history.go(-1)" value="回傳" type="button"></td>
						</tr>
					</tbody>
				</table>
			</form>
		</div>
	</div>
</div>
</div>
</body>
</html>

啟動專案,測驗

在這里插入圖片描述

添加單個學生

添加單個學生所需要做的是,當用戶點擊添加時,需要跳轉到學生添加頁面,也就是表單

用戶提交時,需要一個servlet來處理表單,即呼叫業務邏輯方法插入學生,但插入前需要先判讀賬號是否已經存在

后臺添加學生頁面

在manage檔案夾下創建admin_student_add.jsp,代碼如下

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="admin_menu.jsp"%>
<div class="main-wrap">
	<div class="crumb-wrap">
		<div class="crumb-list">
			<i class="icon-font"></i><a href="admin_index.jsp">首頁</a><span
				class="crumb-step">&gt;</span><a class="crumb-name"
				href="${pageContext.request.contextPath}/manage/admin_do_student_select">學生管理</a><span
				class="crumb-step">&gt;</span><span>添加學生</span>
		</div>
	</div>
	<div class="result-wrap">
		<div class="result-content">
			<form
				action="${pageContext.request.contextPath}/manage/admin_do_student_add"
				method="post" id="myform" name="myform">
				<table class="insert-tab" width="100%">
					<tbody>
						<tr>
							<th><i class="require-red">*</i>賬號:</th>
							<td><input class="common-text required" id="title"
								name="userId" size="50" value="" type="text" required></td>
						</tr>
						<tr>
							<th><i class="require-red">*</i>登錄密碼:</th>
							<td><input class="common-text required" id="title"
								name="userPassword" size="50" value="" type="password" required>
							</td>
						</tr>
						<tr>
							<th><i class="require-red">*</i>學生姓名:</th>
							<td><input class="common-text required" id="title"
								name="userName" size="50" value="" type="text" required>
							</td>
						</tr>
						<tr>
							<th><i class="require-red">*</i>性別:</th>
							<td><input type="radio" name="userSex" value="男"
								checked="checked" /><input type="radio" name="userSex"
								value="女" /></td>
						</tr>
						<tr>
							<th><i class="require-red">*</i>出生日期:</th>
							<td><input class="common-text required" id="title"
								name="userBirthday" size="50" value="" type="text" required>
							</td>
						</tr>
						<tr>
							<th><i class="require-red">*</i>班級:</th>
							<td><input class="common-text required" id="title"
								name="userClass" size="50" value="" type="text" required>
							</td>
						</tr>
						<tr>
							<th></th>
							<td><input class="btn btn-primary btn6 mr10" value="提交"
								type="submit"> <input class="btn btn6"
								onClick="history.go(-1)" value="回傳" type="button"></td>
						</tr>
					</tbody>
				</table>
			</form>
		</div>
	</div>
</div>
</div>
</body>
</html>

后端實作

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

package com.zhuo.controller.user;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;

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 com.zhuo.entity.User;
import com.zhuo.service.impl.UserServiceImpl;

@WebServlet("/manage/admin_do_student_add")
public class DoStudentAdd extends HttpServlet {
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/* 設定字符編碼,解決中文亂碼問題 */
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=utf-8");
		/* 接收客戶端資訊 */
		String userId = request.getParameter("userId");
		String userName = request.getParameter("userName");
		String userPassword = request.getParameter("userPassword");
		String userSex = request.getParameter("userSex");
		String userBirthday = request.getParameter("userBirthday");
		String userClass = request.getParameter("userClass");
		// 創建用戶物體
		User user = new User(userId, userPassword, userName,  userSex, userBirthday, userClass, "學生");
		// 創建用戶service層介面的實作類
		UserServiceImpl userServiceImpl = new UserServiceImpl();
		/* 呼叫業務邏輯方法檢查用戶是否重復,若查到則回傳count>0 */
		int count = 0;
		try {
			count = userServiceImpl.checkIdRepeated(userId);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		if (count > 0) {
			PrintWriter out = response.getWriter();
			System.out.println("out =" + out);
			out.write("<script>");
			out.write("alert('添加失敗,賬號已存在')");
			out.write("</script>");
			out.write("<script>");
			out.write("window.location='" + request.getContextPath() + "/views/after/manage/admin_student_add.jsp'");
			out.write("</script>");
		} else {
			/* 呼叫業務邏輯方法添加學生 */
			try {
				userServiceImpl.addStudent(user);
				response.sendRedirect("admin_do_student_select");
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

先通過request請求獲取添加學生的資訊,然后存放在用戶物體中,之后呼叫檢查賬號是否已經存在的業務邏輯方法

若不存在,接著呼叫添加學生的業務邏輯方法

若存在則回應給用戶添加失敗的資訊,并重新回傳到添加頁面

在service層的UserService介面中添加一個添加學生的業務邏輯方法,如下

	// 添加學生資訊
	public int addStudent(User user) throws SQLException;

在service層的實作類UserServiceImpl中重寫介面方法addStudent,如下

	@Override
	public int addStudent(User user) throws SQLException{
		// 插入學生
		int i = userDao.insertStudent(user);
		return i;
	}

在dao層的UserDao介面中添加插入學生的抽象方法,如下``

	// 插入學生資訊
	public int insertStudent(User user) throws SQLException;

在dao層的實作類UserDaoImpl中重寫介面方法insertStudent,如下

	@Override
	public int insertStudent(User user) throws SQLException {
		// sql插入陳述句
		String sql = "insert into user values(?, ?, ?, ?, DATE_FORMAT(?, '%Y-%m-%d'), ?, ?)";
		int i = JDBCUtil.executeUpdate(sql, user.getUserId(), user.getUserPassword(), user.getUserName(),
				user.getUserSex(), user.getUserBirthday(), user.getUserClass(), user.getUserLevel());
		return i;
	}

啟動專案測驗

在這里插入圖片描述

批量添加學生

jQuery easyUI的使用

批量添加學生是通過點擊按鈕彈出一個對話框來實作的,對話框包含一個表單和兩個按鈕(匯入,關閉),表單只使用一個input檔案型別的組件,點擊可彈出檔案對話框選擇檔案,這里使用JQuery easyUI實作這些操作

jQuery EasyUI 下載

在整體結構頁面admin_menu.jsp的head標簽內參考,如下

<link rel="stylesheet" type="text/css"
	href="${pageContext.request.contextPath}/views/jquery-easyui-1.6.10/themes/default/easyui.css">
<link rel="stylesheet" type="text/css"
	href="${pageContext.request.contextPath}/views/jquery-easyui-1.6.10/themes/icon.css">
<script type="text/javascript"
	src="${pageContext.request.contextPath}/views/jquery-easyui-1.6.10/jquery.min.js"></script>
<script type="text/javascript"
	src="${pageContext.request.contextPath}/views/jquery-easyui-1.6.10/jquery.easyui.min.js"></script>

在后臺學生管理頁面使用easyUI

前面說過批量添加學生不是一個頁面,而是一個對話框,含有表單以及兩個按鈕,在easyUI實作對話框,只需在jsp頁面中使用如下代碼

<div id="dlg" class="easyui-dialog" style="width: 370px;height: 250px;padding: 10px 20px"
     closed="true" buttons="#dlg-buttons">
</div>

表單要實作檔案上傳功能,需要在form內指定enctype屬性并把值設為multipart/form-data,即包含多部分資料的請求,且請求方式必須改為post,只需在jsp提供如下代碼

    <form id="fm" method="post" enctype="multipart/form-data">
            <input name="registerFile" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
            application/vnd.ms-excel" class="easyui-filebox" plain="true" data-options="buttonText:'選擇檔案'" required/>
    </form>

easyUI的表單不是通過提交上傳到服務器的,因為form表單即沒有指定action屬性,也沒有提供型別為submit的input組件

而是通過使用 easyui 表單(form)插件來改變表單(form)為 ajax 表單(form),表單(form)提交所有欄位到后臺服務器,服務器處理和發送一些資料回傳到前端頁面,我們接識訓傳資料,并將它顯示出來,這是通過在js撰寫腳本實作的,后面會給出

兩個按鈕(匯入,關閉),當點擊匯入會上傳檔案,即通過使用 easyui 表單(form)插件來改變表單(form)為 ajax 表單(form),當點擊關閉時關閉對話框,js代碼后面給出

<div id="dlg-buttons">
    <a href="javascript:upload()" class="easyui-linkbutton" iconCls="icon-ok">匯入</a>
    <a href="javascript:closeDialog()" class="easyui-linkbutton" iconCls="icon-cancel">關閉</a>
</div>

綜上,前面是代碼片段分析,要想真正的使用它們,需要在admin_student.jsp的body標簽之前使用即可,如下
在這里插入圖片描述

我們需要點擊按鈕彈出對話框,也就是上面給的代碼,需要下面的js代碼,如下

// url全域變數
var url;
/* 打開對話框 */
function openAddRegisterDialog() {
    $("#dlg").dialog("open").dialog("setTitle", "批量匯入帳號");
    url = "webresource/all_register?flagText=addRegister";
}

還需要一個點擊關閉按鈕,關閉對話框的js代碼,如下

/* 關閉對話框 */
function closeDialog() {
     $("#dlg").dialog("close");
 }

同理,點擊匯入時,需要把表單轉化為ajax上傳到服務器,js代碼如下

/* 上傳檔案 */
function upload() {
	$("#fm").form("submit", {
		url: url,
		onSubmit: function() {
			return $(this).form("validate");
		},
		success: function(result) {
			var json = $.parseJSON(result);
			console.info(json)
			if (json.success == "false") {
				$.messager.alert("系統提示", json.msg);
				return;
			} else {
				alert(json.msg);
				$("#dlg").dialog("close");
				$("#dg").datagrid("reload");
				window.location.reload();
			}
		}
	});
}

后端實作

由于客戶端表單不是普通的表單,而是martipart/form-data型別的,所有不能通過request請求獲取檔案,需要通過流實作,

Servlet3.0提供了專門的檔案上傳 API,HttpServletRequest的getPart()方法可以完成單個檔案上傳,而getParts()方法可以完成多個檔案上傳,但這里我不打算使用,而是使用第三方工具

使用第三方工具上傳

使用第三方工具,可以鍛煉使用其他技術的能力,因為要使用它 ,就需要閱讀檔案

可以完成上傳功能的第三方工具很多,但比較著名的是Apache 的 FileUpload 工具,該工具可以Apache 的官網上下載,Apache 的官網為: http://apache.org

FileUpload工具下載

FileUpload工具存放在Apacher的 Commons 中,所以需要在Commons下載

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

IO包下載

進一步跟蹤該Jar包的資訊,會看到如下注意:該版本需要依賴于Apache的Commons下的IO2.2的包,

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

官網用戶向導

打開Apache官網的檔案上傳主頁的用戶向導User guide,其中就有使用FileUpload 工具實作檔案上傳的示例,

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

代碼實作基本上傳

首先需要在專案的webapp下新建一個目錄 upload,用于保存上傳的檔案,

然后在controller層的user包下創建AllRegisterServlet.java,下面給出檔案上傳主要代碼實作

	try {
			// 1.判斷請求是否為Multipart請求
			if (!ServletFileUpload.isMultipartContent(request)) {
				throw new RuntimeException("該請求不能完成檔案上傳");
			}
			// 2.創建檔案項工廠
			DiskFileItemFactory factory = new DiskFileItemFactory();
			// 3.創建檔案上傳核心組件
			ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
			// 4.決議Multipart請求,獲取所有請求體正文中的item
			List<FileItem> fileItems = servletFileUpload.parseRequest(request);
			// 5.決議每個請求正文體中的item
			for (FileItem item : fileItems) {
				if(item.isFormField()) {   //若item為普通引數
					 //獲取引數名
					String fieldName = item.getFieldName();
					//獲取引數值
					String fieldValue = item.getString(); 
					System.out.println(fieldName + " : " + fieldValue);
				} else {
					//獲取檔案名
					String fileName = item.getName(); 
					// 獲取輸入流
					InputStream is = item.getInputStream();
					// 獲取images真實路徑
					String path = this.getServletContext().getRealPath("/upload");
					/* 創建輸出流 */
					File desFile = new File(path, fileName);
					// 獲取資源路徑
					registerFilePath = desFile.getPath();
					FileOutputStream fos = new FileOutputStream(desFile);
					/* 完成檔案復制 */
					byte[] bytes = new byte[1024];
					int len = -1;
					while((len = is.read(bytes)) != -1) {
						fos.write(bytes, 0, len);
					}
					/* 關閉流 */
					fos.close();
					is.close();
				}
			}
		}catch (FileUploadException e) {
			e.printStackTrace();
		}

上面代碼只是解決檔案上傳功能,但還存在如下問題

  • 當用戶從表單中提交的普通引數包含中文字符時,會出現亂碼問題,
  • 當上傳檔案的檔案名包含中文時,上傳到服務器的檔案名會出現亂碼,
  • 不同的瀏覽器,向服務器上傳的檔案名是不同的,即 Fileltem的getName()方法獲取到的檔案名是不同的,例如,用戶從客戶端上傳了D:\abc\xxx.jpg檔案,火狐瀏覽器上傳的檔案名為xxx.jpg,而IE瀏覽器上傳的檔案名為D:\abc\xxx.jpg,
  • 不同的用戶若提交了相同的檔案名的檔案,后面的用戶的檔案將無法上傳,

解決這些問題的思路:

解決普通引數的中文亂碼問題,只需使用Fileltem 的帶參getString(String Encoding)方法獲取引數名即可,

上傳檔案名的中文亂碼問題,需要通過ServletFileUpload的方法setHeadEncoding()指定上傳檔案請求頭部編碼的方式解決,不過,需要注意的是,該設定方式不會改變普通引數請求頭部的編碼,

為了解決瀏覽器向服務器發送檔案名不同這個問題,需要使用string的substring()方法截取出檔案名,因為檔案名一定是最后一個"\"后面部分,

對于相同檔案名的上傳問題,只需要使保存在服務器端的檔案名稱唯一即可,例如,為原始檔案名前添加一個當前系統時間System.currentTimeMillis()

修改后的代碼如下
在這里插入圖片描述

完成到這里,基本的功能都實作了,但還是可以繼續優化到最優的,下面進行介紹

無論是 Windows系統、Linux系統,還是其它系統,其目錄中所包含的檔案數量是有上限的,

所以對于上傳的檔案,應該分目錄進行管理,若檔案不是太多,可以在 upload 下按照yyyyMMdd日期格式再建一級子目錄,若檔案較多,則可按照年、月、日創建多級子目錄,這樣,即方便管理,又不會超出目錄的檔案數量上限,

下面按照yyyyMMdd日期格式進行優化,優化后代碼如下
在這里插入圖片描述

至此,檔案上傳就實作了,之后就是決議上傳的檔案資料進行注冊

也就是說servlet除了處理用戶提交的檔案還需要做下面三件事

  1. 通過呼叫業務方法提取用戶上傳的檔案里所有用戶資訊
  2. 獲取到所有用戶資訊后需要遍歷,然后呼叫業務方法檢查用戶名是否存在,若不存在,執行第三步
  3. 呼叫業務方法注冊用戶

主要代碼如下

		// 創建用戶service層介面的實作類
		UserServiceImpl userServiceImpl = new UserServiceImpl();
		// 創建存放用戶的list集合
		ArrayList<User> listUser = new ArrayList<User>();
		try {
			// 呼叫業務邏輯方法獲取所有學生資訊
			listUser = userServiceImpl.getAllStudent(registerFilePath);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		// 存放注冊成功的學生人數
		int number = 0;
		if (listUser != null) { //list集合不為null
			/* 遍歷集合,先檢查用戶名是否存在,若不存在呼叫業務方法注冊學生 */
			for (int i = 0; i < listUser.size(); i++) {
				User user = listUser.get(i);
				String userId = user.getUserId();
				int count = 0;
				try {
					count = userServiceImpl.checkIdRepeated(userId);
					number++;
				} catch (SQLException e) {
					e.printStackTrace();
				}
				if (count > 0) {
					System.out.println("已存在:" + user.getUserId());
				} else {
					try {
						userServiceImpl.register(user);
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
			}
			// 定義map用于給客戶回應
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("success", "true");
			map.put("msg", "成功匯入" + number + "條記錄");
            // map存放在json中
			result = JSON.toJSONString(map);
			// 清楚map
			map.clear();
			if (result != null) {
				// 輸出流
				PrintWriter out = response.getWriter();
				// 回應給客戶
				out.write(result);
			}
		}

上面用到了提取檔案獲取所有學生資訊的業務方法,也就是需要決議用戶上傳的檔案

在service層的UserService介面中添加提取檔案獲取所有學生資訊的抽象方法,如下

	// 提取檔案里的所有學生資訊
	public ArrayList<User> getAllStudent(String registerFilePath) throws SQLException;
}

在service層的實作類UserServiceImpl中重寫介面方法getAllRegister,如下

	@Override
	public ArrayList<User> getAllStudent(String registerFilePath) throws SQLException {
		//決議檔案獲取所有學生資訊
		ArrayList<User> listUser = userDao.analyzeFile(registerFilePath);
		return listUser;
	}

service層只是呼叫dao層,也就是具體的底層操作,即決議檔案獲取學生資訊是dao層完成的,而service層只是提現業務功能

在dao層的UserDao介面中添加決議檔案獲取所有學生的抽象方法,如下

	// 決議檔案獲取所有學生資訊
	public ArrayList<User> analyzeFile(String registerFilePath) throws SQLException;

在dao層的實作類UserDaoImpl中重寫介面方法analyzeFile,如下

	@Override
	public ArrayList<User> analyzeFile(String registerFilePath) throws SQLException {
		ArrayList<User> listUser = new ArrayList<User>();
		int i = 0;
		Sheet sheet;
		Workbook book;
		Cell cell1, cell2, cell3, cell4, cell5, cell6, cell7;
		try {
			book = Workbook.getWorkbook(new File(registerFilePath));
			sheet = book.getSheet(0);
			int col = sheet.getColumns();
			int row = sheet.getRows();
			i = 0;
			if (col > 0 && row > 0) {
				while (i < row) {
					User user = new User();
					// 獲取每一行的單元格
					if (!sheet.getCell(0, i).getContents().equals("")) {
						cell1 = sheet.getCell(0, i);// (列,行)帳號
						cell2 = sheet.getCell(1, i);// 密碼
						cell3 = sheet.getCell(2, i);// 姓名
						cell4 = sheet.getCell(3, i);// 年齡
						cell5 = sheet.getCell(4, i);// 生日
						cell6 = sheet.getCell(5, i);// 班級
						cell7 = sheet.getCell(6, i);// 等級
						if (cell1.getContents().equals(""))// 如果讀取的資料為空
						{
							break;
						}
						user.setUserId(cell1.getContents());
						user.setUserPassword(cell2.getContents());
						user.setUserName(cell3.getContents());
						user.setUserSex(cell4.getContents());
						user.setUserBirthday(cell5.getContents());
						user.setUserClass(cell6.getContents());
						user.setUserLevel(cell7.getContents());
						listUser.add(user);
						i++;
					}
				}
			}
			book.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listUser;
	}

底層操作使用了第三方工具庫jxl決議excel表格,因為存放資料一般都是使用excel的,這里我就默認excel了,jxl第三方工具jar包可以自行網上下載

到此,批量添加學生的功能就完成了,專案結構如下
在這里插入圖片描述

在這里插入圖片描述

啟動專案測驗

在這里插入圖片描述

教師管理和學生管理是類似的,就不講了,下一篇更新資源管理

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

標籤:其他

上一篇:canvas學習(html5)畫畫

下一篇:學會用taro封裝一個組件

標籤雲
其他(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