站畢設(shè)全攻略:源碼、論文與答辯PPT詳解)
簡(jiǎn)介在Java Web開發(fā)領(lǐng)域SpringBoot憑借約定大于配置、內(nèi)嵌容器等特性大幅降低了項(xiàng)目搭建門檻已成為企業(yè)級(jí)應(yīng)用和畢業(yè)設(shè)計(jì)的主流選擇。結(jié)合MyBatis與MySQL開發(fā)者可以高效實(shí)現(xiàn)數(shù)據(jù)持久化與業(yè)務(wù)邏輯分離。權(quán)限控制、文件上傳、分頁搜索等經(jīng)典功能模塊則是理解Web系統(tǒng)設(shè)計(jì)的關(guān)鍵實(shí)踐場(chǎng)景。對(duì)于準(zhǔn)備畢業(yè)設(shè)計(jì)的學(xué)生而言選擇一個(gè)功能完整、技術(shù)棧穩(wěn)定的項(xiàng)目至關(guān)重要。校園新聞網(wǎng)站恰好覆蓋前后端交互、數(shù)據(jù)庫設(shè)計(jì)、角色權(quán)限管理等核心知識(shí)點(diǎn)既能鍛煉工程能力又便于論文撰寫與答辯展示。本文圍繞SpringBoot校園新聞網(wǎng)站的完整開發(fā)流程從技術(shù)選型、數(shù)據(jù)庫設(shè)計(jì)到核心功能實(shí)現(xiàn)再到論文編寫與答辯PPT制作系統(tǒng)梳理實(shí)踐要點(diǎn)與避坑經(jīng)驗(yàn)為同類畢設(shè)任務(wù)提供可直接參考的完整方案。 畢設(shè)避坑指南我從零做完一個(gè)SpringBoot校園新聞網(wǎng)站源碼、論文和答辯PPT一次講透如果你正在為畢業(yè)設(shè)計(jì)發(fā)愁或者想找一個(gè)既能應(yīng)付答辯、又能真正學(xué)到東西的Java Web項(xiàng)目SpringBoot校園新聞網(wǎng)站絕對(duì)是一個(gè)經(jīng)典到不能再經(jīng)典的選題。它不復(fù)雜但五臟俱全前端展示、后臺(tái)管理、數(shù)據(jù)庫設(shè)計(jì)、權(quán)限控制、文件上傳……這些畢業(yè)設(shè)計(jì)答辯時(shí)老師最愛問的點(diǎn)一個(gè)不落。我自己當(dāng)初就是選了這么一個(gè)項(xiàng)目從搭環(huán)境到最后答辯通過前后折騰了將近兩個(gè)月踩了不少坑也積累了不少經(jīng)驗(yàn)。這篇文章就把整個(gè)項(xiàng)目的設(shè)計(jì)與實(shí)現(xiàn)思路、核心代碼邏輯、論文編寫要點(diǎn)和答辯PPT的制作思路一次講清楚源碼和配套文檔的思路也會(huì)一并拆解希望能給正在做同類項(xiàng)目的你提供一份“抄作業(yè)”級(jí)別的參考。1. 項(xiàng)目整體設(shè)計(jì)與技術(shù)選型解析1.1 為什么選SpringBoot而不是SSH或SSM很多學(xué)校其實(shí)還在教SSHStruts2 Spring Hibernate或者SSMSpring SpringMVC MyBatis但如果你問我畢設(shè)選什么我強(qiáng)烈建議直接用SpringBoot。原因很簡(jiǎn)單省去大量XML配置項(xiàng)目能在幾分鐘內(nèi)跑起來。在畢設(shè)答辯現(xiàn)場(chǎng)老師要看的是你能不能把項(xiàng)目啟動(dòng)、演示功能而不是聽你解釋web.xml里配了多少個(gè)監(jiān)聽器。SpringBoot的核心優(yōu)勢(shì)在于“約定大于配置”。內(nèi)嵌Tomcat打包成jar直接java -jar就能跑不需要單獨(dú)裝Tomcat、不需要手動(dòng)部署war包。對(duì)于畢設(shè)這種需要快速演示的場(chǎng)景來說這個(gè)優(yōu)勢(shì)特別大。另外SpringBoot的生態(tài)非常成熟集成MyBatis、Spring Security、Thymeleaf、Spring Data JPA都是幾行配置的事方便我們?cè)谡撐睦飳憽氨鞠到y(tǒng)基于SpringBoot框架實(shí)現(xiàn)了快速開發(fā)與模塊化設(shè)計(jì)”。但要注意一個(gè)點(diǎn)SpringBoot版本不要追新。我見過很多同學(xué)一上來就裝Spring Boot 3.x結(jié)果MyBatis、druid這些老牌依賴兼容性出問題光調(diào)依賴就調(diào)了一周。做畢設(shè)最穩(wěn)妥的版本是Spring Boot 2.x系列比如2.5.4、2.7.xJDK用1.8或者11就夠了。不是越新越好穩(wěn)定能跑才是第一位的。1.2 技術(shù)棧選擇與前后端方案權(quán)衡校園新聞網(wǎng)站的整體技術(shù)棧市面上主流有兩種組合方案ASpringBoot Thymeleaf模板引擎 MyBatis MySQL。前后端不分離頁面由服務(wù)端渲染。方案BSpringBoot Vue Axios MyBatis MySQL。前后端分離前端工程化。我個(gè)人的建議除非你對(duì)Vue已經(jīng)非常熟否則選方案A。原因很現(xiàn)實(shí)畢設(shè)的評(píng)分重點(diǎn)在“功能完整度 論文邏輯 答辯表述”而不是技術(shù)棧的新舊。Thymeleaf的語法和HTML差不多學(xué)習(xí)成本極低而且不用處理跨域問題CORS不用單獨(dú)啟動(dòng)Node服務(wù)部署時(shí)一個(gè)jar包就搞定。方案B雖然看上去更“高大上”但你要多維護(hù)一套前端工程答辯時(shí)也會(huì)被追問“你是怎么解決跨域的”“Nginx你配過嗎”這類問題回答不上來反而減分。如果學(xué)校明確要求前后端分離那就另當(dāng)別論但純做后端渲染的校園新聞網(wǎng)站完全夠用而且能省下大量時(shí)間打磨論文和答辯PPT。1.3 項(xiàng)目目錄結(jié)構(gòu)與核心依賴配置先列一個(gè)我使用下來的項(xiàng)目目錄結(jié)構(gòu)大家可以直接參考src/main/java/com/example/news/ ├── controller/ // Control層接收請(qǐng)求 │ ├── AdminController.java │ ├── NewsController.java │ ├── CategoryController.java │ └── UserController.java ├── service/ // Service層業(yè)務(wù)邏輯 │ ├── NewsService.java │ ├── CategoryService.java │ ├── UserService.java │ └── CommentService.java ├── mapper/ // MyBatis的Mapper接口 │ ├── NewsMapper.java │ ├── CategoryMapper.java │ └── UserMapper.java ├── entity/ // 數(shù)據(jù)庫實(shí)體類 │ ├── News.java │ ├── Category.java │ ├── User.java │ └── Comment.java ├── common/ // 通用工具類 │ ├── Result.java // 統(tǒng)一返回結(jié)果 │ └── PageResult.java // 分頁結(jié)果封裝 └── NewsApplication.java // SpringBoot啟動(dòng)類Maven的pom.xml里核心依賴就這幾個(gè)!-- 核心框架 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- 模板引擎 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-thymeleaf/artifactId /dependency !-- MyBatis集成 -- dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version2.2.2/version /dependency !-- MySQL驅(qū)動(dòng) -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency !-- 權(quán)限控制可選但建議加 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-security/artifactId /dependency注意如果用了Security務(wù)必記得寫配置類否則默認(rèn)會(huì)攔截所有請(qǐng)求并彈出登錄框。很多同學(xué)第一次啟動(dòng)項(xiàng)目發(fā)現(xiàn)頁面打不開就是這個(gè)原因。application.yml里的核心配置server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/campus_news?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.news.entity configuration: map-underscore-to-camel-case: true file: upload-path: /usr/local/upload/ # 圖片上傳路徑Windows下改成 D:/upload/注意一個(gè)細(xì)節(jié)serverTimezoneAsia/Shanghai必須加否則JDBC連接MySQL 8.x時(shí)會(huì)報(bào)時(shí)區(qū)錯(cuò)誤。這個(gè)坑幾乎每個(gè)人都會(huì)踩。2. 系統(tǒng)需求分析與數(shù)據(jù)庫設(shè)計(jì)2.1 用戶角色與核心功能拆解校園新聞網(wǎng)站的核心用戶角色有三個(gè)普通訪客游客、管理員、新聞發(fā)布員。如果擴(kuò)展開還可以有新聞審核員但畢設(shè)做到三種角色已經(jīng)足夠了。普通訪客能干什么瀏覽首頁新聞列表、按分類查看新聞、搜索新聞、查看新聞詳情、注冊(cè)登錄后發(fā)表評(píng)論。管理員能干什么除訪客權(quán)限外還能進(jìn)入后臺(tái)管理界面維護(hù)新聞分類、管理用戶賬號(hào)禁用/啟用、審核新聞內(nèi)容可選、管理評(píng)論刪除違規(guī)評(píng)論。新聞發(fā)布員能干什么登錄后可以發(fā)布新聞、編輯自己發(fā)布的新聞、刪除自己的新聞。這個(gè)角色實(shí)際上就是管理員的一個(gè)細(xì)分在權(quán)限控制上可以復(fù)用同一套邏輯也可以通過角色標(biāo)識(shí)區(qū)分。很多同學(xué)做出來的網(wǎng)站看上去功能很全但實(shí)際上只是一個(gè)“新聞?wù)故? 增刪改查”的堆砌。我建議在論文里一定要用用例圖把這三個(gè)角色的權(quán)限邊界畫清楚這不僅是軟件工程課程的硬性要求也是答辯老師評(píng)估你“系統(tǒng)分析能力”的重要標(biāo)準(zhǔn)。2.2 新聞系統(tǒng)和數(shù)據(jù)庫表設(shè)計(jì)數(shù)據(jù)庫設(shè)計(jì)是整個(gè)項(xiàng)目的根基。設(shè)計(jì)得好后期寫代碼非常順暢設(shè)計(jì)亂了后期各種SQL關(guān)聯(lián)查詢會(huì)讓你懷疑人生。我當(dāng)時(shí)把項(xiàng)目翻了一次盤就是因?yàn)榈谝话嬖O(shè)計(jì)少了一張?jiān)u論表導(dǎo)致后面硬編碼字符串存評(píng)論內(nèi)容極其痛苦。核心表我建議至少設(shè)計(jì)這五張分類表category字段名類型說明idint主鍵自增namevarchar(50)分類名稱比如“校園通知”“學(xué)術(shù)活動(dòng)”sortint排序字段數(shù)值越小越靠前create_timedatetime創(chuàng)建時(shí)間新聞表news字段名類型說明idint主鍵自增category_idint分類ID外鍵titlevarchar(200)新聞標(biāo)題summaryvarchar(500)摘要列表頁展示contenttext正文內(nèi)容富文本cover_imagevarchar(255)封面圖URLauthor_idint發(fā)布人IDview_countint瀏覽量statustinyint0草稿1已發(fā)布2已下架create_timedatetime發(fā)布時(shí)間用戶表user字段名類型說明idint主鍵自增usernamevarchar(50)用戶名唯一passwordvarchar(255)密碼MD5或BCrypt加密nicknamevarchar(50)昵稱roletinyint角色1管理員2發(fā)布員3普通用戶avatarvarchar(255)頭像URLstatustinyint0禁用1正常create_timedatetime注冊(cè)時(shí)間評(píng)論表comment字段名類型說明idint主鍵自增news_idint新聞IDuser_idint評(píng)論用戶IDcontentvarchar(500)評(píng)論內(nèi)容create_timedatetime評(píng)論時(shí)間新聞圖片表news_image可選很多校園新聞會(huì)有多圖展示需求如果只存一個(gè)封面圖不夠建議加一張子表存儲(chǔ)正文中的圖片路徑。不過如果對(duì)功能要求不高也可以直接把圖片以img標(biāo)簽的形式嵌入富文本內(nèi)容中省一張表。SQL的建表語句里注意幾點(diǎn)字符集用utf8mb4不要用utf8。因?yàn)閡tf8在MySQL里最多存3字節(jié)而一些生僻字和Emoji表情是4字節(jié)編碼一旦用戶輸入了這些內(nèi)容直接報(bào)錯(cuò)。這個(gè)坑非常隱蔽我當(dāng)初排查了很久才發(fā)現(xiàn)是字符集問題。2.3 核心流程設(shè)計(jì)發(fā)布、審核與展示的邏輯很多畢設(shè)項(xiàng)目做出來功能是通的但流程是亂的。比如用戶發(fā)布的新聞直接出現(xiàn)在首頁沒有任何審核機(jī)制這在答辯時(shí)是比較容易被質(zhì)疑的點(diǎn)如果這是“校園新聞網(wǎng)站”那惡意用戶發(fā)垃圾新聞怎么辦所以我在設(shè)計(jì)時(shí)加了一個(gè)狀態(tài)機(jī)新聞從“草稿 - 待審核 - 已發(fā)布 - 下架”。發(fā)布員提交新聞后狀態(tài)為“待審核”管理員在后臺(tái)能看到待審核列表點(diǎn)擊通過后新聞才會(huì)出現(xiàn)在前臺(tái)首頁。如果管理員駁回可以填寫駁回原因可選。這個(gè)設(shè)計(jì)本身邏輯不難但在論文里可以寫出一小節(jié)“系統(tǒng)核心業(yè)務(wù)流程設(shè)計(jì)”配上流程圖B格直接拉滿。而且在答辯時(shí)如果老師問“你怎么避免垃圾內(nèi)容被公開展示”你就可以理直氣壯地回答“我設(shè)計(jì)了審核機(jī)制”。這比“我的系統(tǒng)功能都有只是沒做審核”要有說服力得多。3. 核心功能實(shí)現(xiàn)與難點(diǎn)攻克3.1 登錄鑒權(quán)與權(quán)限控制的兩種實(shí)現(xiàn)方式用戶登錄和權(quán)限控制是每個(gè)Web項(xiàng)目的核心也是答辯老師必問的內(nèi)容。校園新聞網(wǎng)站的權(quán)限控制有兩種常見實(shí)現(xiàn)方式第一種是使用Spring Security JWT或Session。優(yōu)點(diǎn)是安全性高、擴(kuò)展性好缺點(diǎn)是配置復(fù)雜對(duì)初學(xué)者不太友好。如果你對(duì)Security不熟光一個(gè)SecurityConfig就能卡你一星期。第二種是使用攔截器HandlerInterceptor Session自己寫一套簡(jiǎn)單的權(quán)限校驗(yàn)邏輯。優(yōu)點(diǎn)是代碼透明、容易理解論文里也好解釋缺點(diǎn)是安全性不如Security全面。我的建議如果只是為了畢設(shè)用第二種完全足夠。寫一個(gè)LoginInterceptor在preHandle方法里判斷Session中是否存在登錄用戶再判斷訪問路徑是否以/admin開頭且用戶角色是否為管理員。核心代碼只有十幾行。Component public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri request.getRequestURI(); // 如果是后臺(tái)路徑必須登錄且為管理員 if (uri.startsWith(/admin)) { User user (User) request.getSession().getAttribute(loginUser); if (user null) { response.sendRedirect(/login); return false; } if (user.getRole() ! 1) { response.setContentType(text/html;charsetutf-8); response.getWriter().write(scriptalert(無權(quán)限訪問);location.href/;/script); return false; } } return true; } }上面的代碼里role字段1表示管理員2表示發(fā)布員3表示普通用戶。這里我特別留意了“路徑前綴匹配”的方式后臺(tái)所有頁面統(tǒng)一放在/admin/**下面管理起來非常方便。配置一下WebMvcConfigurer把攔截器注冊(cè)進(jìn)去就行Configuration public class WebConfig implements WebMvcConfigurer { Resource private LoginInterceptor loginInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns(/**) .excludePathPatterns(/login, /register, /css/**, /js/**, /images/**, /news/**); } }關(guān)于密碼加密別用MD5了容易被問倒。現(xiàn)在主流是BCrypt加密Spring Security里就自帶BCryptPasswordEncoder。你不需要引入整個(gè)Spring Security單獨(dú)引入spring-security-crypto這個(gè)依賴也可以使用BCryptPasswordEncoder。在注冊(cè)時(shí)對(duì)密碼加密登錄時(shí)用matches方法校驗(yàn)。// 注冊(cè)時(shí)加密 String encodedPwd new BCryptPasswordEncoder().encode(user.getPassword()); user.setPassword(encodedPwd); // 登錄時(shí)校驗(yàn) boolean match new BCryptPasswordEncoder().matches(rawPassword, user.getPassword());這個(gè)加密方式在論文“系統(tǒng)安全設(shè)計(jì)”那一小節(jié)里寫出來會(huì)顯得比較專業(yè)。3.2 新聞發(fā)布中的圖片上傳與富文本處理圖片上傳是校園新聞網(wǎng)站里最容易出Bug的功能。核心難點(diǎn)有兩個(gè)一是文件存儲(chǔ)路徑。開發(fā)環(huán)境下的D:/upload和生產(chǎn)環(huán)境下的/usr/local/upload不一樣如果硬編碼在代碼里換環(huán)境就掛。我的做法是在application.yml里配置一個(gè)變量然后在Controller中通過Value注入。二是靜態(tài)資源映射。SpringBoot的默認(rèn)靜態(tài)資源路徑是classpath:/static/你把圖片傳到磁盤上默認(rèn)是訪問不到的。需要在WebConfig里配置虛擬路徑映射Override public void addResourceHandlers(ResourceHandlerRegistry registry) { String uploadPath fileUploadPath /; registry.addResourceHandler(/upload/**) .addResourceLocations(file: uploadPath); }Controller層接收上傳文件的代碼大致是PostMapping(/admin/news/uploadImage) ResponseBody public Result uploadImage(RequestParam(file) MultipartFile file) { if (file.isEmpty()) { return Result.error(文件不能為空); } String originalFilename file.getOriginalFilename(); String ext originalFilename.substring(originalFilename.lastIndexOf(.)); // 校驗(yàn)文件類型防止上傳jsp等危險(xiǎn)文件 ListString allowTypes Arrays.asList(.jpg, .jpeg, .png, .gif); if (!allowTypes.contains(ext.toLowerCase())) { return Result.error(圖片格式不支持); } String newName UUID.randomUUID().toString().replace(-, ) ext; File dest new File(uploadPath newName); try { file.transferTo(dest); return Result.success(/upload/ newName); } catch (IOException e) { e.printStackTrace(); return Result.error(上傳失敗); } }提示文件名必須用UUID重命名不能用用戶上傳的原始文件名。一是防止文件名重復(fù)覆蓋二是避免中文文件名在Linux環(huán)境下亂碼三是能避免路徑穿越攻擊。富文本編輯器推薦用UEditor或者WangEditor。WangEditor更輕量而且MIT協(xié)議用在畢設(shè)里沒有版權(quán)問題。前端引入JS后通過editor.getHtml()把富文本內(nèi)容提交到后端。后端直接存content字段就行不需要額外處理展示時(shí)用th:utext而不是th:text來渲染否則HTML標(biāo)簽會(huì)原樣顯示。關(guān)于XSS攻擊直接用th:utext是存在安全隱患的用戶如果提交了script標(biāo)簽會(huì)被瀏覽器執(zhí)行。有的項(xiàng)目選擇用Jsoup來做HTML白名單過濾去掉script、iframe等標(biāo)簽是很穩(wěn)妥的做法。論文中把這一點(diǎn)作為“系統(tǒng)安全防護(hù)措施”寫進(jìn)去很加分。3.3 首頁數(shù)據(jù)展示、分頁與搜索的實(shí)現(xiàn)細(xì)節(jié)校園新聞網(wǎng)站的門面就是首頁。我的首頁設(shè)計(jì)是頂部導(dǎo)航欄顯示新聞分類中間是輪播圖展示前5條置頂新聞下面按照分類展示最新新聞列表。分頁查詢建議用MyBatis的分頁插件PageHelper非常成熟用法也簡(jiǎn)單// Service中 PageHelper.startPage(pageNum, pageSize); ListNews newsList newsMapper.selectByCategoryId(categoryId); PageInfoNews pageInfo new PageInfo(newsList);PageInfo里包含了總記錄數(shù)、總頁數(shù)、當(dāng)前頁等所有信息直接返回給前端使用即可。需要注意一點(diǎn)PageHelper.startPage只對(duì)接下來查詢到的第一條SQL生效所以在調(diào)用startPage之后必須緊跟Mapper查詢中間不要夾雜其他SQL。搜索功能的實(shí)現(xiàn)也很簡(jiǎn)單在NewsMapper.xml里加一條動(dòng)態(tài)SQLselect idsearchNews resultTypecom.example.news.entity.News SELECT * FROM news where if testkeyword ! null and keyword ! AND title LIKE CONCAT(%, #{keyword}, %) /if if testcategoryId ! null AND category_id #{categoryId} /if AND status 1 /where ORDER BY create_time DESC /select這里用where標(biāo)簽可以自動(dòng)處理多個(gè)條件拼接時(shí)的AND問題是一個(gè)細(xì)節(jié)技巧。如果用trim標(biāo)簽也可以但新手更容易出錯(cuò)建議直接用where。搜索這塊還有一個(gè)容易被忽視的點(diǎn)關(guān)鍵詞的防注入。MyBatis的#{}是預(yù)編譯方式天然防SQL注入所以上面這么寫是安全的。如果你用了${}那就非常危險(xiǎn)了直接寫進(jìn)論文里會(huì)變成一個(gè)負(fù)面案例。3.4 三個(gè)容易翻車的細(xì)節(jié)時(shí)間格式化、事務(wù)回滾、日志輸出我在做這個(gè)項(xiàng)目時(shí)有幾個(gè)小細(xì)節(jié)反復(fù)折磨人這里一并分享出來。第一個(gè)是時(shí)間格式化。默認(rèn)情況下從MySQL查出來的datetime字段是java.util.Date類型直接用${news.createTime}輸出會(huì)是一長串英文格式比如Tue Aug 15 10:30:00 CST 2023非常不美觀。解決方案有兩個(gè)一是在實(shí)體類的字段上加JsonFormat注解如果是返回JSON二是直接在service層轉(zhuǎn)換成String類型并格式化為yyyy-MM-dd HH:mm:ss。更簡(jiǎn)單的方案是在Thymeleaf模板中用#temporals工具類處理但語法稍微復(fù)雜一些。我當(dāng)時(shí)直接在實(shí)體里加了一個(gè)格式化方法public String getCreateTimeStr() { if (this.createTime null) { return ; } SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd HH:mm); return sdf.format(this.createTime); }然后在頁面上th:text${news.createTimeStr}即可簡(jiǎn)單省事。第二個(gè)是事務(wù)問題。一個(gè)新聞發(fā)布流程可能涉及兩次數(shù)據(jù)庫操作插入新聞主記錄、更新分類下的新聞數(shù)量如果設(shè)計(jì)了冗余字段。第一次成功、第二次失敗的話就會(huì)造成數(shù)據(jù)不一致。加上Transactional注解是最基本的Transactional(rollbackFor Exception.class) public void addNews(News news) { newsMapper.insert(news); categoryMapper.increaseCount(news.getCategoryId()); }注意rollbackFor Exception.class必須寫因?yàn)镾pring默認(rèn)只在拋出RuntimeException時(shí)才回滾。如果你在實(shí)際中拋出了一個(gè)受檢異常Exception不寫這個(gè)參數(shù)就不會(huì)回滾很容易踩坑。第三個(gè)是日志。很多同學(xué)在排查問題時(shí)全靠System.out.println()項(xiàng)目里到處是輸出語句答辯時(shí)演示頁面控制臺(tái)一片紅看起來很不專業(yè)。建議用SLF4J Logback的組合SpringBoot默認(rèn)已經(jīng)集成了只需在類上聲明Slf4j Service public class NewsServiceImpl implements NewsService { // 業(yè)務(wù)代碼 }Slf4j是Lombok提供的注解能自動(dòng)生成log對(duì)象在關(guān)鍵節(jié)點(diǎn)打日志。論文里也可以寫“本系統(tǒng)采用SLF4J日志框架為系統(tǒng)運(yùn)維提供了可靠依據(jù)”之類的描述顯得系統(tǒng)更規(guī)范。4. 論文編寫與PPT答辯全流程這一部分其實(shí)很多人忽視但在實(shí)際評(píng)分中論文和答辯PPT的比重往往和代碼差不多甚至更高。見過不少項(xiàng)目功能做的很棒、論文寫得稀爛的最終成績(jī)并不理想。血的教訓(xùn)告訴我畢設(shè)不只是寫代碼更是“做材料”。4.1 論文結(jié)構(gòu)怎么搭才合理一份完整的畢業(yè)設(shè)計(jì)論文結(jié)構(gòu)一般是摘要中英文各一頁第一章 緒論背景與意義、國內(nèi)外研究現(xiàn)狀、主要工作第二章 相關(guān)技術(shù)介紹SpringBoot、MyBatis、MySQL、Thymeleaf第三章 系統(tǒng)分析需求分析、可行性分析、用例圖、功能模塊圖第四章 系統(tǒng)設(shè)計(jì)總體架構(gòu)、數(shù)據(jù)庫設(shè)計(jì)、核心類設(shè)計(jì)第五章 系統(tǒng)實(shí)現(xiàn)界面截圖 核心代碼 文字說明第六章 系統(tǒng)測(cè)試測(cè)試用例表格、測(cè)試結(jié)果分析最容易出現(xiàn)的問題技術(shù)介紹部分大段百度抄和后面系統(tǒng)設(shè)計(jì)脫節(jié)。我建議“相關(guān)技術(shù)介紹”這一章可以控制在4-6頁把SpringBoot的核心特性、MyBatis的工作流程寫清楚就行要給后面系統(tǒng)設(shè)計(jì)留足空間。核心的專業(yè)性體現(xiàn)在第四章和第五章。數(shù)據(jù)庫設(shè)計(jì)部分E-R圖一定要畫最好用Visio或者draw.io畫得干凈一點(diǎn)。每張表都要給出設(shè)計(jì)表格并描述每個(gè)字段的含義。系統(tǒng)實(shí)現(xiàn)部分每個(gè)功能模塊至少配一張界面截圖加一段核心代碼代碼不需要很長的完整類挑關(guān)鍵代碼片段即可。摘要這部分很容易被忽略但導(dǎo)師一定第一個(gè)看。摘要不要寫“本文研究了……”“本文介紹了……”而是要寫清楚“系統(tǒng)包含哪些功能模塊、采用什么技術(shù)方案、達(dá)到了什么效果”。三四句話把精華說清楚比套話強(qiáng)得多。4.2 答辯PPT的制作思路與內(nèi)容組織答辯PPT不用追求頁數(shù)多但每一頁都要有價(jià)值。我的PPT只有12頁但邏輯非常完整封面題目、姓名、學(xué)號(hào)、指導(dǎo)老師目錄研究背景與意義1頁簡(jiǎn)要說明為什么做這個(gè)系統(tǒng)系統(tǒng)技術(shù)架構(gòu)1頁畫一個(gè)簡(jiǎn)單的技術(shù)架構(gòu)圖功能模塊介紹1頁用系統(tǒng)功能結(jié)構(gòu)圖展示核心功能演示3-4頁放關(guān)鍵界面截圖配一兩個(gè)核心代碼或核心設(shè)計(jì)點(diǎn)數(shù)據(jù)庫設(shè)計(jì)展示1頁關(guān)鍵表結(jié)構(gòu)截圖即可系統(tǒng)測(cè)試結(jié)果1頁放關(guān)鍵測(cè)試用例和結(jié)果總結(jié)與展望1頁P(yáng)PT制作注意配色統(tǒng)一不要用花哨的模板。技術(shù)類答辯白色背景 深色文字是最穩(wěn)的。每頁文字不要多控制在5行以內(nèi)答辯時(shí)PPT只是輔助重點(diǎn)是你的口頭表達(dá)。功能演示部分建議錄制一段短視頻嵌入PPT這樣可以避免現(xiàn)場(chǎng)網(wǎng)絡(luò)、環(huán)境問題導(dǎo)致的演示失敗。如果現(xiàn)場(chǎng)允許用瀏覽器打開系統(tǒng)live演示效果更好但要確保提前把所有環(huán)境都跑通避免現(xiàn)場(chǎng)連不上數(shù)據(jù)庫。4.3 答辯現(xiàn)場(chǎng)的高頻問題與解答策略答辯時(shí)老師問的問題基本都是圍繞系統(tǒng)本身我根據(jù)自己的答辯經(jīng)驗(yàn)和周圍同學(xué)的經(jīng)歷整理了下面幾個(gè)高頻問題及應(yīng)對(duì)策略問為什么選SpringBoot不用SSM答SpringBoot簡(jiǎn)化了Spring的配置復(fù)雜度內(nèi)嵌服務(wù)器、自動(dòng)配置等特性可以大幅提高開發(fā)效率。從工程實(shí)踐角度目前企業(yè)級(jí)項(xiàng)目使用SpringBoot的比例遠(yuǎn)高于傳統(tǒng)SSM學(xué)習(xí)SpringBoot也更貼近行業(yè)技術(shù)趨勢(shì)。問登錄功能是怎么實(shí)現(xiàn)的密碼安全嗎答登錄采用Session實(shí)現(xiàn)會(huì)話保持密碼使用BCrypt加密存儲(chǔ)登錄校驗(yàn)時(shí)會(huì)進(jìn)行加密密碼的匹配而不是明文比對(duì)。問系統(tǒng)是如何避免SQL注入的答MyBatis框架本身使用了預(yù)編譯機(jī)制#{}占位符會(huì)在發(fā)送SQL前進(jìn)行參數(shù)預(yù)編譯這樣用戶輸入的特殊字符就會(huì)被當(dāng)作普通字符串不能改變SQL語義。問如果用戶量很大頁面的性能如何優(yōu)化答可以從加Redis緩存熱點(diǎn)新聞緩存、數(shù)據(jù)庫索引優(yōu)化、靜態(tài)資源CDN加速幾個(gè)角度回答。最好還能結(jié)合自己常用的場(chǎng)景提出問題然后從上面的角度回答記住這個(gè)是加分項(xiàng)。問什么是事務(wù)在這個(gè)系統(tǒng)里哪里用到了答事務(wù)是一組不可分割的操作。比如在系統(tǒng)中發(fā)布新聞的同時(shí)更新分類下的新聞數(shù)量?jī)蓚€(gè)操作必須同時(shí)成功或同時(shí)失敗這就是事務(wù)的應(yīng)用場(chǎng)景。核心策略答辯前把上述問題背熟結(jié)合自己的系統(tǒng)舉例子不要只背概念。5. 常見問題與排查技巧實(shí)錄5.1 啟動(dòng)報(bào)錯(cuò)排查速查表我把做項(xiàng)目過程中實(shí)際遇到過的高頻報(bào)錯(cuò)整理成了一個(gè)表格方便你對(duì)照排查報(bào)錯(cuò)現(xiàn)象可能原因解決方法java.sql.SQLException: The server time zone valueJDBC連接缺少時(shí)區(qū)參數(shù)url中添加serverTimezoneAsia/ShanghaiFailed to configure a DataSource沒有配置數(shù)據(jù)源或yml配置沒被識(shí)別檢查application.yml中spring.datasource配置啟動(dòng)后訪問頁面顯示W(wǎng)hitelabel Error PageController路徑或者模板路徑錯(cuò)誤檢查Controller和GetMapping注解路徑是否匹配Invalid bound statement (not found)Mapper接口和XML文件沒綁定檢查namespace是否和接口全限定名一致檢查mapper-locations配置Bean named xxx is not foundService或Mapper沒加注解或者缺MapperScanController注入的Service加Service注解啟動(dòng)類加MapperScan(xxx.mapper)上傳圖片后訪問404靜態(tài)資源映射沒配置檢查addResourceHandlers配置是否正確5.2 頁面顯示正常但CSS樣式丟失這個(gè)問題一般出現(xiàn)在部署到Linux服務(wù)器時(shí)。原因基本上是兩個(gè)一是路徑問題。模板頁面中引用的CSS路徑如果是絕對(duì)路徑/css/style.css而且部署時(shí)項(xiàng)目名帶上下文路徑那就會(huì)找不到樣式。最穩(wěn)妥的做法是用Thymeleaf的URL表達(dá)式th:href{/css/style.css}它會(huì)自動(dòng)拼接上下文路徑。二是文件編碼問題。Windows下開發(fā)默認(rèn)使用GBK編碼而Linux下默認(rèn)是UTF-8如果頁面中的中文亂碼了八成是編碼問題。建議所有文件統(tǒng)一使用UTF-8編碼并在application.yml中配置spring: thymeleaf: encoding: UTF-85.3 修改了數(shù)據(jù)庫表結(jié)構(gòu)但代碼報(bào)字段不存在這個(gè)問題的根源是MyBatis的二級(jí)緩存。默認(rèn)情況下MyBatis開啟了本地緩存如果你改了表結(jié)構(gòu)但實(shí)體類沒有同步更新MyBatis會(huì)緩存上一次的映射結(jié)果導(dǎo)致SQL查詢的字段和實(shí)體屬性對(duì)不上。排查思路清掉Maven的target目錄重新mvn clean同時(shí)檢查實(shí)體類字段和數(shù)據(jù)庫字段是否一致另外檢查map-underscore-to-camel-case配置它決定了create_time能否自動(dòng)映射到createTime。我遇到過最奇葩的一個(gè)情況是數(shù)據(jù)庫里加了summary字段實(shí)體類也加了但查詢結(jié)果一直是null。最后排查發(fā)現(xiàn)是XML文件里的resultMap沒有同步加這個(gè)字段的映射。所以如果你的實(shí)體類有字段但查出來為null記得檢查resultMap。5.4 論文查重與降重技巧最后聊一個(gè)非技術(shù)但非常重要的話題論文查重。SpringBoot校園新聞網(wǎng)站的論文網(wǎng)上模板非常多很容易查重率超標(biāo)。我的降重經(jīng)驗(yàn)有三個(gè)一是把技術(shù)介紹部分用自己的話重寫。比如“SpringBoot是由Pivotal團(tuán)隊(duì)提供的全新框架其設(shè)計(jì)目的是用來簡(jiǎn)化Spring應(yīng)用的初始搭建以及開發(fā)過程”改成“SpringBoot是Spring生態(tài)體系的延伸它在Spring框架的基礎(chǔ)上實(shí)現(xiàn)了自動(dòng)化配置讓開發(fā)者能夠以更少的配置完成項(xiàng)目的搭建”。意思一樣但表達(dá)方式變了。二是多用圖表。圖表中的內(nèi)容是不參與查重的把一些流程性、框架性的內(nèi)容用流程圖和架構(gòu)圖表示既能降低查重率又顯得論文更專業(yè)。三是核心代碼部分適當(dāng)精簡(jiǎn)不要整段粘貼大段源碼只保留關(guān)鍵代碼段并用文字說明邏輯一樣能起到解釋作用但有效避免了代碼重復(fù)問題。最后的心里話做完這個(gè)SpringBoot校園新聞網(wǎng)站畢業(yè)設(shè)計(jì)我最大的體會(huì)是畢設(shè)項(xiàng)目不需要多么高深的技術(shù)但一定要是一個(gè)“完整的故事”。從需求分析到數(shù)據(jù)庫設(shè)計(jì)從編碼實(shí)現(xiàn)到測(cè)試部署每一步都能自圓其說答辯時(shí)能講清楚“為什么這么做”這比炫耀技術(shù)棧更有用。SpringBoot校園新聞網(wǎng)站雖然看起來只是簡(jiǎn)單的增刪改查但當(dāng)你認(rèn)真做完每一個(gè)模塊、踩完每一個(gè)坑你會(huì)發(fā)現(xiàn)SpringBoot的自動(dòng)配置原理、MyBatis的映射機(jī)制、MySQL表設(shè)計(jì)的基本原則都在這個(gè)項(xiàng)目里得到了最直觀的驗(yàn)證。如果你也在做這個(gè)項(xiàng)目希望這篇文章能幫你少走一些彎路。遇到具體問題卡住了別硬扛先看日志再查配置最后帶著報(bào)錯(cuò)信息去搜索引擎找答案絕大多數(shù)坑都有人替你踩過了。本文還有配套的精品資源點(diǎn)擊獲取