計(jì)全套導(dǎo)入與改造指南:從跑通到答辯無憂)
簡(jiǎn)介這是一套面向JavaEE課程設(shè)計(jì)的高校宿舍管理系統(tǒng)完整項(xiàng)目包采用經(jīng)典SSH框架Struts2、Spring、Hibernate搭建。適合正在完成企業(yè)級(jí)Web開發(fā)實(shí)訓(xùn)的學(xué)生也適合希望復(fù)習(xí)框架整合流程的開發(fā)者。項(xiàng)目包含完整源碼、數(shù)據(jù)庫(kù)腳本與課程設(shè)計(jì)報(bào)告覆蓋用戶管理、宿舍分配、宿舍信息維護(hù)、維修申請(qǐng)和數(shù)據(jù)統(tǒng)計(jì)等核心模塊能夠幫助讀者理解MVC分層、依賴注入、面向切面編程以及對(duì)象關(guān)系映射等SSH技術(shù)在真實(shí)項(xiàng)目中的協(xié)作方式。壓縮包共284個(gè)文件以Java源碼、JSP頁(yè)面、Class文件為主體另含Spring與Struts的XML配置、35個(gè)Jar依賴、SQL初始化腳本、DOCX設(shè)計(jì)報(bào)告及部分靜態(tài)資源整體約32.7MB目錄結(jié)構(gòu)便于按功能模塊檢索。已有3643人參與學(xué)習(xí)適合需要快速搭建宿舍管理類課設(shè)或深入研讀SSH框架集成細(xì)節(jié)的Java學(xué)習(xí)者獲得后可直接導(dǎo)入數(shù)據(jù)庫(kù)腳本并運(yùn)行體驗(yàn)完整流程。1. 拆開「JavaEE課程設(shè)計(jì)全套.zip」之前先想清楚你要交什么同樣是下載了「JavaEE課程設(shè)計(jì)全套.zip」有人順利跑通界面、按時(shí)交上報(bào)告、答辯時(shí)被老師追問也能接住有人卻在導(dǎo)入項(xiàng)目的第一步就卡住最后換了好幾個(gè)壓縮包才勉強(qiáng)交差。差別不在運(yùn)氣而在拿到壓縮包之后有沒有先做「識(shí)別」再做「動(dòng)手」。這套壓縮包在高校場(chǎng)景里對(duì)應(yīng)的是JavaEE課程的期末項(xiàng)目?jī)?nèi)容普遍是完整源碼、數(shù)據(jù)庫(kù)腳本和說明文檔技術(shù)棧通常是 Servlet JSP JDBC MySQL Tomcat 這一套經(jīng)典組合。它解決的核心問題是「課程設(shè)計(jì)不知道做什么、做出來太簡(jiǎn)單不敢交」——你缺的不是代碼而是「能跑起來、能講清楚、敢讓老師深挖」的完整鏈路。適合正在做JavaEE課程設(shè)計(jì)的學(xué)生也適合想把老式 Web 項(xiàng)目改造成 Spring Boot 的入門開發(fā)者。2. 先識(shí)別技術(shù)棧與目錄結(jié)構(gòu)這決定你導(dǎo)入項(xiàng)目的方式很多人翻車在一個(gè)隱藏前提上以為「JavaEE課程設(shè)計(jì)全套.zip」只有一個(gè)版本解壓后雙擊就萬事大吉。實(shí)際上這類壓縮包至少有 Maven 工程和傳統(tǒng) Web 工程兩種組織方式導(dǎo)入 IDE 的路徑完全不一樣。在做任何一個(gè)操作之前先花兩分鐘把目錄結(jié)構(gòu)看清楚。2.1 解壓后先看的關(guān)鍵文件我拿到這類壓縮包的第一步永遠(yuǎn)是解壓后查目錄而不是直接扔進(jìn) IDE。Linux 或 macOS 下用一條命令就能定位關(guān)鍵標(biāo)記Windows 下用資源管理器看同名文件即可。unzip JavaEE課程設(shè)計(jì)全套.zip -d ./javaee-project cd javaee-project find . -maxdepth 3 -type f | head -50find輸出的前幾個(gè)文件就能暴露項(xiàng)目類型。優(yōu)先級(jí)最高的是pom.xml存在它說明這是一個(gè) Maven 工程導(dǎo)入 IDE 時(shí)選 Maven 模型即可如果沒有pom.xml而是看到WebContent或src/main/webapp下掛著WEB-INF/web.xml外加一個(gè)lib目錄塞滿 jar 包那這就是傳統(tǒng)的非 Maven Web 工程導(dǎo)入方式完全不同。另外注意找.sql結(jié)尾的數(shù)據(jù)庫(kù)腳本以及README或需求文檔.docx之類的說明文件——很多資源包里附帶文檔里面寫的部署步驟比任何教程都準(zhǔn)。2.2 提前摸清數(shù)據(jù)庫(kù)配置避免第一次啟動(dòng)就翻車識(shí)別完工程類型后再做一次集中檢查。這一步的成本非常低卻能避免最常見的一類錯(cuò)誤——數(shù)據(jù)庫(kù)配置與本地環(huán)境不一致。grep -n jdbc:mysql\|root\|password src -r --include*.java --include*.properties --include*.xml 2/dev/null | head -20這條命令把源碼和配置文件里所有與數(shù)據(jù)庫(kù)連接相關(guān)的行找出來重點(diǎn)看三部分?jǐn)?shù)據(jù)庫(kù)地址jdbc:mysql://…、用戶名、密碼。常見做法是這些配置集中在db.properties、jdbc.properties或一個(gè)叫DBUtil.java的工具類里也有直接散落在 DAO 類中的所以用-r遞歸搜索最穩(wěn)妥。看清了庫(kù)名和賬號(hào)密碼后面初始化數(shù)據(jù)庫(kù)時(shí)才能一次性通過否則等界面出來了才發(fā)現(xiàn)登錄報(bào) SQLException排查鏈路會(huì)拉得很長(zhǎng)。2.3 做一份完整性檢查清單再動(dòng)手檢查項(xiàng)用表格列出來比腦內(nèi)估摸靠譜得多。我在導(dǎo)入前會(huì)對(duì)著這個(gè)清單過一遍避免「代碼導(dǎo)入成功才發(fā)現(xiàn)缺了數(shù)據(jù)庫(kù)腳本」這種返工。檢查項(xiàng)期望看到的內(nèi)容缺失時(shí)的后果構(gòu)建文件pom.xml 或 WEB-INF/web.xml 存在IDE 無法正確識(shí)別工程類型數(shù)據(jù)庫(kù)腳本至少一個(gè) .sql 文件含建庫(kù)建表語句項(xiàng)目啟動(dòng)成功但功能全部報(bào)錯(cuò)配置文件db.properties / jdbc.properties / web.xml數(shù)據(jù)庫(kù)無法連接Filter 可能失效依賴包lib 目錄有 jar 包或 Maven 依賴完整編譯報(bào) ClassNotFoundException說明文檔部署步驟、賬號(hào)密碼、項(xiàng)目介紹無法確認(rèn)默認(rèn)登錄賬號(hào)隱患很大說明文檔這一項(xiàng)最容易被人忽略但它的價(jià)值有時(shí)比源碼還高。很多資源包會(huì)在文檔里寫明默認(rèn)管理員賬號(hào)和初始數(shù)據(jù)比如「admin / 123456」。沒有這份信息你可能得一遍遍翻代碼才能找到登錄入口答辯前非常被動(dòng)。整個(gè)識(shí)別過程控制在十分鐘內(nèi)別在這一步上拖延真正的重頭戲是后面的導(dǎo)入和啟動(dòng)。3. 把整套 JavaEE 課程設(shè)計(jì)在本地跑起來從導(dǎo)入到出界面識(shí)別完類型后啟動(dòng)路徑就清晰了。這一章按兩種工程類型分別給出導(dǎo)入步驟再講數(shù)據(jù)庫(kù)初始化和啟動(dòng)驗(yàn)證。這里踩的每一個(gè)坑都是當(dāng)年我?guī)屯瑢W(xué)調(diào)環(huán)境時(shí)反復(fù)見過的。3.1 IDEA 導(dǎo)入 Maven 版一條命令驗(yàn)證依賴Maven 工程我用 IntelliJ IDEA 導(dǎo)入。選擇File - Open直接選中解壓后的根目錄包含pom.xml的那一層IDEA 會(huì)自動(dòng)識(shí)別為 Maven 項(xiàng)目并開始下載依賴。這階段最容易出現(xiàn)的問題是 Maven 倉(cāng)庫(kù)地址或 JDK 版本不匹配導(dǎo)致依賴下載失敗或編譯目標(biāo)版本報(bào)錯(cuò)。導(dǎo)入完成后先跑一條命令驗(yàn)證依賴是否完整。mvn clean package -DskipTestsclean清掉舊的編譯產(chǎn)物package打包成 war-DskipTests跳過單元測(cè)試。這一步的重點(diǎn)不是拿到 war 包而是確認(rèn)項(xiàng)目在脫離 IDE 的情況下也能編譯通過。如果你看到 BUILD SUCCESS說明代碼層面沒有大問題后續(xù)的報(bào)錯(cuò)集中在運(yùn)行環(huán)境和數(shù)據(jù)庫(kù)上。如果 BUILD FAILURE優(yōu)先看第一行[ERROR]絕大多數(shù)情況是某依賴下載不下來——換 Maven 鏡像源或者檢查本機(jī) JDK 版本是否高于 pom 里maven.compiler.source設(shè)置的版本然后跑mvn clean package重新試一次。3.2 導(dǎo)入傳統(tǒng) Web 工程手動(dòng)配置一個(gè)關(guān)鍵步驟非 Maven 工程的處理方式完全不同。用 IDEA 的File - New - Project from Existing Sources選中解壓目錄在導(dǎo)入向?qū)Ю镞xWeb類型。導(dǎo)入成功后還有一個(gè)必須手動(dòng)做的操作把lib目錄添加到項(xiàng)目依賴?yán)锓駝t IDE 編譯會(huì)報(bào)一堆「找不到包」。# 啟動(dòng) Tomcat 的兩種方式注意 run 與 start 的區(qū)別 catalina.sh run # 前臺(tái)運(yùn)行控制臺(tái)直接輸出實(shí)時(shí)日志 catalina.sh start # 后臺(tái)運(yùn)行日志寫入 logs 目錄調(diào)試階段我?guī)缀踔挥胏atalina.sh run。原因很直白前臺(tái)運(yùn)行時(shí)控制臺(tái)打印的每一行日志都會(huì)實(shí)時(shí)出現(xiàn)像SEVERE: Exception starting filter這類錯(cuò)誤一眼就能看到而不必去logs/catalina.out里翻找start 更適合確認(rèn)無錯(cuò)后的正式啟動(dòng)。Windows 下對(duì)應(yīng)命令是catalina.bat run效果一樣。如果你看到配置 Tomcat 時(shí)找不到 Artifact那是 Deployment 選項(xiàng)卡里沒有把 war 包或 exploded war 添加進(jìn)去IDEA 的菜單路徑是Run - Edit Configurations - Tomcat Server - Deployment - Add。3.3 初始化數(shù)據(jù)庫(kù)連接串的三個(gè)必設(shè)參數(shù)數(shù)據(jù)庫(kù)初始化是整個(gè)流程里最需要細(xì)心的一步。找到.sql文件在 MySQL 的bin目錄下執(zhí)行導(dǎo)入。mysql -u root -p db/init.sql回車后輸入密碼看到導(dǎo)入過程沒有任何 ERROR 輸出即為成功。接著打開項(xiàng)目的數(shù)據(jù)庫(kù)配置文件把連接串改成兼容當(dāng)前環(huán)境的格式常見做法是把連接串統(tǒng)一為下面這套。jdbc:mysql://localhost:3306/course_design?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8三個(gè)參數(shù)各有一個(gè)實(shí)際作用。useSSLfalse避免本地環(huán)境 SSL 握手導(dǎo)致的警告甚至連接異常serverTimezoneAsia/Shanghai處理 MySQL 8.x 對(duì)時(shí)區(qū)校驗(yàn)嚴(yán)格的問題——不加時(shí)報(bào)錯(cuò)The server time zone value ?D1ú±ê×?ê±?? is unrecognizedcharacterEncodingutf8保證中文數(shù)據(jù)在數(shù)據(jù)庫(kù)和 Web 應(yīng)用之間傳輸不亂碼。如果你的 MySQL 是 5.x 版本時(shí)區(qū)參數(shù)可以保留useSSL即使刪掉也能跑但保留無妨。3.4 啟動(dòng)后的三層驗(yàn)證Tomcat 起來、首頁(yè)能打開不代表項(xiàng)目真的沒問題。我一般按三層順序檢查每層出問題都能定位到具體位置。第一層檢查頁(yè)面資源能否正常加載。打開瀏覽器開發(fā)者工具F12的 Console 和 Network看有沒有 404 或 JS 報(bào)錯(cuò)。第二層走通一個(gè)核心業(yè)務(wù)流程通常是注冊(cè)或登錄。注冊(cè)一個(gè)賬號(hào)登錄后進(jìn)入列表頁(yè)再做一個(gè)新增和刪除操作任何一步報(bào) 500 都順著服務(wù)端控制臺(tái)日志找異常棧的Caused by。第三層進(jìn)后臺(tái)管理頁(yè)面看列表數(shù)據(jù)是否從數(shù)據(jù)庫(kù)真實(shí)讀取——如果頁(yè)面上有寫死的演示數(shù)據(jù)那說明 DAO 層可能沒生效后續(xù)改造時(shí)必須重點(diǎn)關(guān)注。4. 把這套 JavaEE 課程設(shè)計(jì)改成你自己的四個(gè)必改點(diǎn)下載的資源包跑通了只是第一步。答辯時(shí)的核心風(fēng)險(xiǎn)在于「老師一眼看出這不是你寫的」。與其賭老師不深究不如主動(dòng)做四個(gè)改造點(diǎn)既降低風(fēng)險(xiǎn)又能把項(xiàng)目難度往上提一檔。4.1 重構(gòu)包名與類名最基礎(chǔ)的身份標(biāo)識(shí)資源包里的包名幾乎都是com.example.xxx或某個(gè)固定簽名風(fēng)格這是查重的第一觀察點(diǎn)。理想的做法是在 IDEA 里右鍵com.example包 -Refactor - Rename把整個(gè)根包名改成你的學(xué)號(hào)拼音縮寫或姓名縮寫組合IDEA 會(huì)同步更新所有 Java 文件里的 import 聲明和 XML 配置文件里的引用。如果 IDE 重構(gòu)失敗也可以退而求其次用命令行批量替換后再手動(dòng)移動(dòng)目錄。# 注意目錄結(jié)構(gòu)不會(huì)跟隨替換自動(dòng)調(diào)整務(wù)必先用 IDE 處理 grep -rl com.example src --include*.java | xargs sed -i s/com\.example/com\.myname/g替換后還需要把src/main/java/com/example目錄改名為src/main/java/com/myname并且檢查web.xml、spring-mvc.xml里的包掃描路徑是否同步更新。改包名只是消除表面嫌疑真正的難點(diǎn)在于下面三個(gè)功能層面的改造。4.2 把 Statement 換成 PreparedStatement答辯必問點(diǎn)課程設(shè)計(jì)答辯時(shí)老師基本必問一句「你的登錄查詢?cè)趺捶乐?SQL 注入」。資源包里的老代碼很多是直接拼接 SQL 的這是最明顯的技術(shù)債也是最容易改出價(jià)值的點(diǎn)。拿登錄驗(yàn)證舉例改造前后對(duì)比非常直觀。// 改之前字符串拼接存在 SQL 注入風(fēng)險(xiǎn) Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery( SELECT * FROM user WHERE username username AND password password ); // 改之后參數(shù)化查詢SQL 結(jié)構(gòu)與數(shù)據(jù)分離 String sql SELECT * FROM user WHERE username? AND password?; PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, username); ps.setString(2, password); ResultSet rs ps.executeQuery();這塊代碼的邏輯值得展開講。PreparedStatement會(huì)先把帶問號(hào)的 SQL 語句發(fā)送給數(shù)據(jù)庫(kù)完成編譯之后再傳入?yún)?shù)值參數(shù)只被當(dāng)作數(shù)據(jù)處理不會(huì)改變 SQL 語義。所以即使用戶輸入 or 11數(shù)據(jù)庫(kù)也會(huì)把它當(dāng)成一串普通字符而不是拼進(jìn) WHERE 條件。動(dòng)手時(shí)把資源包里的Statement全部替換為PreparedStatement同時(shí)注意原有的連接關(guān)閉順序先關(guān)ResultSet再關(guān)PreparedStatement最后關(guān)Connection。這一項(xiàng)改動(dòng)讓項(xiàng)目至少在數(shù)據(jù)安全層面有了一個(gè)實(shí)打?qū)嵉牧咙c(diǎn)。4.3 加一個(gè)登錄過濾器Filter讓項(xiàng)目具備統(tǒng)一攔截能力資源包里的老項(xiàng)目通常在每個(gè) Servlet 里判斷 Session 是否為空重復(fù)代碼多且容易漏。加一個(gè)登錄過濾器是一本萬利的改造代碼量不大但講述時(shí)能體現(xiàn)「應(yīng)用層統(tǒng)一處理」的設(shè)計(jì)意識(shí)。WebFilter(/*) public class LoginFilter implements Filter { Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) resp; String uri request.getRequestURI(); // 放行登錄頁(yè)面、登錄接口和靜態(tài)資源 if (uri.endsWith(/login.jsp) || uri.endsWith(/login) || uri.contains(/static/) || uri.contains(/images/)) { chain.doFilter(req, resp); return; } // 檢查 Session 中是否存在登錄標(biāo)志 if (request.getSession().getAttribute(loginUser) null) { response.sendRedirect(request.getContextPath() /login.jsp); return; } chain.doFilter(req, resp); } }WebFilter(/*)表示攔截所有請(qǐng)求chain.doFilter是放行動(dòng)作把請(qǐng)求繼續(xù)傳給后續(xù)的 Servlet。這里最容易被問倒的是放行邏輯——如果只想放行少數(shù)路徑用endsWith或contains逐個(gè)判斷即可如果想反著攔截少數(shù)路徑寫成if (!uri.endsWith(/login.jsp)) {…}會(huì)讓邏輯更繞不推薦。另外注意loginUser這個(gè) Session 屬性的名字要和登錄 Servlet 里setAttribute設(shè)置的一致否則會(huì)被自己的過濾器攔截到死循環(huán)反復(fù)跳回登錄頁(yè)。這個(gè)坑我見過很多人踩因?yàn)橘Y源包里登錄 Servlet 用的屬性名五花八門。4.4 改數(shù)據(jù)庫(kù)表結(jié)構(gòu)和初始數(shù)據(jù)讓數(shù)據(jù)「長(zhǎng)在你手上」前三個(gè)改造點(diǎn)更多是代碼層面的數(shù)據(jù)和表結(jié)構(gòu)的改造同樣重要。資源包的演示數(shù)據(jù)通常是通用模板改成貼合你自選主題的內(nèi)容不僅答辯更有說服力也讓整套項(xiàng)目真正變成「你的課程設(shè)計(jì)」。-- 給用戶表增加一個(gè)貼合業(yè)務(wù)場(chǎng)景的字段 ALTER TABLE user ADD COLUMN student_no VARCHAR(20) DEFAULT COMMENT 學(xué)號(hào); -- 把演示賬號(hào)改成你準(zhǔn)備好講解的數(shù)據(jù) UPDATE user SET real_name 張三, student_no 20240001 WHERE id 1;執(zhí)行以上 SQL 前先看清表結(jié)構(gòu)user表如果你的庫(kù)里已經(jīng)存在且有關(guān)聯(lián)表的外鍵引用修改主鍵 id 時(shí)要謹(jǐn)慎否則會(huì)破壞引用完整性。常見做法是只改非主鍵字段的數(shù)據(jù)不碰主鍵。這里的重點(diǎn)是答辯演示時(shí)老師會(huì)看到頁(yè)面上的真實(shí)數(shù)據(jù)如果數(shù)據(jù)和你的選題描述對(duì)不上解釋成本會(huì)直線上升。數(shù)據(jù)一改「這是不是我寫的」這個(gè)問題至少在觀感上有了答案。5. 跑通 JavaEE 課程設(shè)計(jì)前后的常見問題排查5 個(gè)踩坑記錄這一章寫的是把同類項(xiàng)目跑通時(shí)最高頻的 5 個(gè)問題每條都按「現(xiàn)象 → 原因 → 解決」來拆。這些問題出現(xiàn)的概率極高而且往往不依賴具體項(xiàng)目?jī)?nèi)容只要用的是 Servlet JSP Tomcat 這套組合它們遲早會(huì)出現(xiàn)在你的控制臺(tái)里。5.1 現(xiàn)象啟動(dòng) Tomcat 報(bào) ClassNotFoundException 或 NoClassDefFoundError控制臺(tái)一片紅指向某個(gè)類找不到但代碼里 import 明明沒問題。原因幾乎都是lib目錄里的 jar 包沒有被加入運(yùn)行時(shí)的部署結(jié)構(gòu)。Maven 工程還要額外確認(rèn)依賴是否為provided或compile范圍傳統(tǒng) Web 工程則要檢查 Project Structure 里的 Artifacts 有沒有把依賴勾選上。解決方式是IDEA 中進(jìn)入Project Structure - Modules - Dependencies確保lib已作為文件夾加入再進(jìn)入Artifacts - Output Layout把lib拖入WEB-INF/lib下。改完重建 Artifact重啟 Tomcat這個(gè)報(bào)錯(cuò)立刻消失。5.2 現(xiàn)象數(shù)據(jù)庫(kù)連接時(shí)報(bào) Access denied 或 Unknown database前端一提交登錄表單就拋 SQLException。原因基本是兩個(gè)密碼不對(duì)或數(shù)據(jù)庫(kù)名字不對(duì)。資源包里的db.properties寫的是作者本機(jī)的庫(kù)名和賬號(hào)你的 MySQL 里不一定有這個(gè)庫(kù)。解決方式先登錄 MySQL 控制臺(tái)執(zhí)行show databases;看庫(kù)名再對(duì)比配置文件里的 URL 末尾斜杠后的庫(kù)名。賬號(hào)密碼就老老實(shí)實(shí)改成你自己的 root 密碼別嫌麻煩。常見做法是新建一個(gè)專用賬號(hào)并授權(quán)避免把密碼放配置里又用弱密碼。5.3 現(xiàn)象頁(yè)面和數(shù)據(jù)中文全部變成問號(hào)或亂碼分兩種情況。一種是從數(shù)據(jù)庫(kù)讀出來的中文亂碼原因是連接串沒加characterEncodingutf8或者表本身是latin1字符集另一種是 JSP 頁(yè)面本身的亂碼原因是 JSP 頭部沒聲明頁(yè)面編碼。統(tǒng)一解決方案是JSP 頁(yè)面第一行寫% page contentTypetext/html;charsetUTF-8 languagejava %MySQL 建表時(shí)指定DEFAULT CHARSETutf8mb4連接串加上characterEncodingutf8三個(gè)地方都對(duì)齊后重啟項(xiàng)目亂碼問題基本絕跡。5.4 現(xiàn)象Tomcat 啟動(dòng)失敗報(bào) Address already in use: JVM_Bind原因很簡(jiǎn)單端口 8080 被另一個(gè) Tomcat 或進(jìn)程占用了。解決方式分兩步先查到占用進(jìn)程再?zèng)Q定殺進(jìn)程還是換端口。lsof -i :8080 # 查看 8080 端口被哪個(gè) PID 占用 kill -9 PID # 確認(rèn)是殘留進(jìn)程后強(qiáng)制結(jié)束如果你不想殺進(jìn)程開源方案是改 Tomcat 的conf/server.xml里Connector port8080改成 8081 或其他空閑端口。殺進(jìn)程對(duì)我來說是常規(guī)操作但在共享機(jī)器上慎用——先確認(rèn) PID 對(duì)應(yīng)的進(jìn)程確實(shí)是你自己的殘留 Java 進(jìn)程再動(dòng)手。5.5 現(xiàn)象編譯報(bào)找不到 getXxx/setXxx 方法代碼里卻沒寫這些方法代碼用了 Lombok 的Data注解但 IDEA 編譯時(shí)找不到自動(dòng)生成的方法。原因要么是 IDEA 沒裝 Lombok 插件要么是 Java 17 高版本 JDK 與舊版 Lombok 不兼容要么是annotationProcessor沒開啟。解決方式先裝 Lombok 插件并重啟 IDEA再確認(rèn)Settings - Build - Compiler - Annotation Processors里勾選 Enable annotation processing。如果還是不行就把 Lombok 版本換成支持當(dāng)前 JDK 的新版。這個(gè)問題的隱蔽性在于代碼看起來完全正常只有編譯時(shí)報(bào)錯(cuò)第一次遇到的人很可能誤判為依賴沒導(dǎo)全。6. 答辯前做一次「降級(jí)自測(cè)」和框架遷移準(zhǔn)備最終章給你兩個(gè)實(shí)用技巧。一個(gè)是答辯前的自查方法一個(gè)是把這份作業(yè)升級(jí)成 Spring Boot 項(xiàng)目的合理路徑。別急著關(guān)掉項(xiàng)目這兩個(gè)動(dòng)作能讓你的分?jǐn)?shù)和收獲都再上一檔。6.1 按評(píng)審視角做三輪自測(cè)第一輪以使用者身份操作從訪問登錄頁(yè)開始走完注冊(cè)、登錄、數(shù)據(jù)增刪改查、退出登錄的完整鏈路任何一步出現(xiàn) 404、500 或跳轉(zhuǎn)錯(cuò)亂記下來當(dāng)場(chǎng)修復(fù)。第二輪模擬老師的關(guān)注點(diǎn)打開代碼找一處你完全沒看懂的類死磕十分鐘直到能講出它的輸入、處理和輸出然后打開數(shù)據(jù)庫(kù)確認(rèn)每張表的字段和頁(yè)面表單元素能對(duì)上。第三輪做脫稿演練在沒看代碼的情況下講清楚「一次登錄請(qǐng)求經(jīng)過幾個(gè)組件、每個(gè)組件做什么、數(shù)據(jù)流向哪里」。準(zhǔn)備答辯的講法講究的是能串起一條數(shù)據(jù)流JSP 提交表單Servlet 接收參數(shù)并調(diào)用 Service 層Service 調(diào)用 DAO 層執(zhí)行 SQL結(jié)果封裝返回給 JSP 渲染。你能不能把這六句話講順基本決定了評(píng)審問不倒你的概率。6.2 把 DAO 和 Service 層平移到 Spring Boot可行的升級(jí)路徑如果你的課程要求用 Spring Boot 做框架或者你想讓這份作業(yè)進(jìn)入簡(jiǎn)歷不需要全盤重寫。Servlet 控制層可以丟棄但 Service 層和 DAO 層的業(yè)務(wù)邏輯完全可以復(fù)用。常見做法是新建一個(gè) Spring Boot 工程把原項(xiàng)目的 Service、DAO、實(shí)體類復(fù)制過去再把 DAO 里的原生 JDBC 代碼逐步替換為 Spring 的 JdbcTemplate依賴只需要下面這組。dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-jdbc/artifactId /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency遷移時(shí)先按 Controller、Service、DAO 三層把包結(jié)構(gòu)拆好再把原工具類里的數(shù)據(jù)庫(kù)連接改成application.properties中的spring.datasource.url配置。業(yè)務(wù)邏輯里的 SQL 語句可以原樣保留這不是重寫而是重構(gòu)周期比從零開發(fā)短得多。我當(dāng)年第一次把 Servlet 項(xiàng)目遷到 Spring Boot就用了這個(gè)思路只花了兩個(gè)晚上就完成了遷移而核心業(yè)務(wù)邏輯幾乎沒動(dòng)。后來我養(yǎng)成的習(xí)慣是課程設(shè)計(jì)絕不只做到「能跑」一定要在答辯前留出時(shí)間做一次降級(jí)自測(cè)——把自己放在評(píng)審的位置上把所有可能被追問的代碼重新讀一遍。這個(gè)習(xí)慣幫我避開了很多次臨場(chǎng)翻車希望也能幫到你。本文還有配套的精品資源點(diǎn)擊獲取