生信息管理系統(tǒng)JavaWeb課設(shè):從解壓到部署排錯(cuò)全指南)
簡(jiǎn)介這是一份基于 Java Web 技術(shù)棧開(kāi)發(fā)的學(xué)生信息管理系統(tǒng)源碼包使用 JSP 與 Servlet 編寫(xiě)頁(yè)面展示和業(yè)務(wù)邏輯借助 MySQL 完成學(xué)生數(shù)據(jù)的持久化存儲(chǔ)面向 Java 初學(xué)者、高校課程設(shè)計(jì)及畢業(yè)設(shè)計(jì)人群。系統(tǒng)實(shí)現(xiàn)了學(xué)生信息的錄入、查詢(xún)、修改、刪除等基礎(chǔ)增刪改查功能項(xiàng)目目錄結(jié)構(gòu)完整、分層清晰適合作為理解 MVC 模式與數(shù)據(jù)庫(kù)交互的入門(mén)練習(xí)。資源共三十個(gè)文件以十五個(gè) JSP 頁(yè)面構(gòu)成主要展示與交互層另含 Java 類(lèi)、XML 配置、數(shù)據(jù)庫(kù)驅(qū)動(dòng) jar 包及工程描述文件壓縮包整體約 2.15MB輕量便于快速部署。目前已有 4341 人學(xué)習(xí)下載。開(kāi)發(fā)者可將項(xiàng)目導(dǎo)入集成開(kāi)發(fā)環(huán)境直接運(yùn)行調(diào)試結(jié)合配套博文理清前后端數(shù)據(jù)流轉(zhuǎn)也可在此基礎(chǔ)上擴(kuò)展條件查詢(xún)、分頁(yè)展示或權(quán)限管理等模塊功能。1. 學(xué)生信息管理系統(tǒng)javaWeb.zip是什么一份能跑的課設(shè)代碼不是拿來(lái)就能跑你從某個(gè)資源站下載了“學(xué)生信息管理系統(tǒng)_javaWeb.zip”解壓后看到一堆文件夾和散亂的jar包第一反應(yīng)大概率是“這到底怎么打開(kāi)”。這個(gè)zip里裝的是一個(gè)典型的javaWeb課設(shè)項(xiàng)目JSP做頁(yè)面Servlet做控制JDBC寫(xiě)MySQL數(shù)據(jù)庫(kù)標(biāo)準(zhǔn)的三層結(jié)構(gòu)。它能幫你完成課程設(shè)計(jì)、畢業(yè)設(shè)計(jì)或者用來(lái)搞懂一個(gè)javaWeb項(xiàng)目從前端到數(shù)據(jù)庫(kù)的完整調(diào)用鏈。但我要先說(shuō)句實(shí)話(huà)這類(lèi)zip本身只保證代碼完整不保證你本機(jī)能直接跑通。你缺的是環(huán)境匹配、部署配置和排錯(cuò)思路。這篇筆記就是讓你從解壓到瀏覽器里看到學(xué)生列表再把常見(jiàn)翻車(chē)點(diǎn)一個(gè)個(gè)排掉。2. 環(huán)境準(zhǔn)備JDK、Tomcat、MySQL和IDEA的版本怎么搭才不會(huì)開(kāi)局翻車(chē)2.1 JDK與Tomcat版本配對(duì)先避免ClassNotFoundException和無(wú)效卡死拿到這個(gè)zip先別急著雙擊導(dǎo)入IDEA。我處理過(guò)太多“啟動(dòng)Tomcat直接崩潰”的案例九成是版本不匹配。典型的javaWeb學(xué)生管理系統(tǒng)用的是javax.servlet包這是Tomcat 9及之前版本的包名。如果你裝了Tomcat 10或更高版本包名變成了jakarta.servlet運(yùn)行會(huì)直接報(bào)NoClassDefFoundError或ClassNotFoundException。我一般建議的組合JDK 8 Tomcat 9 MySQL 5.7/8.0 IDEA 2022以后任意版本。JDK 8雖然老但兼容性最好很多課設(shè)代碼里用了JDK 8的語(yǔ)法特性換成JDK 11或17容易出現(xiàn)某些API被移除的兼容性問(wèn)題。Tomcat 9支持Servlet 4.0對(duì)javax包支持完整。IDEA從2021版開(kāi)始內(nèi)置了Tomcat集成不用額外裝插件。版本對(duì)應(yīng)關(guān)系大致如下組件推薦版本說(shuō)明JDK1.8大多數(shù)課設(shè)編譯目標(biāo)避免新JDK的模塊化坑Tomcat9.0.x使用javax.servlet與老項(xiàng)目匹配MySQL5.7 或 8.05.7連接串多一個(gè)useSSL參數(shù)8.0需要serverTimezonemysql-connector-java5.1.49配5.7、8.0.33配8.0驅(qū)動(dòng)類(lèi)名不同注意區(qū)分IDEA2022.3 / 2023.x直接支持Tomcat運(yùn)行配置如果你打開(kāi)項(xiàng)目看到j(luò)avax.servlet.http.HttpServlet這個(gè)import那就老老實(shí)實(shí)用Tomcat 9。如果看到j(luò)akarta.servlet請(qǐng)換Tomcat 10。這類(lèi)zip八成是前者。2.2 用IDEA導(dǎo)入javaWeb項(xiàng)目從open到Artifact配置的完整步驟很多人用IDEA直接Open這個(gè)解壓目錄然后發(fā)現(xiàn)沒(méi)有“運(yùn)行”按鈕或者運(yùn)行后頁(yè)面404。因?yàn)镮DEA不會(huì)自動(dòng)把普通目錄識(shí)別成Web項(xiàng)目。步驟是File - Open選中解壓后的文件夾以Project方式打開(kāi)。如果IDEA提示是否信任選信任。確認(rèn)項(xiàng)目SDKFile - Project Structure - Project設(shè)置Project SDK為1.8Project language level為8。找到web/WEB-INF/web.xml或WebContent/WEB-INF/web.xml確認(rèn)它存在。這是web項(xiàng)目入口。設(shè)置ArtifactFile - Project Structure - Artifacts點(diǎn)選Web Application: ExplodedFrom module選擇你的模塊。這里IDEA會(huì)自動(dòng)識(shí)別web.xml和web根目錄。添加依賴(lài)庫(kù)在Project Structure - Libraries里把lib目錄下的jar包全部加進(jìn)去重點(diǎn)是mysql驅(qū)動(dòng)和servlet-api。如果項(xiàng)目里用Maven則檢查pom.xml但這zip多半是普通目錄外加一個(gè)lib文件夾。配置TomcatRun - Edit Configurations - - Tomcat Server - Local在Application server里選你本機(jī)Tomcat路徑默認(rèn)端口8080不變。關(guān)鍵點(diǎn)是第4步Artifact如果沒(méi)配置好Tomcat啟動(dòng)后訪問(wèn)的永遠(yuǎn)是http://localhost:8080/而不是/項(xiàng)目名/。你需要在Deployment標(biāo)簽頁(yè)里把Artifact加進(jìn)去Application context填項(xiàng)目名比如填/student那么頁(yè)面地址就是http://localhost:8080/student/。2.3 MySQL 8和mysql-connector-java的兼容選擇這個(gè)zip里可能自帶了mysql驅(qū)動(dòng)jar包但你最好檢查一下版本。老項(xiàng)目里常見(jiàn)的是mysql-connector-java-5.1.x對(duì)應(yīng)MySQL 5.7沒(méi)問(wèn)題但如果你本機(jī)裝的是MySQL 8.0連接代碼用com.mysql.jdbc.Driver會(huì)提示不支持而且URL里必須加serverTimezone否則報(bào)The server time zone value is unrecognized。MySQL 8下正確做法是改用com.mysql.cj.jdbc.DriverURL寫(xiě)成這樣jdbc:mysql://localhost:3306/student_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8參數(shù)說(shuō)明useSSLfalse是本地開(kāi)發(fā)必須否則MySQL 8會(huì)提示SSL連接警告serverTimezoneAsia/Shanghai是讓驅(qū)動(dòng)知道時(shí)區(qū)不填會(huì)直接報(bào)錯(cuò)characterEncodingutf8保證中文寫(xiě)入不亂碼。如果你用的是5.7可以只用useSSLfalse時(shí)區(qū)也能留空。如果zip里的驅(qū)動(dòng)是5.x版本而你連的是MySQL 8最省事的方案是去下載一個(gè)mysql-connector-java-8.0.33.jar替換掉lib里的舊jar包同時(shí)把代碼里的Class.forName(com.mysql.jdbc.Driver)改成com.mysql.cj.jdbc.Driver。不要抱著“能少改就少改”的心態(tài)驅(qū)動(dòng)不匹配會(huì)在第5章列出一堆連鎖問(wèn)題。3. 數(shù)據(jù)庫(kù)設(shè)計(jì)與連接串建表SQL和JDBC參數(shù)這樣寫(xiě)3.1 學(xué)生、班級(jí)、用戶(hù)三張表SQL建表語(yǔ)句與字段說(shuō)明學(xué)生信息管理系統(tǒng)最少需要三張表學(xué)生表、班級(jí)表、用戶(hù)表。班級(jí)表和學(xué)生表是主外鍵關(guān)系用戶(hù)表單獨(dú)存登錄賬號(hào)。打開(kāi)zip里通常有個(gè)db.sql或schema.sql沒(méi)有的話(huà)自己建也快。以MySQL 8為例建表語(yǔ)句如下CREATE DATABASE IF NOT EXISTS student_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE student_db; CREATE TABLE t_class ( id INT PRIMARY KEY AUTO_INCREMENT, class_name VARCHAR(50) NOT NULL UNIQUE, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE t_student ( id INT PRIMARY KEY AUTO_INCREMENT, student_no VARCHAR(20) NOT NULL UNIQUE, name VARCHAR(50) NOT NULL, gender TINYINT DEFAULT 0 COMMENT 0-男 1-女, birthday DATE, class_id INT, phone VARCHAR(20), address VARCHAR(200), FOREIGN KEY (class_id) REFERENCES t_class(id) ON DELETE SET NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(30) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, real_name VARCHAR(50) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; INSERT INTO t_user (username, password, real_name) VALUES (admin, 123456, 管理員);參數(shù)說(shuō)明utf8mb4比utf8多支持emoji和特殊字符課設(shè)推薦直接用ON DELETE SET NULL表示刪除班級(jí)時(shí)學(xué)生記錄的class_id置空避免外鍵約束沖突。password字段先存明文是原項(xiàng)目常見(jiàn)坑后面第6章我給改法。3.2 JDBC連接代碼驅(qū)動(dòng)注冊(cè)、URL參數(shù)、增刪改查骨架zip里的項(xiàng)目通常會(huì)有一個(gè)DBUtil.java或JdbcUtil.java作用就是給所有DAO提供一個(gè)連接對(duì)象。不好的寫(xiě)法是每個(gè)DAO里重復(fù)寫(xiě)驅(qū)動(dòng)注冊(cè)和連接創(chuàng)建。我建議你把它統(tǒng)一成一個(gè)工具類(lèi)后續(xù)改連接串只改一處。下面是基于MySQL 8的寫(xiě)法import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class DBUtil { private static final String DRIVER com.mysql.cj.jdbc.Driver; private static final String URL jdbc:mysql://localhost:3306/student_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8; private static final String USER root; private static final String PASSWORD 你的密碼; static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } }邏輯說(shuō)明靜態(tài)代碼塊保證驅(qū)動(dòng)只注冊(cè)一次getConnection()每次調(diào)用返回新連接。這種方式適合課設(shè)雖然沒(méi)用連接池但量小無(wú)所謂。注意PASSWORD里的“你的密碼”要改成你自己MySQL的root密碼如果密碼中有特殊字符如、#建議把URL和密碼都放到單獨(dú)配置文件中不過(guò)課設(shè)階段直接寫(xiě)死也能接受。增刪改查的骨架代碼長(zhǎng)這樣public boolean addStudent(Student s) { String sql INSERT INTO t_student (student_no, name, gender, birthday, class_id, phone, address) VALUES (?,?,?,?,?,?,?); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, s.getStudentNo()); ps.setString(2, s.getName()); ps.setInt(3, s.getGender()); ps.setDate(4, new java.sql.Date(s.getBirthday().getTime())); ps.setInt(5, s.getClassId()); ps.setString(6, s.getPhone()); ps.setString(7, s.getAddress()); return ps.executeUpdate() 0; } catch (SQLException e) { e.printStackTrace(); } return false; }參數(shù)說(shuō)明這里用PreparedStatement而不是Statement能防SQL注入也是課設(shè)答辯的加分項(xiàng)。所有字段值都用?占位再按索引set進(jìn)去順序不能亂。getBirthday()返回的是java.util.Date而數(shù)據(jù)庫(kù)列是DATE類(lèi)型所以需要轉(zhuǎn)成java.sql.Date這是一個(gè)容易忽略的編譯期不報(bào)錯(cuò)但運(yùn)行期插入失敗的點(diǎn)。3.3 密碼字段為什么不建議用varchar直接存我看過(guò)大量javaWeb課設(shè)用戶(hù)表密碼都是明文。比如上面SQL里直接INSERT123456。這不影響運(yùn)行但你在答辯時(shí)會(huì)被問(wèn)“密碼安全性”。哪怕不做復(fù)雜加密至少用MD5加鹽處理一下這屬于低成本高收益的改進(jìn)。改造后再寫(xiě)登錄判斷時(shí)比對(duì)的是MD5(密碼鹽)的結(jié)果而不是明文。具體代碼在第6章給出。如果你現(xiàn)在只是想讓項(xiàng)目跑起來(lái)可以先不動(dòng)這行SQL。但記得把默認(rèn)密碼設(shè)成統(tǒng)一值方便自己登錄測(cè)試。常見(jiàn)的初始賬號(hào)在web.xml或說(shuō)明文檔里會(huì)寫(xiě)不寫(xiě)的話(huà)DBA類(lèi)代碼里也能搜到。我習(xí)慣先在數(shù)據(jù)庫(kù)里執(zhí)行一次插入再整理到初始化SQL腳本里。4. 部署到Tomcat從IDEA里跑通到瀏覽器訪問(wèn)的完整流程4.1 配置Tomcat與Artifact一步都不能少的設(shè)置環(huán)境、數(shù)據(jù)庫(kù)都準(zhǔn)備好后開(kāi)始部署。打開(kāi)IDEA的Run - Edit Configurations點(diǎn)選Tomcat Server - Local。在Server標(biāo)簽頁(yè)里指定Tomcat安裝目錄我本機(jī)裝在C:\apache-tomcat-9.0.89IDEA會(huì)自動(dòng)識(shí)別版本。默認(rèn)端口是8080如果你的8080被占用了改成8081、9090都行但注意改完后面訪問(wèn)地址也要跟著變。關(guān)鍵在Deployment標(biāo)簽頁(yè)。點(diǎn)選Artifact會(huì)彈出一個(gè)類(lèi)似student:war exploded的選項(xiàng)。這里要選帶exploded的那個(gè)它表示展開(kāi)目錄部署開(kāi)發(fā)時(shí)改了代碼不用重新打war包熱部署效果更好。選完之后下方Application context填/student這是你瀏覽器里的路徑名。如果你填成/表示根路徑那訪問(wèn)時(shí)就不帶項(xiàng)目名。配置完啟動(dòng)??吹娇刂婆_(tái)輸出Server startup in [xxx] ms就說(shuō)明Tomcat起來(lái)了。此時(shí)打開(kāi)瀏覽器輸入http://localhost:8080/student/應(yīng)該能看到登錄頁(yè)或首頁(yè)。如果看到404先檢查Application context和URL是否一致再看Tomcat日志有沒(méi)有報(bào)錯(cuò)。4.2 啟動(dòng)后驗(yàn)證訪問(wèn)學(xué)生列表頁(yè)并完成一次增刪改查項(xiàng)目起沒(méi)起來(lái)不能只看能打開(kāi)頁(yè)面。我建議按這個(gè)順序驗(yàn)證一條完整鏈路先用SQL客戶(hù)端執(zhí)行SELECT * FROM t_user確認(rèn)管理員賬號(hào)還在。在瀏覽器登錄頁(yè)輸入用戶(hù)名密碼點(diǎn)登錄。如果跳轉(zhuǎn)到了學(xué)生列表頁(yè)說(shuō)明登錄Servlet和Session沒(méi)問(wèn)題。在列表頁(yè)點(diǎn)“新增學(xué)生”填寫(xiě)基本信息提交。然后回?cái)?shù)據(jù)庫(kù)查t_student看有沒(méi)有數(shù)據(jù)進(jìn)來(lái)。能查到的同時(shí)頁(yè)面上列表也出現(xiàn)了這條記錄說(shuō)明JDBC的INSERT和SELECT都通了。點(diǎn)“修改”把姓名改掉再點(diǎn)“刪除”刷新數(shù)據(jù)庫(kù)確認(rèn)記錄消失。這四個(gè)操作覆蓋了Servlet、JSP、DAO和數(shù)據(jù)庫(kù)連接的全部環(huán)節(jié)。如果其中一步斷了再回頭看第5章的排查表。Tomcat日志的位置默認(rèn)在Tomcat安裝目錄的logs文件夾下IDEA運(yùn)行時(shí)也會(huì)把控制臺(tái)輸出打印出來(lái)。重點(diǎn)看localhost.2025-xx-xx.log和catalina.out??刂婆_(tái)里有異常堆棧時(shí)先看Caused by后面的內(nèi)容那才是問(wèn)題的根源。比如常見(jiàn)的Access denied for user rootlocalhost就出現(xiàn)在Caused by里而不是第一行。5. javaWeb學(xué)生項(xiàng)目避坑指南5個(gè)典型翻車(chē)點(diǎn)與排查路徑5.1 中文亂碼JSP、Servlet、數(shù)據(jù)庫(kù)連接三處都要UTF-8現(xiàn)象登錄之后頁(yè)面上學(xué)生姓名全是問(wèn)號(hào)“???”或亂碼。原因三層都可能有鍋。JSP頁(yè)面沒(méi)寫(xiě)pageEncodingServlet里沒(méi)設(shè)置請(qǐng)求和響應(yīng)編碼數(shù)據(jù)庫(kù)連接串里沒(méi)指定characterEncoding。解決按順序檢查。JSP開(kāi)頭加上% page contentTypetext/html;charsetUTF-8 pageEncodingUTF-8 %Servlet里在doGet或doPost開(kāi)頭加request.setCharacterEncoding(utf-8)和response.setContentType(text/html;charsetutf-8)數(shù)據(jù)庫(kù)連接串確保已帶上characterEncodingutf8。如果還亂碼檢查HTML頁(yè)面meta標(biāo)簽里是否是charsetutf-8。這三處都改過(guò)來(lái)中文亂碼基本絕跡。5.2 登錄后跳轉(zhuǎn)404表單提交路徑和Servlet映射不一致現(xiàn)象登錄按鈕點(diǎn)擊后瀏覽器地址欄變成了某個(gè)路徑然后就是404頁(yè)面。比如表單寫(xiě)的actionlogin但Servlet用注解WebServlet(/LoginServlet)。原因這是javaWeb項(xiàng)目里最常見(jiàn)的手誤。表單action、超鏈接href、Servlet的映射路徑、web.xml中url-pattern只要有一個(gè)不一致就找不到目標(biāo)。解決打開(kāi)登錄頁(yè)的JSP或HTML看form標(biāo)簽的action屬性再去看LoginServlet上的WebServlet注解。讓兩者保持一致。比如action寫(xiě)法是login.do注解就寫(xiě)WebServlet(/login.do)。如果用的是web.xml配置檢查servlet-mapping里的url-pattern。改完重啟Tomcat再試。5.3 數(shù)據(jù)庫(kù)拒絕連接MySQL服務(wù)沒(méi)啟、密碼錯(cuò)、驅(qū)動(dòng)版本亂現(xiàn)象點(diǎn)擊任何涉及數(shù)據(jù)庫(kù)的功能頁(yè)面報(bào)錯(cuò)或白屏后臺(tái)日志顯示Communications link failure或Access denied for user rootlocalhost。原因MySQL服務(wù)沒(méi)啟動(dòng)是最多的其次是密碼不一致然后是驅(qū)動(dòng)和MySQL版本不匹配。解決先檢查MySQL服務(wù)狀態(tài)Windows下打開(kāi)服務(wù)管理器確認(rèn)MySQL80或你的服務(wù)名在運(yùn)行。然后在IDEA里直接執(zhí)行一條查詢(xún)測(cè)試連接比如運(yùn)行DBUtil的main方法。如果報(bào)Access denied把DBUtil里的密碼改成MySQL實(shí)際密碼。如果報(bào)The server time zone value按3.2的URL加上時(shí)區(qū)參數(shù)。如果報(bào)Unknown initial character set index說(shuō)明驅(qū)動(dòng)太老或太新?lián)Q匹配版本。5.4 無(wú)法加載驅(qū)動(dòng)mysql-connector-java的jar包位置與依賴(lài)范圍現(xiàn)象運(yùn)行項(xiàng)目時(shí)控制臺(tái)報(bào)java.lang.ClassNotFoundException: com.mysql.jdbc.Driver。原因驅(qū)動(dòng)jar包沒(méi)被Tomcat加載或者在IDEA項(xiàng)目里沒(méi)有被編譯到WEB-INF/lib目錄。解決這個(gè)坑我踩過(guò)很多次。先確認(rèn)lib目錄下有mysql驅(qū)動(dòng)jar包然后在IDEA里打開(kāi)Project Structure - Artifacts看Output Layout里有沒(méi)有把lib下的jar包打包進(jìn)WEB-INF/lib。沒(méi)有的話(huà)右鍵Available Elements里的jar包選Put into Output Root。如果你用Tomcat跑還需要在Run Configuration里確認(rèn)依賴(lài)范圍不要選provided要選compile或runtime。改完后重新部署。如果項(xiàng)目是Maven結(jié)構(gòu)的則檢查pom.xml里mysql依賴(lài)的scope不能是provided。5.5 頁(yè)面取不到數(shù)據(jù)ResultSet關(guān)閉過(guò)早與Bean屬性命名問(wèn)題現(xiàn)象列表頁(yè)能打開(kāi)但顯示“暫無(wú)數(shù)據(jù)”數(shù)據(jù)庫(kù)中明明有記錄?;蛘吣硞€(gè)字段值顯示不出來(lái)比如性別顯示成0/1毛坯而不是“男/女”。原因兩種可能性。第一種是DAO里在ResultSet還沒(méi)遍歷完就關(guān)閉了Connection或PreparedStatement導(dǎo)致后續(xù)讀取異常。第二種是JSP里用${student.name}取值但Student類(lèi)的getter方法名和屬性名對(duì)不上比如屬性是studentNogetter方法寫(xiě)成了getStudentno()EL表達(dá)式取不到值。解決把DAO代碼里所有關(guān)閉資源的操作放在finally塊或try-with-resources中確保先遍歷完再關(guān)閉。檢查JavaBean的屬性命名IDEA里自動(dòng)生成getter/setter不要手寫(xiě)。性別顯示問(wèn)題可以在Student屬性里加一個(gè)字符串類(lèi)型的genderStr在DAO查詢(xún)時(shí)根據(jù)gender字段轉(zhuǎn)換或者在JSP里用三元表達(dá)式。6. 把這些功能加上課設(shè)才能從“跑通”變成“能答辯”6.1 用Filter做登錄攔截三行配置保護(hù)所有頁(yè)面現(xiàn)在的系統(tǒng)如果別人知道列表地址直接訪問(wèn)就能繞過(guò)登錄。加一個(gè)Filter把所有頁(yè)面請(qǐng)求攔截下來(lái)檢查Session里有沒(méi)有登錄標(biāo)記這是成本最低的安全功能。WebFilter(/*) public class LoginFilter implements Filter { Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) res; Object user request.getSession().getAttribute(user); String path request.getRequestURI(); if (user null !path.endsWith(login.jsp) !path.endsWith(login)) { response.sendRedirect(request.getContextPath() /login.jsp); return; } chain.doFilter(req, res); } }邏輯說(shuō)明WebFilter(/*)攔截所有URL但要讓開(kāi)登錄頁(yè)、登錄接口和靜態(tài)資源。上面代碼里先判斷Session里有沒(méi)有user對(duì)象沒(méi)有就去攔截否則放行。注意request.getContextPath()拿到的是項(xiàng)目路徑這樣可以拼出正確的登錄頁(yè)地址。Filter是Servlet三大組件之一答辯被問(wèn)到的概率很高。6.2 給查詢(xún)列表加分頁(yè)避免一次查全表學(xué)生數(shù)據(jù)超過(guò)100條后頁(yè)面會(huì)卡。最樸素的分頁(yè)是SQL加LIMIT ? OFFSET ?然后前端有上一頁(yè)、下一頁(yè)按鈕。SELECT * FROM t_student ORDER BY id LIMIT 10 OFFSET 0;參數(shù)說(shuō)明LIMIT 10每頁(yè)10條OFFSET 0是跳過(guò)的記錄數(shù)第二頁(yè)就是OFFSET 10。在DAO里動(dòng)態(tài)拼接時(shí)用LIMIT ? OFFSET ?配合PreparedStatement.setInt()來(lái)傳值。同時(shí)還需要一條SELECT COUNT(*) FROM t_student計(jì)算總條數(shù)來(lái)渲染頁(yè)數(shù)。這個(gè)功能火山一樣的分頁(yè)只要你寫(xiě)了答辯老師就會(huì)覺(jué)得你不是純搬運(yùn)的。6.3 密碼加鹽哈希把明文密碼從數(shù)據(jù)庫(kù)里趕走登錄邏輯原來(lái)可能是SELECT * FROM t_user WHERE username? AND password?。建議改成先查用戶(hù)再比對(duì)密碼哈希值。String salt stu2025; // 實(shí)際應(yīng)該每個(gè)用戶(hù)隨機(jī)鹽并存入數(shù)據(jù)庫(kù) String stored MD5Util.md5(inputPassword salt); String sql SELECT password FROM t_user WHERE username ?; // 取出數(shù)據(jù)庫(kù)里的hash值與stored比較參數(shù)說(shuō)明MD5不是安全加密但比明文好而且改造成本極低。更穩(wěn)的做法是每個(gè)用戶(hù)注冊(cè)時(shí)生成隨機(jī)鹽存到單獨(dú)字段登錄時(shí)取出鹽再哈希比對(duì)。篇幅有限先把加鹽思路講清楚。第3章插入的默認(rèn)密碼記得同時(shí)改成哈希后的值否則登錄會(huì)失敗。我每次跑這種javaWeb課設(shè)zip最深的感受是下載代碼只用五分鐘配環(huán)境能折騰一下午。但正因?yàn)檎垓v過(guò)這幾輪你才真正理解了Servlet、JSP、Filter和JDBC是怎么協(xié)作的。如果你照著這篇筆記把項(xiàng)目跑起來(lái)再把分頁(yè)和登錄攔截加上這個(gè)zip的價(jià)值就遠(yuǎn)超它本身了。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取