目申報(bào)管理系統(tǒng):課程設(shè)計(jì)源碼解析與部署避坑指南)
簡介jsp823科研項(xiàng)目教學(xué)成果申報(bào)管理系統(tǒng)MySQL版是面向高校師生的Java Web課程設(shè)計(jì)資源主要解決科研項(xiàng)目申報(bào)、審核、查詢與教學(xué)成果匯總展示等管理問題適合需要完成相關(guān)課題的學(xué)生、教師及科研管理人員使用。系統(tǒng)基于JSPServletMySQL構(gòu)建采用MVC分層設(shè)計(jì)覆蓋項(xiàng)目申報(bào)、審核、查詢、統(tǒng)計(jì)報(bào)表等完整業(yè)務(wù)流程支持項(xiàng)目名稱、負(fù)責(zé)人、研究方向、預(yù)期目標(biāo)等申報(bào)信息錄入與管理員審核把關(guān)邏輯清晰便于二次開發(fā)與答辯演示。整個(gè)RAR壓縮包共464個(gè)文件以JSP、Java、JavaScript、CSS、HTML和SQL腳本為主并包含GIF、PNG、JPG界面素材及JAR依賴庫整體約7.19MB目錄結(jié)構(gòu)較清晰。已有36人瀏覽學(xué)習(xí)包內(nèi)提供完整源代碼、數(shù)據(jù)庫建表腳本及配套報(bào)告可幫助學(xué)習(xí)者快速掌握數(shù)據(jù)庫設(shè)計(jì)、前后臺(tái)交互和部署流程是Java Web課程設(shè)計(jì)或畢業(yè)設(shè)計(jì)的實(shí)用參考。1. 課程設(shè)計(jì)常選的JSPMySQL組合這份源碼能幫你搞定什么如果你正在為一門Java Web課程設(shè)計(jì)發(fā)愁手頭又需要一個(gè)能講清楚、能跑通、能改動(dòng)的項(xiàng)目這個(gè)基于JSPMySQL的科研項(xiàng)目教學(xué)成果申報(bào)管理系統(tǒng)值得你花半小時(shí)拆一遍。它做的是高校里很常見的一件事老師提交科研項(xiàng)目申報(bào)信息管理員審核學(xué)生查進(jìn)度和成果最后還能按條件導(dǎo)出統(tǒng)計(jì)報(bào)表。所有操作都在瀏覽器里完成不需要裝任何客戶端。這個(gè)資源最大的價(jià)值在于它不是一個(gè)只貼著管理系統(tǒng)標(biāo)簽的空殼Demo而是把申報(bào)、審核、查詢、統(tǒng)計(jì)這條完整的業(yè)務(wù)鏈路用JSPServletMVC模式實(shí)現(xiàn)了一遍并且附帶了數(shù)據(jù)庫腳本和配套報(bào)告。對(duì)于課程設(shè)計(jì)來說你既能拿它交作業(yè)也能順著它的代碼骨架去擴(kuò)展自己的功能而不是從零開始搭一個(gè)連登錄都別扭的框架。接下來我按一個(gè)一線工程師的視角帶你從項(xiàng)目結(jié)構(gòu)、部署配置、核心業(yè)務(wù)到踩坑點(diǎn)完整過一遍。2. 從.class文件反推架構(gòu)JSPServletMVC骨架與三層分包打開壓縮包你會(huì)發(fā)現(xiàn)里面不是一堆亂扔的JSP文件而是能看出清晰分層的.class源碼目錄。這種老派的JSP項(xiàng)目不會(huì)用SpringBoot一鍵啟動(dòng)它是典型的Servlet統(tǒng)一入口 JSP展示 JDBC操作數(shù)據(jù)庫結(jié)構(gòu)對(duì)理解MVC本質(zhì)反而更直接。2.1 六個(gè)核心類是如何分工的壓縮包里能看到的幾個(gè).class文件其實(shí)已經(jīng)暴露了這個(gè)系統(tǒng)的整體設(shè)計(jì)思路。我挨個(gè)說下它們?cè)谀氵\(yùn)行時(shí)扮演的角色類名職責(zé)對(duì)應(yīng)MVC層次MainCtrl統(tǒng)一請(qǐng)求入口Servlet負(fù)責(zé)路由分發(fā)ControllerCommDAO封裝JDBC增刪改查的公共數(shù)據(jù)訪問對(duì)象ModelInfo業(yè)務(wù)實(shí)體類對(duì)應(yīng)申報(bào)項(xiàng)目信息ModelPageManager分頁邏輯計(jì)算頁數(shù)、偏移量、頁碼列表Model/工具類Upload處理表單文件上傳包括文件流解析與保存工具類StrUtil/SetChar字符串處理、請(qǐng)求和響應(yīng)編碼統(tǒng)一設(shè)置工具類這種設(shè)計(jì)的核心思想是JSP頁面只負(fù)責(zé)展示數(shù)據(jù)所有請(qǐng)求都交給MainCtrl這個(gè)Servlet去接收再由它根據(jù)參數(shù)調(diào)用CommDAO去操作數(shù)據(jù)庫。比如你點(diǎn)提交申報(bào)表單把數(shù)據(jù)POST給MainCtrlMainCtrl通過request.getParameter(xxx)取字段封裝成Info對(duì)象再調(diào)用CommDAO的insert方法寫入MySQL。整個(gè)過程沒有把SQL散落在各個(gè)頁面里后期維護(hù)和換數(shù)據(jù)庫都方便很多。2.2 為什么老課設(shè)項(xiàng)目偏愛Servlet而不上Spring現(xiàn)在的課程設(shè)計(jì)趨勢(shì)是SSMSpringSpringMVCMyBatis或者SpringBoot但這個(gè)項(xiàng)目選擇了最貼近Java Web原教旨的實(shí)現(xiàn)方式。我把兩者做一層對(duì)比Servlet方案請(qǐng)求直接命中某個(gè).do或.action路徑進(jìn)入Class文件邏輯寫在doPost里簡單粗暴但鏈路短調(diào)錯(cuò)方便適合理解HTTP請(qǐng)求處理全過程。SSM方案走了DispatcherServlet-Controller-Service-Mapper四層代碼量少但配置多新手經(jīng)常被IOC容器、事務(wù)管理器卡住最后變成能跑但不理解。對(duì)于課程設(shè)計(jì)答辯來說老師最愛問的問題就是請(qǐng)求從頁面到數(shù)據(jù)庫經(jīng)過了哪些類。用這個(gè)項(xiàng)目你從MainCtrl到CommDAO一條線就能講清楚不需要浮在框架上背書。我做入門項(xiàng)目時(shí)也一直推薦這種老牌寫法的變體——它能讓你看到最原始的請(qǐng)求-響應(yīng)循環(huán)之后再切框架會(huì)心安很多。2.3 JSP頁面與Servlet的映射關(guān)系這類項(xiàng)目的URL通常不是.aspx或.do而是帶有特定后綴的映射。你會(huì)看到web.xml里有類似這樣的配置servlet servlet-nameMainController/servlet-name servlet-classcom.xxx.servlet.MainCtrl/servlet-class /servlet servlet-mapping servlet-nameMainController/servlet-name url-pattern*.do/url-pattern /servlet-mapping配置的邏輯是所有以.do結(jié)尾的請(qǐng)求都會(huì)進(jìn)入MainCtrl。比如login.do、addProject.do、checkPending.do都從同一個(gè)入口進(jìn)再由MainCtrl內(nèi)部用if或switch去根據(jù)參數(shù)method值或路徑段區(qū)分動(dòng)作。這種設(shè)計(jì)的好處是過濾器、編碼設(shè)置、權(quán)限檢查都可以集中在入口做一次不用每個(gè)Servlet重復(fù)編寫。參數(shù)說明url-pattern里用星號(hào)通配必須寫成*.do這種后綴匹配如果你寫成/*Servlet會(huì)攔截所有資源包括CSS和JS導(dǎo)致頁面裸奔無樣式。這是新手最常見的手滑犯錯(cuò)的點(diǎn)之一后面避坑章節(jié)我會(huì)再提。3. 把系統(tǒng)跑起來環(huán)境搭配、建庫與三處容易漏的配置拿到項(xiàng)目不是直接往Tomcat里丟就行你得先保證環(huán)境和數(shù)據(jù)庫腳本的順序正確。很多同學(xué)卡在明明代碼沒問題卻白屏十有八九是環(huán)境版本沖突或字符集沒設(shè)對(duì)。下面這套流程是我在實(shí)際部署中反復(fù)跑過的最穩(wěn)路徑。3.1 環(huán)境搭配JDK、Tomcat、MySQL版本怎么選老項(xiàng)目對(duì)版本敏感我的經(jīng)驗(yàn)值是JDK 1.8 Tomcat 8.5/9.0 MySQL 5.7是兼容性最好的組合。這套組合有幾個(gè)好處JDK 1.8語法兼容Class文件編譯版本不會(huì)出現(xiàn)UnsupportedClassVersionError。Tomcat 8.5支持Servlet 3.1規(guī)范能跑老式web.xml配置。MySQL 5.7的驅(qū)動(dòng)連接字符串簡單不需要處理復(fù)雜的時(shí)區(qū)和SSL參數(shù)。如果你機(jī)器上已經(jīng)是MySQL 8.0也不是不能用但要改驅(qū)動(dòng)類和連接參數(shù)這一點(diǎn)在避坑章節(jié)我會(huì)給出具體報(bào)錯(cuò)和解決方式。建議先裝一個(gè)綠色版MySQL 5.7把項(xiàng)目跑通后再去考慮新版本兼容。3.2 建庫和數(shù)據(jù)導(dǎo)入項(xiàng)目壓縮包里通常會(huì)附帶一份.sql文件文件名大致是jsp823.sql或db_jsp823.sql。打開MySQL命令行或者Navicat按順序執(zhí)行以下操作mysql -u root -p # 輸入密碼后進(jìn)入MySQL命令行 CREATE DATABASE IF NOT EXISTS jsp823 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE jsp823; SOURCE D:/path/to/jsp823.sql;第一行創(chuàng)建數(shù)據(jù)庫重點(diǎn)是顯式指定utf8mb4字符集不然后面導(dǎo)入中文數(shù)據(jù)時(shí)會(huì)因?yàn)榻ū碚Z句沒帶字符集而出現(xiàn)亂碼。SOURCE后面填你本機(jī)sql文件的絕對(duì)路徑不要用相對(duì)路徑否則MySQL會(huì)提示找不到文件。導(dǎo)入之后用SHOW TABLES看一眼應(yīng)該能看到類似user表、project表、achievement表、audit_log表等核心表結(jié)構(gòu)。如果你拿到的是沒有SQL文件的版本那就得自己根據(jù)源碼里的建表語句重建。常見做法是看CommDAO里寫的INSERT、SELECT語句涉及哪些字段把表結(jié)構(gòu)反向補(bǔ)出來。我一般會(huì)先用Navicat的模型設(shè)計(jì)器把表關(guān)系畫出來再生成SQL這樣不會(huì)漏字段。3.3 web.xml與字符編碼配置老項(xiàng)目最容易忽略的地方就是編碼過濾器。你可能看到壓縮包里有一個(gè)SetChar.class它其實(shí)就是干這個(gè)事的。在部署時(shí)要確保兩個(gè)地方都設(shè)置了UTF-8filter filter-nameSetChar/filter-name filter-classcom.xxx.filter.SetChar/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param /filter filter-mapping filter-nameSetChar/filter-name url-pattern/*/url-pattern /filter-mapping這段配置要把請(qǐng)求和響應(yīng)統(tǒng)一轉(zhuǎn)成UTF-8。注意過濾器的url-pattern用/*是沒問題的因?yàn)樗沁^濾器不是Servlet不會(huì)攔截資源加載。SetChar內(nèi)部一般會(huì)執(zhí)行request.setCharacterEncoding(UTF-8)和response.setContentType(text/html;charsetUTF-8)這兩行如果你要手寫過濾器至少這兩行不能少。3.4 部署檢查清單部署完畢不要急著點(diǎn)頁面先按這個(gè)清單在腦子里過一遍WEB-INF/classes目錄下是否編譯好.class文件且包路徑和代碼里的package保持一致。WEB-INF/lib目錄里是否放了mysql-connector-java的jar包版本要和數(shù)據(jù)庫對(duì)應(yīng)。數(shù)據(jù)庫連接配置通常是一個(gè)constants.properties或db.properties文件里的URL、用戶名、密碼是否正確。我見過最快的失敗場(chǎng)景是lib里沒有驅(qū)動(dòng)包啟動(dòng)后第一次連數(shù)據(jù)庫就拋ClassNotFoundException。你把這個(gè)jar放進(jìn)lib重啟Tomcat就能解決。4. 申報(bào)、審核、統(tǒng)計(jì)的實(shí)現(xiàn)鏈路從表單到數(shù)據(jù)庫的完整調(diào)用跑通環(huán)境只是開始真正讓答辯通過的關(guān)鍵是你得把業(yè)務(wù)鏈路的代碼講清楚。這一章我拆三個(gè)核心功能教師提交申報(bào)、管理員審核回寫、按條件統(tǒng)計(jì)報(bào)表。這三條鏈路覆蓋了絕大多數(shù)課程設(shè)計(jì)答辯問題。4.1 教師提交申報(bào)的完整調(diào)用鏈假設(shè)教師在addProject.jsp頁面填完項(xiàng)目名稱、負(fù)責(zé)人、研究方向、預(yù)期目標(biāo)、進(jìn)度安排點(diǎn)擊提交按鈕。頁面里表單的action地址通常是form actionproject/add.do methodpost input typetext namepname / input typetext nameleader / input typetext namedirection / textarea namegoal/textarea textarea nameschedule/textarea input typesubmit value提交申報(bào) / /form表單提交到add.do后容器會(huì)把請(qǐng)求交給MainCtrl。它在doPost方法里根據(jù)路徑段判斷調(diào)用哪個(gè)業(yè)務(wù)邏輯代碼結(jié)構(gòu)大致是這樣的public class MainCtrl extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path request.getRequestURI(); if (path.endsWith(/project/add.do)) { ProjectService service new ProjectService(); Project p new Project(); p.setPname(request.getParameter(pname)); p.setLeader(request.getParameter(leader)); p.setDirection(request.getParameter(direction)); p.setGoal(request.getParameter(goal)); p.setSchedule(request.getParameter(schedule)); p.setStatus(待審核); int result service.add(p); if (result 0) { response.sendRedirect(list.do?page1); } else { request.setAttribute(msg, 提交失敗); request.getRequestDispatcher(/error.jsp).forward(request, response); } } } }這段邏輯很直白取參數(shù)、封裝成Project對(duì)象、調(diào)用Service層的add方法、根據(jù)返回值決定跳轉(zhuǎn)還是留在錯(cuò)誤頁。這里的ProjectService最終會(huì)調(diào)用CommDAO的insert方法把對(duì)象屬性通過PreparedStatement寫入MySQL。參數(shù)說明setStatus(待審核)這個(gè)字段很關(guān)鍵。申報(bào)流程里新提交的項(xiàng)目必須帶一個(gè)初始狀態(tài)審核頁面才能根據(jù)狀態(tài)去篩選數(shù)據(jù)。如果你要自己加狀態(tài)流轉(zhuǎn)建議從1開始編號(hào)而不是寫中文避免存儲(chǔ)編碼不一致導(dǎo)致查詢匹配不上。4.2 管理員審核與狀態(tài)回寫管理員登錄后進(jìn)入審核列表頁看到待審核的項(xiàng)目列表。每條數(shù)據(jù)后面有一個(gè)通過和駁回按鈕。點(diǎn)擊通過時(shí)表單會(huì)提交審核結(jié)果和審核意見。對(duì)應(yīng)的Servlet片段如下if (path.endsWith(/audit/doAudit.do)) { String pid request.getParameter(pid); String result request.getParameter(result); // pass 或 reject String opinion request.getParameter(opinion); String sql UPDATE project SET status?, audit_opinion? WHERE pid?; int rows CommDAO.executeUpdate(sql, result.equals(pass) ? 已通過 : 已駁回, opinion, pid); if (rows 0) { // 刪除或更新審核緩存數(shù)據(jù) response.sendRedirect(audit/list.do?statuspending); } }這里有個(gè)業(yè)務(wù)細(xì)節(jié)值得注意審核狀態(tài)不是簡單的布爾值而是待審核/已通過/已駁回三態(tài)。如果你把status字段設(shè)計(jì)成tinyint建議約定1待審、2通過、3駁回并在代碼里用常量類去定義避免散落魔法數(shù)字。邏輯說明審核完之后項(xiàng)目主表的狀態(tài)變了但當(dāng)用戶在成果展示頁面看到項(xiàng)目時(shí)還要把通過的項(xiàng)目數(shù)據(jù)同步到教學(xué)成果表中這一步常見做法是在同一事務(wù)里執(zhí)行兩條SQL或者通過狀態(tài)查詢直接動(dòng)態(tài)展示。如果你在源碼里看到achievement表它的數(shù)據(jù)通常就是從project表里已通過記錄復(fù)制過來的。4.3 查詢統(tǒng)計(jì)與分頁顯示系統(tǒng)帶的分頁工具PageManager是個(gè)亮點(diǎn)。它做的事情很純粹根據(jù)總記錄數(shù)、每頁條數(shù)、當(dāng)前頁碼算出起始偏移量和總頁數(shù)。在Servlet里使用它的流程是這樣的if (path.endsWith(/project/list.do)) { int pageNum Integer.parseInt(request.getParameter(page)); int pageSize 10; int totalCount CommDAO.queryCount(SELECT COUNT(*) FROM project WHERE status已通過); PageManager pm new PageManager(pageSize, totalCount, pageNum); int offset pm.getOffset(); ListProject list CommDAO.queryList( SELECT * FROM project WHERE status已通過 LIMIT ?, ?, offset, pageSize); request.setAttribute(pageManager, pm); request.setAttribute(list, list); request.getRequestDispatcher(/project_list.jsp).forward(request, response); }這段代碼的邏輯是先查總數(shù)再根據(jù)頁碼算偏移最后用LIMIT查出當(dāng)前頁數(shù)據(jù)。PageManager里封裝了getOffset()和getTotalPages()JSP頁面里用EL表達(dá)式或者JSTL標(biāo)簽就能循環(huán)輸出頁碼鏈接。參數(shù)選擇的考量LIMIT ?, ?語句里offset從0開始pageSize是每頁條數(shù)。如果頁碼從1開始傳你必須在進(jìn)PageManager之前做pageNum減1的換算不然第一頁會(huì)漏掉第一條數(shù)據(jù)。我在給別人排查時(shí)經(jīng)常發(fā)現(xiàn)這個(gè)bug第一頁少一條翻到第二頁又看到重復(fù)記錄這就是offset和pageNum混淆導(dǎo)致的。統(tǒng)計(jì)報(bào)表的實(shí)現(xiàn)也比較類似根據(jù)年度、院系、項(xiàng)目狀態(tài)等條件做GROUP BY把結(jié)果放到Map里再綁定到頁面的圖表標(biāo)簽。如果JSP頁面用了jquery-ui的圖表組件你只需要把統(tǒng)計(jì)出來的JSON字符串輸出到前端指定區(qū)域即可。5. 避坑排查手冊(cè)老JSP項(xiàng)目最容易翻車的五個(gè)點(diǎn)這部分內(nèi)容是我拆過大大小小幾十個(gè)JSP課設(shè)項(xiàng)目后的血淚經(jīng)驗(yàn)匯總。每個(gè)問題我都按現(xiàn)象 → 原因 → 解決來寫方便你遇到時(shí)直接檢索。5.1 MySQL 8.x連不上驅(qū)動(dòng)名、時(shí)區(qū)與SSL三連坑現(xiàn)象項(xiàng)目部署后訪問登錄頁輸入賬號(hào)密碼點(diǎn)擊登錄頁面報(bào)錯(cuò)Communications link failure或The server time zone value ?D1ú±ê×?ê±?? is unrecognized。原因MySQL 8.0的驅(qū)動(dòng)類名不再是com.mysql.jdbc.Driver而是com.mysql.cj.jdbc.Driver同時(shí)強(qiáng)校驗(yàn)時(shí)區(qū)和SSL連接參數(shù)。如果連接字符串里沒有serverTimezone字段驅(qū)動(dòng)不知道你所在時(shí)區(qū)直接拒絕連接。解決更新驅(qū)動(dòng)jar包為mysql-connector-java-8.0.x版本并把JDBC連接串改成長這樣jdbc:mysql://localhost:3306/jsp823?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai加useSSLfalse是因?yàn)楸緳C(jī)開發(fā)不用加密連接這條能減少SSL握手的版本警告。serverTimezoneAsia/Shanghai把時(shí)區(qū)固定成東八區(qū)徹底避開系統(tǒng)默認(rèn)時(shí)區(qū)識(shí)別錯(cuò)誤。5.2 中文亂碼不全在頁面現(xiàn)象數(shù)據(jù)庫里存的是正常中文但頁面上顯示或者?±‰?—亂碼。你已經(jīng)在頁面上寫了% page contentTypetext/html;charsetutf-8%還是不行。原因亂碼的根本原因是連接數(shù)據(jù)庫時(shí)沒指定字符集。JSP頁面編碼只保證請(qǐng)求和響應(yīng)部分JDBC層的characterEncoding參數(shù)缺失時(shí)MySQL連接使用latin1字符集中文在傳輸過程中被錯(cuò)誤轉(zhuǎn)換。解決到數(shù)據(jù)庫連接配置文件里把JDBC URL加上useUnicodetruecharacterEncodingutf8。同時(shí)檢查數(shù)據(jù)庫建表語句是否為utf8mb4。注意utf8和utf8mb4的差別在于emoji字符如果你只存中文utf8夠用但要保持一致方向不要表是utf8mb4連接串是utf8避免索引長度報(bào)錯(cuò)。5.3 上傳路徑寫死導(dǎo)致部署失敗現(xiàn)象本地運(yùn)行上傳頭像或附件都是好的打到服務(wù)器上一點(diǎn)上傳就報(bào)500日志提示FileNotFound或找不到目錄。原因Upload.class里往往用的是絕對(duì)路徑比如C:/upload/或D:/temp。你的課程設(shè)計(jì)演示機(jī)恰好有這個(gè)目錄換到別人機(jī)器或Linux服務(wù)器上就沒這個(gè)路徑mkdir失敗自然就報(bào)異常。解決打開Upload相關(guān)代碼或者JSP頁面上傳處理邏輯把寫死的路徑改成相對(duì)路徑基于ServletContext獲取真實(shí)絕對(duì)路徑。String realPath getServletContext().getRealPath(/upload); File dir new File(realPath); if (!dir.exists()) { dir.mkdirs(); }getRealPath(/upload)會(huì)返回當(dāng)前Web應(yīng)用部署目錄下的upload目錄真實(shí)絕對(duì)路徑。這樣不管項(xiàng)目丟到哪個(gè)Tomcat里路徑都會(huì)隨應(yīng)用自動(dòng)定位不會(huì)再出現(xiàn)換環(huán)境就丟文件的問題。5.4 改了JSP不生效瀏覽器緩存和Tomcat緩存疊加現(xiàn)象你改了index.jsp刷新頁面還是舊內(nèi)容甚至重啟Tomcat也沒用。原因老項(xiàng)目常見設(shè)置是瀏覽器端對(duì)JSP頁面做了304緩存你本地瀏覽器把上一版JSP生成后的HTML緩存住了。另外Tomcat的work目錄里存在編譯后的java文件不會(huì)自動(dòng)清理。解決兩步走。第一步在瀏覽器開發(fā)者工具中勾選Disable cache然后強(qiáng)制刷新CtrlF5。第二步刪除Tomcat安裝目錄下的work/Catalina/localhost/項(xiàng)目名文件夾讓Tomcat重新從src里編譯JSP。兩招都上問題必然消失。從那以后我每次部署改版后的JSP都強(qiáng)制走一遍這個(gè)流程不再靠反復(fù)重啟碰運(yùn)氣。5.5 Tomcat版本和JDK編譯級(jí)別不匹配現(xiàn)象啟動(dòng)Tomcat時(shí)控制臺(tái)報(bào)java.lang.UnsupportedClassVersionError: com/xxx/MainCtrl has been compiled by a more recent version of the Java Runtime。原因class文件的編譯版本高于Tomcat運(yùn)行時(shí)的JDK版本。比如源碼用JDK 17編譯而你運(yùn)行Tomcat的是JDK 8JVM不認(rèn)新版字節(jié)碼。解決兩種思路。一種是把項(xiàng)目里源碼的編譯級(jí)別調(diào)到1.8在Eclipse里右鍵項(xiàng)目Properties選擇Java Compiler設(shè)置為1.8保存后重新編譯另一種是升級(jí)Tomcat運(yùn)行環(huán)境到JDK 17。對(duì)課程設(shè)計(jì)而言建議用JDK 8跑更穩(wěn)定因?yàn)槔享?xiàng)目里很多第三方庫在舊JDK下沒有兼容性問題。6. 把這份源碼改造成你的課程設(shè)計(jì)擴(kuò)展功能與交付技巧跑通只是第一步想拿高分你得在原有框架上加一點(diǎn)自己的東西。這里給你三條不需要?jiǎng)哟笫中g(shù)就能落地的改造路徑。6.1 改表結(jié)構(gòu)時(shí)如何最小化動(dòng)Java代碼如果你想加一個(gè)項(xiàng)目類型字段比如區(qū)分縱向課題和橫向課題不需要重寫所有Servlet。做法是在project表里增加一個(gè)type字段然后在新增申報(bào)的JSP表單里加一個(gè)下拉框name屬性設(shè)為type。MainCtrl里新增一行request.getParameter(type)賦值給Info對(duì)象的type屬性再在列表頁顯示時(shí)加一列輸出。數(shù)據(jù)庫字段、Java實(shí)體類屬性、頁面表單元素三個(gè)位置對(duì)應(yīng)好其他代碼不受影響。這個(gè)模式在MVC里叫擴(kuò)充實(shí)體屬性是成本最低的功能擴(kuò)展方式。6.2 加角色權(quán)限的快捷路徑角色可訪問頁面操作范圍教師addProject.jsp、myProjectList.jsp申報(bào)、修改未審核項(xiàng)目管理員auditList.jsp、statistics.jsp審核、駁回、統(tǒng)計(jì)、刪除學(xué)生projectSearch.jsp、achievementList.jsp查詢、查看成果展示如果你想讓不同角色登錄后看到不同菜單不用寫SpringSecurity那種重框架。最簡單的方式是在SetChar過濾器或MainCtrl入口處加一段Session判斷登錄成功時(shí)把用戶角色寫進(jìn)session需要保護(hù)的路徑從Session里取角色不匹配就跳轉(zhuǎn)403頁面。代碼只需要不到二十行但答辯時(shí)能講出權(quán)限控制的思路比單純的功能大雜燴要加分得多。6.3 交付時(shí)別忘了寫環(huán)境說明我最后建議你做一件事在項(xiàng)目根目錄新建一個(gè)README.md把數(shù)據(jù)庫版本、JDK版本、Tomcat版本、導(dǎo)入步驟、默認(rèn)管理員賬號(hào)寫清楚。別把這個(gè)當(dāng)應(yīng)付差事你想想答辯老師或者接手你代碼的下一屆學(xué)弟他們拿到項(xiàng)目后能十分鐘內(nèi)跑起來第一印象就是這學(xué)生工程素養(yǎng)不錯(cuò)。我見過太多把項(xiàng)目直接打包發(fā)出去連數(shù)據(jù)庫賬號(hào)密碼都不說一聲的案例結(jié)果對(duì)方打開就全亂套了。從那以后我每次交付課設(shè)源碼都強(qiáng)制自己走一遍換一臺(tái)干凈機(jī)器重新部署的測(cè)試流程驗(yàn)證完再交。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取