)
簡(jiǎn)介這是一套基于 Eclipse、JDK8、JSP、MySQL 并在 Tomcat 下運(yùn)行的宿舍寢室管理系統(tǒng)完整源碼面向 Java Web 課程設(shè)計(jì)、畢業(yè)設(shè)計(jì)以及入門(mén)練手的學(xué)習(xí)者將其導(dǎo)入 IDE 后即可運(yùn)行調(diào)試。管理員端支持學(xué)生信息管理學(xué)號(hào)、姓名、性別、年齡、政治面貌、班級(jí)、登錄賬號(hào)與密碼、宿舍信息維護(hù)房間號(hào)、住宿人數(shù)、班級(jí)、樓號(hào)及公告管理可設(shè)置靜校與熄燈時(shí)間學(xué)生端提供各宿舍衛(wèi)生排名查詢(xún)。壓縮包共 248 個(gè)文件、約 6.99MB以 24 個(gè) JSP 頁(yè)面、24 個(gè) Java 源文件及編譯后的 class、79 個(gè) JS 腳本、19 個(gè) CSS 樣式和若干圖片資源為主并附 SQL 建庫(kù)腳本與 jar 依賴(lài)Servlet 與 DAO 分層清晰便于按模塊閱讀和二次開(kāi)發(fā)。已有 1341 人學(xué)習(xí)下載適合借此理清 JSP 渲染、數(shù)據(jù)庫(kù)增刪改查與分層設(shè)計(jì)的完整鏈路也可作為課設(shè)改造的基礎(chǔ)工程。1. 環(huán)境先對(duì)齊JDK8 Tomcat 8.5 MySQL 5.7這套宿舍寢室管理系統(tǒng)為什么不能隨手升版本拿到一份 JSP 寫(xiě)的宿舍寢室管理系統(tǒng)很多人的第一反應(yīng)是去官網(wǎng)拉最新版Tomcat 10、MySQL 8.4、JDK 17 一把梭。裝完啟動(dòng)控制臺(tái)先甩一堆 jakarta.servlet 找不到再甩 MySQL 認(rèn)證插件不匹配最后 JSP 頁(yè)面白屏人就開(kāi)始懷疑源碼是壞的。這套 JDK 8 Tomcat 8.5 MySQL 5.7 的組合不是保守是被 Servlet 命名空間和 JDBC 驅(qū)動(dòng)版本掐住的Tomcat 10 之后包名從 javax 換成 jakarta老 JSP 里import javax.servlet.*全部失效改回來(lái)的工作量比重新裝一遍環(huán)境還大。所以下面按「環(huán)境對(duì)齊、分件安裝、工程導(dǎo)入、建庫(kù)連庫(kù)、排錯(cuò)、驗(yàn)證」的順序走一遍適合剛拿到源碼、想在自己機(jī)器上把宿舍寢室管理系統(tǒng)完整跑起來(lái)的人。2. JDK8 與 Tomcat 8.5 的安裝從解壓到 startup 正常啟動(dòng)這一章解決兩個(gè)東西JDK 裝哪兒、Tomcat 怎么配。它們倆的關(guān)系是 Tomcat 啟動(dòng)時(shí)要去JAVA_HOME找 JVM找不到就閃退找錯(cuò)了就加載到別的版本上后面編譯 JSP 時(shí)一堆Unsupported class file major version就是這么來(lái)的。我一般把運(yùn)行環(huán)境統(tǒng)一放到一個(gè)短路徑下比如C:\env\絕不放桌面、不放「我的文檔」、不放帶中文或空格的目錄因?yàn)?Tomcat 的啟動(dòng)腳本、JSP 編譯臨時(shí)目錄對(duì)空格和中文的處理在老版本上并不友好出了問(wèn)題日志還很難看出來(lái)。2.1 JDK8 的安裝路徑與 JAVA_HOME 配置JDK8 現(xiàn)在官方主推的是 8u202 之后的更新版商用授權(quán)規(guī)則有變化本地學(xué)習(xí)跑項(xiàng)目用 8u202 或者 OpenJDK 的 8 系列都行裝完只要java -version輸出1.8.0_xxx就夠。安裝包雙擊一路下一步也行但我更推薦用解壓版好處是路徑可控、卸載干凈、多版本共存時(shí)隨時(shí)切。解壓到統(tǒng)一目錄后先配兩個(gè)環(huán)境變量。用管理員權(quán)限打開(kāi) CMD逐條執(zhí)行# 設(shè)置 JAVA_HOME注意路徑結(jié)尾不要帶反斜杠 setx JAVA_HOME C:\env\jdk1.8.0_202 /M # 把 JDK 的 bin 追加到系統(tǒng) PATH setx PATH %PATH%;%JAVA_HOME%\bin /Msetx是永久寫(xiě)環(huán)境變量的命令/M表示寫(xiě)到系統(tǒng)級(jí)而不是當(dāng)前用戶(hù)級(jí)不加的話(huà)換個(gè)終端窗口就失效。這里有個(gè)必須提醒的點(diǎn)setx對(duì) PATH 有 1024 字符截?cái)囡L(fēng)險(xiǎn)如果你的 PATH 已經(jīng)很長(zhǎng)先把原值復(fù)制到記事本備份一份再執(zhí)行不然截?cái)嘀笠欢衙钊也坏街荒苓M(jìn)注冊(cè)表救。另外%JAVA_HOME%\bin最好放在 PATH 靠前的位置因?yàn)橛行C(jī)器上裝過(guò) Oracle 客戶(hù)端會(huì)自動(dòng)塞一個(gè)C:\ProgramData\Oracle\Java\javapath進(jìn)去那個(gè)目錄優(yōu)先級(jí)更高結(jié)果你配了 JAVA_HOMEjava -version顯示的還是另一個(gè)版本這種玄學(xué)問(wèn)題排查起來(lái)特別費(fèi)時(shí)間。配完關(guān)掉所有 CMD 窗口重新開(kāi)一個(gè)驗(yàn)證java -version javac -version echo %JAVA_HOME%三條輸出里的版本號(hào)必須一致。如果java -version是 1.8 但javac -version是 17說(shuō)明 PATH 里有多個(gè) JDK 在搶回到 PATH 里把多余的刪掉。javac尤其重要Eclipse 編譯 JSP 生成 Servlet 時(shí)用的就是它只裝 JRE 不裝 JDK 會(huì)報(bào)Unable to find a javac compiler。2.2 Tomcat 8.5 解壓版部署端口、編碼、內(nèi)存三個(gè)參數(shù)Tomcat 選 8.5.x 系列任意一個(gè)小版本都行別用 9 以上的大版本去做老 JSP 項(xiàng)目雖然 9 還保留 javax 命名空間但部分老標(biāo)簽庫(kù)和web.xml的 schema 版本對(duì)不上會(huì)出現(xiàn)啟動(dòng)正常、頁(yè)面一訪(fǎng)問(wèn)就 500 的情況。解壓到C:\env\apache-tomcat-8.5.xx目錄結(jié)構(gòu)和 JDK 平級(jí)方便統(tǒng)一管理。第一個(gè)要改的是conf/server.xml里的 Connector 節(jié)點(diǎn)!-- conf/server.xml找到 8080 那個(gè) Connector 整段替換 -- Connector port8080 protocolHTTP/1.1 connectionTimeout20000 URIEncodingUTF-8 maxThreads200 redirectPort8443 /port是訪(fǎng)問(wèn)端口如果本機(jī)已經(jīng)跑著別的 Web 服務(wù)改成 8081、9090 都行改完記得同步改后面訪(fǎng)問(wèn)地址。URIEncodingUTF-8決定 GET 請(qǐng)求參數(shù)的解碼方式宿舍管理系統(tǒng)里「按樓棟名稱(chēng)查詢(xún)」這種帶中文的 GET 請(qǐng)求如果這里不是 UTF-8后端request.getParameter()拿到的就是亂碼而且 POST 請(qǐng)求不受這個(gè)參數(shù)影響很容易誤判成頁(yè)面編碼問(wèn)題。maxThreads默認(rèn) 200本地開(kāi)發(fā)不用動(dòng)寫(xiě)出來(lái)是讓你知道這個(gè)位置在哪將來(lái)并發(fā)壓測(cè)要調(diào)的時(shí)候別滿(mǎn)文件找。第二個(gè)要改的是 JVM 內(nèi)存參數(shù)正確做法是在bin目錄下新建setenv.batTomcat 啟動(dòng)時(shí)會(huì)自動(dòng)讀它# bin/setenv.batWindows 下用 set 語(yǔ)法等號(hào)兩邊不要加空格 set JAVA_OPTS-Xms256m -Xmx512m -XX:MetaspaceSize128m -XX:MaxMetaspaceSize256m -Dfile.encodingUTF-8-Xms是初始堆-Xmx是最大堆本地跑一個(gè)宿舍管理系統(tǒng)512m 完全夠。MetaspaceSize是 JDK8 才有的參數(shù)JDK8 已經(jīng)徹底移除了永久代如果你從網(wǎng)上抄來(lái)的配置里還寫(xiě)著-XX:PermSize128mTomcat 會(huì)直接啟動(dòng)失敗報(bào)Unrecognized VM option PermSize然后窗口一閃而過(guò)什么都看不到——這是 JDK7 時(shí)代的老配置流傳最廣的一個(gè)坑。-Dfile.encodingUTF-8保證日志和 JSP 編譯時(shí)的默認(rèn)編碼是 UTF-8省掉后面一半的亂碼排查。第三個(gè)是確認(rèn) Tomcat 用對(duì)了 JDK。在bin目錄下開(kāi) CMD 執(zhí)行catalina.bat version輸出里會(huì)有一行JVM Version必須是 1.8.0_xxx。如果顯示的不是你剛配的那個(gè)版本檢查是不是 Tomcat 的setclasspath.bat里硬編碼了JRE_HOME或者系統(tǒng)里殘留了JRE_HOME環(huán)境變量搶在JAVA_HOME前面生效。2.3 首次啟動(dòng)與基礎(chǔ)驗(yàn)證雙擊bin/startup.bat會(huì)彈出一個(gè)黑色窗口正常啟動(dòng)的最后幾行是Server startup in xxx ms。這個(gè)窗口不能關(guān)關(guān)了服務(wù)就停了。瀏覽器訪(fǎng)問(wèn)http://localhost:8080能看到 Tomcat 的歡迎頁(yè)說(shuō)明 JDK、端口、目錄權(quán)限這一層全通了。如果窗口一閃就沒(méi)了別急著重新雙擊用 CMD 進(jìn)到bin目錄執(zhí)行startup.bat錯(cuò)誤信息會(huì)留在當(dāng)前窗口里這是看啟動(dòng)失敗原因最直接的方式。另一種方式是看logs/catalina.YYYY-MM-DD.logTomcat 的啟動(dòng)異?;径悸湓诶锩嫦喈?dāng)于一個(gè)黑匣子閃退之后第一件事就是翻它。常見(jiàn)的是Address already in use: JVM_Bind說(shuō)明 8080 被占了用netstat -ano | findstr :8080找到 PID再taskkill /PID xxx /F干掉或者直接改端口更省事。3. Eclipse 工程導(dǎo)入讓 JSP 項(xiàng)目在 IDE 里能編譯、能部署環(huán)境裝好只是地基真正讓新手卡住的是 Eclipse 里那個(gè)紅叉——明明 Tomcat 單獨(dú)跑得好好的一導(dǎo)入工程就滿(mǎn)屏報(bào)錯(cuò)。原因是 JSP 工程依賴(lài)三樣?xùn)|西JDK、Servlet API由 Tomcat 提供、項(xiàng)目自己的 jar 包Eclipse 需要你把這三樣顯式告訴它它不會(huì)自動(dòng)猜。這一章把工程導(dǎo)入、運(yùn)行時(shí)綁定、編譯級(jí)別、編碼四件事一次配齊。3.1 Eclipse 版本選擇與 Tomcat 運(yùn)行時(shí)綁定Eclipse 版本別追新。2022-06 之后的版本要求用 JDK 11 以上啟動(dòng) IDE 本身你機(jī)器上只裝了 JDK8 的話(huà)雙擊直接報(bào)「必須使用 1.11 或更高版本」然后開(kāi)始懷疑人生。穩(wěn)妥的選擇是 Eclipse IDE for Enterprise Java Developers 2020-06 或 2021-03這兩個(gè)版本用 JDK8 就能啟動(dòng)同時(shí)內(nèi)置的 Web 工具鏈足夠完整。下載頁(yè)面上一定要選名字里帶 Enterprise 的那個(gè)包普通 Java 版沒(méi)有 Server 視圖也沒(méi)有 Dynamic Web Project。裝好之后先綁定 TomcatWindow Preferences Server Runtime Environments Add Apache Apache Tomcat v8.5 Tomcat installation directory: C:\env\apache-tomcat-8.5.xx JRE: 選擇 jdk1.8.0_202不要選 jre 目錄這里JRE那一欄默認(rèn)會(huì)讓你選 JRE一定要點(diǎn)「Installed JREs」手動(dòng)指到 JDK 根目錄。選成tomcat/jre或者系統(tǒng)里的獨(dú)立 JRE編譯 JSP 時(shí)就沒(méi)有 javac報(bào)錯(cuò)信息還挺隱蔽。綁定完成之后Servers視圖里會(huì)出現(xiàn)一個(gè) Tomcat 8.5 的服務(wù)器實(shí)例雙擊它能打開(kāi)配置頁(yè)Server Locations建議選「Use Tomcat installation」讓 Eclipse 直接往你的 Tomcat 目錄里部署這樣 IDE 里跑出來(lái)的效果和單獨(dú)啟動(dòng) Tomcat 完全一致如果選默認(rèn)的「Use workspace metadata」工程會(huì)被扔到.metadata里一個(gè)很深的臨時(shí)目錄手動(dòng)去webapps找 war 包會(huì)找不到。3.2 導(dǎo)入工程與 Project Facets 校準(zhǔn)拿到源碼先看目錄結(jié)構(gòu)。有.project和.classpath的直接File Import General Existing Projects into Workspace選根目錄導(dǎo)入沒(méi)有這兩個(gè)文件的用File New Dynamic Web Project建一個(gè)同名工程再把src、WebContent或web、WebRoot的內(nèi)容拷進(jìn)去注意別把.settings一起拷。導(dǎo)入之后第一步不是急著運(yùn)行是校準(zhǔn) Project Facets這是整個(gè) Eclipse 里最容易出錯(cuò)的地方右鍵工程 Properties Project Facets Dynamic Web Module 勾選版本 3.1 Java 勾選版本 1.8 Java Build Path Libraries 確認(rèn) JRE System Library 是 jdk1.8.0_xxx Add Library Server Runtime Apache Tomcat v8.5 Targeted Runtimes 勾選 Apache Tomcat v8.5 Java Compiler Compiler compliance level 設(shè)為 1.8Dynamic Web Module 的版本必須和 Tomcat 對(duì)上3.0 對(duì)應(yīng) Servlet 3.0Tomcat 73.1 對(duì)應(yīng) Servlet 3.1Tomcat 8/8.54.0 對(duì)應(yīng) Servlet 4.0Tomcat 9。這個(gè)版本號(hào)會(huì)直接寫(xiě)進(jìn)web.xml的根節(jié)點(diǎn)版本寫(xiě)高了 Tomcat 啟動(dòng)時(shí)報(bào)The required Server component failed to start寫(xiě)低了有些注解式 Servlet 又掃不到。Java 版本和 Compiler compliance level 兩處必須都是 1.8只改一處的話(huà)Eclipse 會(huì)用 1.8 語(yǔ)法檢查但按別的版本編譯lambda或者try-with-resources就會(huì)出現(xiàn)莫名其妙的紅波浪線(xiàn)。Targeted Runtimes這一項(xiàng)經(jīng)常被漏掉。它決定 Eclipse 部署時(shí)把哪個(gè) Tomcat 的 jar 加進(jìn) classpath不勾的話(huà)JSP 里所有javax.servlet.*下面的類(lèi)在編輯器里全是紅的但項(xiàng)目其實(shí)能跑——這種「紅著能跑」的狀態(tài)最誤導(dǎo)人會(huì)讓人誤刪代碼。3.3 JSP 編碼、編譯級(jí)別與部署目錄確認(rèn)編碼要一次配三處缺一處就會(huì)有中文亂碼Window Preferences General Workspace Text file encoding UTF-8 Window Preferences Web JSP Files Encoding ISO 10646/Unicode(UTF-8) Window Preferences General Content Types Text JSP Default encoding UTF-8第一處管 Java 源文件讀寫(xiě)第二處管 JSP 文件本身第三處管新建 JSP 時(shí)的默認(rèn)編碼。三處統(tǒng)一之后工程里每個(gè) JSP 文件頭部的% page contentTypetext/html;charsetUTF-8 pageEncodingUTF-8 %才有意義。很多老項(xiàng)目里pageEncoding寫(xiě)的是GBK文件本身是 GBK 存的你在 Eclipse 里改成 UTF-8 之后原有中文注釋全變問(wèn)號(hào)頁(yè)面輸出也跟著亂——這種情況不要全局改先把文件用文本編輯器轉(zhuǎn)碼保存成 UTF-8再統(tǒng)一聲明順序反了就是白干。部署驗(yàn)證走一遍Servers視圖右鍵 Tomcat 實(shí)例 Add and Remove把工程加進(jìn)去啟動(dòng)服務(wù)器。啟動(dòng)日志里會(huì)打出工程的 Context Path通常是工程名。瀏覽器訪(fǎng)問(wèn)http://localhost:8080/工程名/首頁(yè).jsp。如果訪(fǎng)問(wèn)根路徑http://localhost:8080/工程名/報(bào) 404但帶文件名能打開(kāi)說(shuō)明web.xml里沒(méi)配welcome-file-list老項(xiàng)目常見(jiàn)補(bǔ)上index.jsp就行!-- WebContent/WEB-INF/web.xml -- welcome-file-list welcome-fileindex.jsp/welcome-file welcome-filelogin.jsp/welcome-file /welcome-file-listwelcome-file是按順序找的第一個(gè)不存在才找第二個(gè)所以把登錄頁(yè)放前面更符合這個(gè)系統(tǒng)的實(shí)際入口。補(bǔ)完記得在Servers視圖里右鍵 Tomcat Clean讓 Eclipse 重新發(fā)布不然改的web.xml還在舊副本里。4. MySQL 5.7 建庫(kù)與 JDBC 連接字符集、認(rèn)證插件、驅(qū)動(dòng)三件事宿舍寢室管理系統(tǒng)的數(shù)據(jù)模型通常不復(fù)雜無(wú)非是樓棟、寢室、床位、學(xué)生、入住記錄這幾張表真正費(fèi)時(shí)間的是連不上、亂碼、字段超長(zhǎng)這三類(lèi)問(wèn)題。它們?nèi)紒?lái)自三個(gè)地方數(shù)據(jù)庫(kù)的字符集、root 的認(rèn)證插件、JDBC 驅(qū)動(dòng) jar 的位置。逐個(gè)說(shuō)。4.1 MySQL 5.7 安裝與 root 認(rèn)證方式調(diào)整裝 MySQL 5.7 的時(shí)候安裝器會(huì)問(wèn)端口、root 密碼、服務(wù)名端口保持 3306密碼記牢服務(wù)名默認(rèn)MySQL57就行裝完在服務(wù)列表里能看到自動(dòng)啟動(dòng)。這一步?jīng)]什么坑坑在裝完之后MySQL 8.0 開(kāi)始默認(rèn)認(rèn)證插件是caching_sha2_password而大量 JSP 老工程配的是mysql-connector-java-5.1.4x驅(qū)動(dòng)這個(gè)驅(qū)動(dòng)根本不認(rèn)識(shí)新插件連上去會(huì)直接拋Unable to load authentication plugin caching_sha2_password。反過(guò)來(lái)你在 5.7 上跑認(rèn)證插件是mysql_native_password但如果驅(qū)動(dòng) jar 用的是 8.0 版本類(lèi)名從com.mysql.jdbc.Driver變成了com.mysql.cj.jdbc.DriverClass.forName就會(huì)找不到類(lèi)。版本對(duì)齊比什么都重要。確認(rèn)并統(tǒng)一認(rèn)證插件用 root 登錄 MySQL 命令行執(zhí)行-- 查看當(dāng)前 root 的認(rèn)證插件 SELECT user, host, plugin FROM mysql.user WHERE user root; -- 如果是 caching_sha2_password改成 native 方式 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密碼; FLUSH PRIVILEGES;mysql_native_password是 5.7 時(shí)代的默認(rèn)值5.1.x 驅(qū)動(dòng)只認(rèn)它。FLUSH PRIVILEGES刷新權(quán)限表讓改動(dòng)立刻生效不加的話(huà)有時(shí)候要重啟服務(wù)才認(rèn)。如果你不想動(dòng) root也可以給項(xiàng)目單獨(dú)建個(gè)賬號(hào)權(quán)限只給到dorm這一個(gè)庫(kù)這在實(shí)際部署里是更規(guī)范的做法CREATE USER dorm_applocalhost IDENTIFIED WITH mysql_native_password BY App123456; GRANT SELECT, INSERT, UPDATE, DELETE ON dorm_db.* TO dorm_applocalhost; FLUSH PRIVILEGES;只給增刪改查不給 DDL 權(quán)限防止程序里某段建表語(yǔ)句把線(xiàn)上表結(jié)構(gòu)改壞。4.2 建庫(kù)、導(dǎo)入 SQL 腳本與字符集選擇建庫(kù)這一步的字符集必須一次定死中途改代價(jià)很大CREATE DATABASE dorm_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE dorm_db;utf8mb4而不是utf8因?yàn)?MySQL 里的utf8其實(shí)是utf8mb3最多 3 字節(jié)存不下 emoji 和部分生僻字。宿舍管理系統(tǒng)里學(xué)生姓名如果出現(xiàn)生僻字用utf8會(huì)插入失敗或者變成問(wèn)號(hào)。utf8mb4_general_ci里的ci是不區(qū)分大小寫(xiě)登錄賬號(hào)查詢(xún)、樓棟名匹配都用得上除非你的業(yè)務(wù)明確要求區(qū)分大小寫(xiě)否則別選_bin。導(dǎo)入工程自帶的.sql腳本用命令行而不是圖形工具方便看報(bào)錯(cuò)# 先建空庫(kù)再導(dǎo)入導(dǎo)入時(shí)顯式指定字符集 mysql -uroot -p --default-character-setutf8mb4 dorm_db C:\env\sql\dorm.sql--default-character-setutf8mb4是關(guān)鍵。如果你的 sql 腳本是 UTF-8 編碼但客戶(hù)端連接默認(rèn)字符集是 GBK導(dǎo)進(jìn)去的中文會(huì)全部變成亂碼而且導(dǎo)完不報(bào)錯(cuò)等到頁(yè)面上顯示出來(lái)才發(fā)現(xiàn)那時(shí)候數(shù)據(jù)已經(jīng)臟了只能刪庫(kù)重導(dǎo)。導(dǎo)入完成后一定抽查一張表SELECT table_name, table_collation FROM information_schema.tables WHERE table_schema dorm_db;所有表的 collation 都應(yīng)該是utf8mb4_general_ci。如果腳本里寫(xiě)了ENGINEInnoDB DEFAULT CHARSETutf8表會(huì)被建成 utf8mb3和庫(kù)級(jí)字符集不一致后面 join 或者存生僻字都會(huì)出問(wèn)題穩(wěn)妥的做法是把腳本里的CHARSETutf8批量替換成CHARSETutf8mb4再導(dǎo)。4.3 JDBC 驅(qū)動(dòng)放置與連接串參數(shù)驅(qū)動(dòng) jar 放哪兒是 JSP 項(xiàng)目翻車(chē)率最高的一步。放的位置有兩個(gè)選擇工程的WebContent/WEB-INF/lib目錄或者 Eclipse 的Java Build Path。正確答案是必須放WEB-INF/libBuild Path只是讓編譯器不報(bào)錯(cuò)部署的時(shí)候 Eclipse 不會(huì)把 Build Path 里的第三方 jar 復(fù)制到 Tomcat 的WEB-INF/lib下運(yùn)行期自然找不到類(lèi)報(bào)java.lang.ClassNotFoundException: com.mysql.jdbc.Driver。我踩過(guò)這個(gè)坑不止一次編輯器里一路綠燈一訪(fǎng)問(wèn)頁(yè)面就 500。操作上把mysql-connector-java-5.1.4x.jar直接復(fù)制到WebContent/WEB-INF/lib然后右鍵工程 RefreshEclipse 會(huì)自動(dòng)把它加到 Web App Libraries 里不需要手動(dòng) Add to Build Path。接著寫(xiě)連接工具類(lèi)// src/com/dorm/util/DBUtil.java public class DBUtil { // 5.1.x 驅(qū)動(dòng)的類(lèi)名8.0 驅(qū)動(dòng)是 com.mysql.cj.jdbc.Driver private static final String DRIVER com.mysql.jdbc.Driver; // useUnicode characterEncoding 管中文useSSL 關(guān)掉省掉證書(shū)警告 private static final String URL jdbc:mysql://127.0.0.1:3306/dorm_db ?useUnicodetruecharacterEncodingutf8useSSLfalse allowPublicKeyRetrievaltrue; private static final String USER dorm_app; private static final String PWD App123456; public static Connection getConn() throws Exception { Class.forName(DRIVER); // 加載驅(qū)動(dòng)只需一次放在這里夠用 return DriverManager.getConnection(URL, USER, PWD); } }useUnicodetruecharacterEncodingutf8告訴驅(qū)動(dòng)用 UTF-8 和數(shù)據(jù)庫(kù)通信和庫(kù)的utf8mb4是兼容的不用改成utf8mb4因?yàn)?5.1 驅(qū)動(dòng)不認(rèn)這個(gè)值。useSSLfalse關(guān)掉 SSL 握手本地開(kāi)發(fā)沒(méi)證書(shū)不關(guān)會(huì)打一堆警告日志。allowPublicKeyRetrievaltrue是給 8.0 驅(qū)動(dòng)準(zhǔn)備的5.1 驅(qū)動(dòng)會(huì)忽略它留著不礙事將來(lái)?yè)Q驅(qū)動(dòng)不用再改連接串。如果你非要用 8.0 驅(qū)動(dòng)類(lèi)名和連接串都要換com.mysql.cj.jdbc.Driver再加上serverTimezoneAsia/Shanghai否則時(shí)間字段取出來(lái)會(huì)差 8 小時(shí)入住登記時(shí)間全部對(duì)不上。5. 常見(jiàn)問(wèn)題排查JSP 能啟動(dòng)但跑不通的幾類(lèi)坑這一章記的是實(shí)際裝這套東西時(shí)反復(fù)出現(xiàn)的故障每一條都按「現(xiàn)象、原因、解決」寫(xiě)清楚遇到時(shí)對(duì)號(hào)入座就行。5.1 啟動(dòng)與頁(yè)面訪(fǎng)問(wèn)類(lèi)故障現(xiàn)象一Tomcat 窗口一閃而過(guò)手工執(zhí)行 startup.bat 報(bào)Unrecognized VM option PermSize。原因setenv.bat或者catalina.bat里殘留了 JDK7 時(shí)代的內(nèi)存參數(shù)。JDK8 移除了永久代PermSize、MaxPermSize全部作廢JVM 啟動(dòng)時(shí)直接拒絕。解決把-XX:PermSize和-XX:MaxPermSize刪掉換成-XX:MetaspaceSize128m -XX:MaxMetaspaceSize256m。改完先用catalina.bat version驗(yàn)證 JVM 能起來(lái)再startup.bat?,F(xiàn)象二訪(fǎng)問(wèn)項(xiàng)目路徑報(bào) 404但http://localhost:8080的 Tomcat 歡迎頁(yè)正常。原因工程沒(méi)有真正部署到 Tomcat或者 Context Path 和你以為的不一樣。Eclipse 默認(rèn)用工程名作為上下文路徑如果Servers視圖里沒(méi)執(zhí)行Add and Remove工程根本沒(méi)發(fā)布。解決打開(kāi)Servers視圖雙擊 Tomcat看Modules標(biāo)簽頁(yè)里有沒(méi)有你的工程、Path 是不是/工程名。沒(méi)有就Add and Remove加進(jìn)去。也可以反過(guò)來(lái)在工程上右鍵Run As Run on ServerEclipse 會(huì)自動(dòng)完成注冊(cè)。現(xiàn)象三JSP 頁(yè)面里javax.servlet.http.HttpServletRequest報(bào)紅或者運(yùn)行時(shí)報(bào)NoClassDefFoundError: javax/servlet/http/HttpServlet。原因兩種情況。一是Targeted Runtimes沒(méi)勾Eclipse 沒(méi)把 Tomcat 的 jar 加進(jìn)編輯期 classpath二是你誤用了 Tomcat 10它的包名是jakarta.servlet.*javax下的類(lèi)一個(gè)都沒(méi)有。解決前者進(jìn)Properties Targeted Runtimes勾上 Tomcat 8.5后者最省事的就是把 Tomcat 換成 8.5 或 9別在老 JSP 工程上折騰 jakarta 遷移改一遍 import 還要重配web.xml的 schema性?xún)r(jià)比極低。5.2 數(shù)據(jù)庫(kù)與中文編碼類(lèi)故障現(xiàn)象四訪(fǎng)問(wèn)登錄頁(yè)直接 500堆棧里是java.lang.ClassNotFoundException: com.mysql.jdbc.Driver。原因驅(qū)動(dòng) jar 只加到了Java Build Path沒(méi)放WEB-INF/lib編譯期能找到、運(yùn)行期找不到。解決把 jar 復(fù)制進(jìn)WebContent/WEB-INF/libRefresh工程Servers視圖里Clean一次重新發(fā)布。判斷標(biāo)準(zhǔn)很簡(jiǎn)單去 Tomcat 的webapps/工程名/WEB-INF/lib目錄下看一眼jar 在不在不在就是沒(méi)配對(duì)?,F(xiàn)象五登錄不進(jìn)去日志里Access denied for user dorm_applocalhost但密碼明明是對(duì)的。原因賬號(hào)的 host 不匹配或者認(rèn)證插件不對(duì)。dorm_applocalhost和dorm_app%是兩個(gè)不同賬號(hào)從 127.0.0.1 連過(guò)來(lái)時(shí) MySQL 的匹配規(guī)則有時(shí)候會(huì)讓你以為用的是同一個(gè)。認(rèn)證插件不對(duì)的話(huà)報(bào)錯(cuò)信息會(huì)是Unable to load authentication plugin不是 access denied注意區(qū)分。解決先SELECT user, host, plugin FROM mysql.user;把賬號(hào)全列出來(lái)確認(rèn) host 和 plugin。缺dorm_app127.0.0.1就補(bǔ)一個(gè)插件是caching_sha2_password就ALTER USER ... IDENTIFIED WITH mysql_native_password BY ...。現(xiàn)象六頁(yè)面能打開(kāi)但插入的寢室名、學(xué)生姓名在數(shù)據(jù)庫(kù)里全是問(wèn)號(hào)。原因鏈路上有任意一環(huán)不是 UTF-8??赡艿狞c(diǎn)包括 JSP 的pageEncoding、request.setCharacterEncoding(UTF-8)沒(méi)調(diào)、連接串缺characterEncoding、庫(kù)表是 utf8mb3、MySQL 服務(wù)端character_set_server是 latin1。五處任何一處不一致都會(huì)亂而且表現(xiàn)為「有的頁(yè)面亂有的不亂」特別迷惑。解決別一處一處猜直接查服務(wù)端變量定位SHOW VARIABLES LIKE character_set%;character_set_server、character_set_database、character_set_connection三個(gè)都應(yīng)該是utf8mb4。不是的話(huà)在my.ini的[mysqld]段加上character-set-serverutf8mb4和collation-serverutf8mb4_general_ci重啟服務(wù)。程序側(cè)再補(bǔ)一個(gè)過(guò)濾器統(tǒng)一設(shè)編碼比在每個(gè) Servlet 里寫(xiě)一行setCharacterEncoding靠譜// src/com/dorm/filter/EncodingFilter.java public class EncodingFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding(UTF-8); // 只管 POST 體GET 靠 Tomcat 的 URIEncoding resp.setCharacterEncoding(UTF-8); chain.doFilter(req, resp); } }過(guò)濾器要在web.xml里注冊(cè)并且filter-mapping放最前面保證它在所有 Servlet 之前執(zhí)行。GET 請(qǐng)求的中文在 Tomcat 8 之后默認(rèn)就是 UTF-8但如果server.xml里顯式寫(xiě)了別的URIEncoding會(huì)被覆蓋回頭查一遍第 2 章那段配置。6. 裝完怎么驗(yàn)證從登錄到宿舍分配走一遍完整鏈路環(huán)境裝完、工程跑起來(lái)不代表這套宿舍寢室管理系統(tǒng)就通了。我習(xí)慣做一次端到端驗(yàn)證把「讀」和「寫(xiě)」都覆蓋到因?yàn)橹淮蜷_(kāi)登錄頁(yè)看不出連接池、事務(wù)、字符集這些問(wèn)題。驗(yàn)證按下面這張表逐項(xiàng)過(guò)每項(xiàng)都有明確的通過(guò)標(biāo)準(zhǔn)驗(yàn)證項(xiàng)操作路徑通過(guò)標(biāo)準(zhǔn)JSP 編譯訪(fǎng)問(wèn)登錄頁(yè)頁(yè)面正常渲染Tomcat 日志無(wú) JasperException數(shù)據(jù)庫(kù)連接輸入正確賬號(hào)密碼登錄跳轉(zhuǎn)首頁(yè)不出現(xiàn) 500查詢(xún)功能寢室列表按樓棟篩選列表有數(shù)據(jù)中文樓棟名不亂碼寫(xiě)入功能新增一條寢室記錄數(shù)據(jù)庫(kù)里能查到字段值完整中文往返新增帶中文的寢室名再查出來(lái)頁(yè)面顯示與輸入一致時(shí)間字段查看入住登記時(shí)間與系統(tǒng)時(shí)間一致不差 8 小時(shí)第六項(xiàng)最容易被忽略。如果用的是 8.0 驅(qū)動(dòng)又沒(méi)配serverTimezone時(shí)間會(huì)整體偏 8 小時(shí)本地測(cè)試看不太出來(lái)一上線(xiàn)就出問(wèn)題。驗(yàn)證時(shí)直接往數(shù)據(jù)庫(kù)插一條記錄對(duì)比SELECT NOW()和頁(yè)面顯示的時(shí)間差 8 小時(shí)就回去補(bǔ)連接串參數(shù)。寫(xiě)入驗(yàn)證之后一定要回?cái)?shù)據(jù)庫(kù)確認(rèn)別只看頁(yè)面提示「保存成功」-- 驗(yàn)證寫(xiě)入同時(shí)確認(rèn)中文沒(méi)有變成問(wèn)號(hào) SELECT id, room_no, building, capacity, create_time FROM dorm_room ORDER BY id DESC LIMIT 5;room_no和building如果是???或者空串說(shuō)明寫(xiě)入鏈路上還有編碼問(wèn)題回第 5 章第 6 條排查。如果create_time是0000-00-00檢查表字段有沒(méi)有設(shè)默認(rèn)值以及 Java 側(cè)傳的是java.util.Date還是LocalDateTime——5.1 驅(qū)動(dòng)對(duì)LocalDateTime支持不好會(huì)靜默失敗這種不報(bào)錯(cuò)的問(wèn)題最難查。最后一步是把工程打成 war 包脫離 Eclipse 單獨(dú)部署一次# 在工程根目錄執(zhí)行產(chǎn)物丟到 Tomcat 的 webapps 下 jar -cvf dorm.war -C WebContent .然后用startup.bat啟動(dòng) Tomcat訪(fǎng)問(wèn)http://localhost:8080/dorm/能正常登錄就說(shuō)明這個(gè)工程不依賴(lài) Eclipse 的元數(shù)據(jù)可以交付了。這一步是很多人的盲區(qū)IDE 里跑得好好的war 包一部署就 500八成是WEB-INF/lib漏了 jar或者classes目錄沒(méi)打進(jìn)去。有一條血淚經(jīng)驗(yàn)——從那以后我每次拿到一份 JSP 源碼都先把 JDK 小版本、Tomcat 大版本、驅(qū)動(dòng)版本這三行寫(xiě)在便簽上貼屏幕邊上裝一步核一步再也不敢「先跑起來(lái)再說(shuō)」。版本這種看起來(lái)最枯燥的東西往往就是那個(gè)讓你折騰一整晚的坑。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取