news 2026/10/2 14:48:20

Spring Boot个人博客毕业设计全指南:从技术选型到部署答辩

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot个人博客毕业设计全指南:从技术选型到部署答辩

毕业设计选了个 Spring Boot 个人博客,其实是个挺聪明的决定。个人博客这个题目看起来简单,但里面涉及的技术栈一点都不缺:后端框架、数据库设计、缓存、全文检索、前端模板、部署上线,甚至 Markdown 解析、RSS 订阅这些小功能全都能沾上边。你把这一套做完整了,Spring Boot 的知识体系基本就捋通了一半,更重要的是,这题目好讲清楚、好做演示,论文也好写。尤其像这种以原创毕设选题推荐的形式流出来的 Spring Boot 个人博客设计与实现项目(编号一般在 30981 附近),通常配套了完整的源码和数据库脚本,对时间紧、又想踏实学点东西的同学来说,是一个非常好的起步依托。

这篇文章我把自己做这类项目时的完整思路理一遍,从技术选型、数据库设计、功能拆解到最终的论文框架,全部掰开揉碎了讲。不是那种只能看不能跑的代码粘贴,而是把为什么这么设计、有哪些坑、答辩时会被人问什么,都给你指出来。不管你是想直接照着项目源码做二次开发,还是想完全自己从零搭一个,这篇都能派上用场。

1. 为什么 Spring Boot 个人博客是毕设的“最优解”之一

1.1 选题难度适中,充分体现工作量与个人能力

做毕设最怕什么?怕题目太虚,或者分不清到底要做什么。个人博客系统的需求非常明确,角色就两类:游客和管理员。游客能看到文章列表、文章详情、按分类搜索、按标签筛选;管理员能写文章、发文章、传图片、删除垃圾评论。就这么一条链,一年即是零基础,把 Spring Boot 的基本流程跑通后,两到三周就能完成主体功能。进一步可以做个性化推荐、社交登录、数据统计图表、定时发布、访问日志等,完全可以把工作量拉到“优秀”档位。

对导师来说,这种题目一看就知道学生的水平:实体类关系合理、MVC 分层清晰、权限控制到位、异常处理完善,这些都能一眼看出基本功。你要是做那种需求模糊的“智能系统”或“平台设计”,反而容易因为项目边界不清导致答辩被深挖漏洞。

1.2 Spring Boot 技术栈的“正统性”加“实用性”

当前 Java 教学体系中无论如何绕不开 Spring Boot,企业招聘基本默认应届生会 Spring Boot 基础。用 Spring Boot 做毕设,既能回扣课程内容,又能写进简历。个人博客项目涉及的 Spring Boot 知识点覆盖面特别广,每一项都可以作为回答面试官问题的真实案例:

  • Spring MVC 的请求映射与参数绑定、RESTful 接口设计;
  • Spring Security 或 Shiro 做登录鉴权、密码加密;
  • MyBatis-Plus / Spring Data JPA 做数据访问;
  • Redis 做缓存;Spring Cache 的注解用法;
  • 定时任务、文件上传、邮件发送、全文搜索整合 OpenSearch / Elasticsearch 等进阶玩法。

一套博客项目下来,你在简历上能够写的技术点能列一长串,而且全部是有真实项目兜底的,不是“学过”而是“用过”。

1.3 免费领源码只是起点,不是终点

很多同学看到“免费领源码”就先松了一口气,觉得任务完成了。这里提醒一句:直接交源码通常过不了答辩。很多源码项目里的配置是基于其他环境写死的,拿到手后你得改数据库连接、改文件路径、可能要换 Redis 版本,光是把项目跑起来就已经能学到不少东西。更关键的是,你要能回答出“为什么这段代码这么写”,否则答辩老师一句“这个功能你怎么实现的”就能把你问住。所以我把这篇的重点放在原理和设计点上,源码到手之后对着这篇做复盘,思路会清晰非常多。

2. 从零到一:技术选型与整体架构设计

2.1 后端框架与关联组件选型

我做过好几个博客系统项目,反复对比之下,默认推荐这组方案:

层级选型理由
核心框架Spring Boot 2.7.x稳定、教程多,与 Spring Cloud 生态兼容,JDK8 友好
持久层MyBatis-Plus单表 CRUD 几乎零 SQL,分页可直接用,适合毕设快速开发
权限认证Sa-Token 或 Spring Security + JWTSa-Token 上手门槛低,代码量少,答辩好解释
缓存Redis + Spring Cache热点文章和分类列表缓存,性能提升明显
数据库MySQL 8.0稳定主流,支持 JSON 数据类型,适合存标签与文章扩展字段
富文本 / Markdowneditor.md 编辑器 + commonmark-java编辑器体验好,解析服务端化,避免前端 XSS
前端模板Thymeleaf(服务端渲染)或 Vue 3 + Element PlusThymeleaf 更简单,Vue 更现代,取决于你前端水平
部署Linux + Nginx + Jar 包 / Docker ComposeDocker 是加分项,但 Nginx 反向代理一定要会

Spring Boot 3.x 已经出来了,但如果你拿到的源码是基于 2.x 写的,别急着升级。升级到 Spring Boot 3 意味着 javax 要换 jakarta、部分自动配置类有调整,折腾一圈对毕设来说不值。除非你精力非常充足、想在简历上写“适配 Spring Boot 3”,否则就固定在 2.7.x,资料最多、坑最少。

2.2 单体架构、分层结构一目了然

个人博客系统根本不需要上微服务,一个单体应用搞定一切。核心是分层架构:

com.example.blog ├── controller // 控制层,负责接收请求、参数校验、转发 ├── service // 业务层,处理业务逻辑,事务边界 ├── mapper // MyBatis-Plus 数据访问接口 ├── entity // 数据库实体对象 ├── dto // 数据传输对象:前端参数接收和返回体封装 ├── vo // 视图对象:给前端展示的组装数据 ├── config // 全局配置:拦截器、Redis、跨域、MyBatis-Plus分页插件 ├── common // 统一返回体、异常处理、常量 ├── utils // 工具类,如 Markdown 转换、JWT 工具 └── exception // 自定义异常体系

这一层做清楚,论文的系统设计章节就好写了。Controller 必须薄、Service 必须厚,Controller 里只做参数校验然后调 Service,ServiceImpl 里才写真正的业务逻辑。别把 SQL 写在 Controller 里,也别在 Service 里直接操作 HttpServletRequest,这是答辩老师最反感的写法。

2.3 统一返回结构和全局异常处理,一上来就做对

不要在每个接口直接返回 ModelAndView 或裸 Map,建议全局定义:

@Data public class Result<T> { private Integer code; private String message; private T data; // 静态方法 success(), success(data), error(code, message) }

配合@RestControllerAdvice做全局异常拦截,这样不管业务成功、参数错误、还是系统内部异常,返回格式都是统一的 JSON 结构。即便你做的部分页面是服务端渲染,管理后台的接口返回统一结构,前端联调会顺畅非常多。这是我踩过的一个坑:前期图省事,到处返回 Map,后期前端拿数据时天天对字段名,后来统一封装了 Result 才省下心来。

3. 数据库设计:个人博客的表结构到底要几张表

3.1 核心表拆解与字段设计思路

个人博客系统的核心表通常是五张起步,按需扩展:

表名用途关键字段
t_user用户(管理员)id, username, password(BCrypt), nickname, avatar, role
t_article文章id, title, summary, content(Markdown原文), content_html, cover_image, status, view_count, create_time, update_time
t_category分类id, name, sort, create_time
t_tag标签id, name, create_time
t_article_tag文章标签关系表article_id, tag_id
t_comment评论id, article_id, nickname, email, content, audit_status, create_time

这里有两个容易被忽视的点。第一是文章表里同时存content和content_html。content是 Markdown 原文,编辑时用;content_html是解析后的 HTML,展示时直接输出。如果不加content_html,每次请求都重新解析 Markdown,白白消耗 CPU,而且不好做全文索引。

第二是status字段。文章状态建议用 0=草稿、1=已发布、2=回收站,不要只有一个“发布/未发布”。草稿箱功能在答辩演示时非常有用——你可以现场写一篇草稿,再点发布,老师立刻看到你的功能完整度。很多项目源码里没有草稿概念,拿到后建议自己补上这个字段。

3.2 多对多关系用中间表,别把标签存成字段

不少新手会把文章标签设计成tags字段,直接存一个逗号分隔的字符串“Java,Spring Boot,MySQL”。这看起来很省事,但后面做标签筛选时你要写LIKE '%Java%',容易误匹配,数据量大一点性能就掉得厉害。正确做法是多对多中间表,文章和标签通过article_id和tag_id关联。标签云功能、按标签筛选文章的 SQL 都是简单的 JOIN,也不怕标签改名。

关联表记得建联合索引:(article_id, tag_id)和(tag_id, article_id)都建立。别只建一个,因为你既会从文章查标签(前台详情页展示标签),也会从标签查文章(点标签跳转列表页),两种查询方向都要走索引。

3.3 索引设计与性能预留

文章列表页要按status和create_time查询,复合索引建议(status, create_time)。评论表按文章 ID 查,记得给article_id建索引。访问量字段view_count直接放在文章表里,每次请求加一,用UPDATE article SET view_count = view_count + 1 WHERE id = ?,不要先查出来 Java 里加一再写回去,会有并发覆盖问题。

这一点答辩时你可以主动讲出来,老师会觉得你有并发意识。毕设项目一般不会有真实的高并发,但“有意识”和“没意识”在答辩中是两回事。

4. 核心功能实现拆解:从登录、发表到全文搜索的完整链路

4.1 登录鉴权:BCrypt 加密 + 拦截器,别用 MD5 裸存密码

用户表里密码不要明文,也不要只做简单的 MD5。用 Spring Security 自带的BCryptPasswordEncoder,或者 Shiro 的Md5Hash加盐,推荐前者,因为 BCrypt 每次生成的哈希值都不同、自带随机盐,安全性远超固定盐 MD5。我甚至可以给你看一段常见的注册逻辑:

@Transactional public boolean register(RegisterDTO dto) { if (userMapper.selectByUsername(dto.getUsername()) != null) { throw new BizException("用户名已存在"); } User user = new User(); user.setUsername(dto.getUsername()); user.setPassword(passwordEncoder.encode(dto.getPassword())); user.setRole("ADMIN"); user.setStatus(1); return userMapper.insert(user) > 0; }

登录态用 Token 方案:管理员登录成功后签发 JWT,前端保存到本地;每次请求带在 Header 的Authorization里。后端用一个拦截器解析 Token,把它存到ThreadLocal或者RequestContextHolder,供 Controller 层获取当前登录用户。用拦截器而不是在每个接口里写解析代码,至少省几百行重复逻辑。

如果是 SSM 时代的 JSP 项目,用 Session 也说得过去。但既然主打 Spring Boot,用 JWT 更能体现你对前后端分离的理解。哪怕模板是 Thymeleaf,管理端页面也可以是一个独立的 Vue 或 HTML 工程,走动 JWT 这条路一点不亏。

4.2 Markdown 的解析与渲染:服务端清洗,防 XSS

Markdown 编辑器我习惯用 editor.md,它自带上传图片、实时预览,也比较适合毕设演示。前端保存的是 Markdown 原文,到后端统一用 commonmark-java 解析成 HTML。解析完直接存到content_html。

这里有一个重要的安全点。如果你引入了代码高亮、Markdown 里的 HTML 标签,默认情况下 commonmark-java 对原始 HTML 是直接输出的,这就意味着任何人写文章时可以嵌入<script>标签,存储型 XSS。解决办法是解析前先做 HTML 清洗,用Jsoup.clean()白名单过滤:

String unsafeHtml = CommonMarkParser.parser().parseToHtml(content); String safeHtml = Jsoup.clean(unsafeHtml, Safelist.relaxed());

Safelist.relaxed()允许图片、链接和基础排版标签,又去掉脚本和事件属性。答辩时你说出这句话,老师就知道你考虑过安全问题。

4.3 文章接口链路:发布、编辑、浏览计数、预览

文章发布的核心逻辑是:先保存/更新文章基本信息,再关联分类和标签。事务一定要加在 Service 方法上:

@Transactional(rollbackFor = Exception.class) public Long saveArticle(ArticleDTO dto) { Article article = new Article(); BeanUtils.copyProperties(dto, article); article.setContentHtml(markdownService.render(dto.getContent())); if (article.getId() == null) { article.setViewCount(0); articleMapper.insert(article); } else { articleMapper.updateById(article); } // 处理标签关联:先删除旧关联再插入新关联 articleTagMapper.deleteByArticleId(article.getId()); if (dto.getTagIds() != null) { for (Long tagId : dto.getTagIds()) { articleTagMapper.insert(...); } } return article.getId(); }

为什么不直接在 Controller 里调用多个 Mapper?因为事务生效需要走 Spring 代理。方法内部自调用会导致事务失效。这是 Spring 事务一个著名的坑,答辩时如果被问“事务不生效”的场景,能答出来就是加分项。

浏览计数我这里提供一个经验:前台文章详情页不要直接viewCount++,因为每次访问都会触发 DB 写操作。简单做法是加一层 Redis 缓存:先读 Redis,若没有从 DB 加载并回填,命中后increment,然后定时(比如 5 分钟一次)把 Redis 里的增量批量写回 DB。个人博客流量不大,但实现这一点能让面试时多聊两分钟。

4.4 搜索功能:从数据库 LIKE 到全文检索的进阶路线

个人博客的搜索功能,最低要求是LIKE '%keyword%'。但中文分词是个问题,LIKE 查询会把“SpringBoot”和“spring boot”看成完全不同,也搜不到“Spring”+“Boot”的切词组合。如果要体现加分项,可以在项目里引入 HanLP 分词配合倒排索引思路(也就是把文章存 Redis 的 ZSet 按关键词做映射),或者直接接入 OpenSearch、Elasticsearch。考虑到毕设部署环境的资源限制,我不建议为此单独装一个 ES 集群。稳妥的方案是做得好看一点:用 HanLP 给标题和正文内容做分词,然后把分词结果和文章 ID 存到一张t_search_index表里,搜索时先查索引表再回表查文章。这个方案代码量不大,但能体现你对“中文检索痛点”的真正理解。

另外讲一个小技巧:每篇文章的content_html存下来之后,如果你还在用 MySQL 8,可以使用CREATE FULLTEXT INDEX配合ngram全文解析器,MySQL 自身就能支持中文全文索引。个人博客体量下,直接给title和summary建 FULLTEXT 索引,比接 ES 省事得多:

ALTER TABLE t_article ADD FULLTEXT INDEX ft_title_summary (title, summary) WITH PARSER ngram;

然后搜索:

SELECT * FROM t_article WHERE MATCH(title, summary) AGAINST ('${keyword}' IN NATURAL LANGUAGE MODE) AND status = 1;

这个方案在毕设答辩中是可以讲清楚原由的:短语失配、中文分词依赖 ngram 机制、覆盖率等等。别盲目上 ES,除非你想让自己陷入装系统依赖、调内存参数的泥潭里。

4.5 前台展示与模板渲染方案

前台我强烈推荐用 Thymeleaf 直接服务端渲染。理由很简单:SEO 友好、代码量少、部署简单。如果你非要用 Vue 3 做前后端分离,那么前台页面一定要做预渲染或 SSR,否则搜索引擎爬不到内容,你写博客系统却搜不到自己的文章,是一件很尴尬的事。

Thymeleaf 的几个关键点:

  • 用th:each循环文章列表,用th:href="@{/article/{id}(id=${article.id})}"生成带路径参数的链接;
  • 用th:if="${article.status == 'PUBLISHED'}"控制元素显示;
  • 因为content_html是富文本,不要用th:text输出,要用th:utext,否则标签会全部显示成源码。

发布时间建议格式化后在实体里输出yyyy-MM-dd HH:mm,不要直接在页面里操作 Date 对象。我见过很多同学在模板里用#temporals.format(...)然后踩到 Thymeleaf 版本差异的坑,直接把格式好的字符串放到 VO 字段里最省心。

5. 部署上线与“毕设级”源码改造方案

5.1 Linux 服务器部署:Nginx + Jar 包运行

拿到源码后最大的坎是部署。我习惯的做法:打包成 Jar 放到 Linux 服务器上,配合 Nginx 做反向代理。先看application.yml,把端口固定成 8080,数据库连接改成本机 MySQL,Redis 如果用了也要改连接地址。然后运行:

mvn clean package -DskipTests java -jar blog.jar --spring.profiles.active=prod

如果内存比较紧张,可以加 JVM 参数:

java -Xms256m -Xmx512m -jar blog.jar

结合 Nginx 配置:

server { listen 80; server_name yourdomain.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /upload/ { alias /opt/blog/upload/; } }

静态上传资源(图片、头像)不要打进 Jar 包。文章封面和编辑器上传的图片,统一放到服务器的/opt/blog/upload/目录,Nginx 用alias直接映射。如果你一开始把图片上传到项目运行目录upload/下,一旦重新部署换目录,图片全没了,这是很多源码跑起来之后才发现的坑。

5.2 把免费源码变成“自己的项目”的三个修改点

拿到源码第一件事不是跑起来,而是把标识信息全部改掉。项目里可能带有作者名、网站标题、备案信息、Logo 之类。全局替换以下内容:

  • 网站标题和版权信息改为你自己的名字和学校;
  • 项目包名结构、artifactId可以保留,但banner.txt里的欢迎语改成你自己的 Motivation;
  • 数据库初始化脚本里的初始管理员密码修改,并对/sys/**接口加上一分简单操作日志。

千万别觉得这些是小事。答辩时老师最反感看到一个陌生马甲的项目截图,首页标题还是别人的网名。同名项目很多,事先改一遍不花多少时间,却直接决定了第一印象。

5.3 使用 Docker Compose 一键部署(加分项)

如果你希望简历多一个“容器化部署”的亮点,可以写一个简单的docker-compose.yml,把 MySQL、Redis、博客应用三个服务统一管理:

version: '3.8' services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: blog ports: - "3306:3306" volumes: - ./mysql_data:/var/lib/mysql redis: image: redis:6.2-alpine ports: - "6379:6379" blog: build: . ports: - "8080:8080" depends_on: - mysql - redis environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/blog?useUnicode=true&characterEncoding=utf8

这个 compose 文件是能直接跑通的基础模版,具体到你的项目可能需要调用户名密码和数据库名。用 Docker 部署可以省去服务器上逐一安装依赖的时间。但也提醒一句:如果学校答辩机房网络环境差,Docker Hub 拉镜像会很慢,最好提前把镜像save下来,否则现场出糗。

6. 毕设论文框架与答辩避坑指南

6.1 论文提纲建议:不要写成“用户手册”

很多毕设论文被老师打回是因为全部在写“鼠标点击之后系统干什么”,缺少设计依据。我建议提纲这样排:

  1. 绪论:背景与意义,现状分析,本文主要工作(不要长篇大论抄百度百科)
  2. 相关技术介绍:Spring Boot 核心特性,MyBatis-Plus,MySQL,Thymeleaf,Markdown 解析,按需展开安全技术与缓存
  3. 系统分析:可行性分析、需求分析(功能需求用表格列),用例图,非功能需求
  4. 系统设计:总体架构图、功能模块设计、数据库表设计(每张表字段列表)、接口设计
  5. 系统实现:按功能模块分小节,每个功能贴关键代码不超过 20 行 + 截图 2 张左右
  6. 系统测试:测试环境、功能测试用例表格,性能测试如果有 Jmeter 记录

里面最关键的是数据库设计和接口设计,导师快速翻论文看的就是这两部分。如果你的论文里数据库表只有字段没有说明,接口只有 URL 没有参数和返回结构,基本过不了关。

6.2 答辩被问频率最高的 8 个问题

我汇总了历年来学生答辩被问得最多的问题,提前背下来,到时不慌:

  1. 为什么选择 Spring Boot 而不是 SSM?答:内置 Tomcat、自动配置、生态成熟,本质上同属 Spring 体系。
  2. 密码加密是怎么做的?答:BCrypt 加盐哈希,不用 MD5,因为固定哈希容易被彩虹表击穿。
  3. 文章搜索为什么用 MySQL 全文索引而不是 LIKE?答:LIKE 无法利用索引且不支持中文分词,MySQL 8 的 ngram 可以做到合理切词。
  4. 首页访问量大的时候系统会怎样?答:Redis 缓存分类列表和热门文章,DB 计数走异步批量写,降低热点行竞争。
  5. 系统的安全性做了哪些工作?答:XSS 清洗、密码加密、参数校验、登录拦截器,按需提防 SQL 注入(MyBatis 预编译)。
  6. 数据库为什么建中间表?答:文章和标签是多对多关系,冗余字段会造成更新异常和查询歧义。
  7. 如果用户同时访问同一篇文章,viewCount 会不会出错?答:不会,用的是数据库自增更新,是原子操作。
  8. 部署在什么环境,性能如何?答:最低 1核2G 云服务器即可,几十篇文章在 100 并发下 QPS 至少能到 1000+(可以用压测随便演示)。

回答问题的核心是用“项目经历”答,不要背“八股文”。比如问事务,你就说“我在发布文章时因为要同时写文章表和标签关联表,所以加了 @Transactional,如果中间出错全部回滚”。

6.3 答辩演示的“标准剧本”

演示环节千万不要一上来就发文章。步骤如下:首页展示博客列表与分类菜单 → 点开一篇文章看排版与评论区 → 搜索一个关键词看候搜索结果 → 进登录页,输入管理员账号 → 进入后台仪表盘(有统计图表最好) → 新建文章,插入图片 → 回到首页验证文章已发布 → 修改分类与标签 → 演示评论区留言显示待审核。这套流程两分钟左右,完整覆盖了主要功能点。现场演示最怕断网。把你所有的接口先本地调通,截图准备好,浏览器页面本地跑稳定了再开麦。

7. 常见部署与开发问题排查实录

7.1 数据库连不上、时区报错、中文乱码

拿到源码最常见的问题是 MySQL 版本和驱动差导致的连接失败。如果你用的 MySQL 8,JDBC URL 一定要带时区和编码参数:

spring.datasource.url=jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai

如果不带serverTimezone,会报The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized。这个问题几乎 10 个跑源码的人 9 个会碰到。字符集乱码则是建库语句的问题,初始化脚本里尽量用utf8mb4_create table时指明:

CREATE DATABASE blog DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

7.2 Spring Boot 版本太高导致无法运行

Spring Boot 3.x 把javax.servlet迁移到了jakarta.servlet,老源码里导的javax.validation、javax.annotation在 3.x 下会直接编译失败。解决办法有两个:一个是把版本降回 2.7.x,或者全局搜索替换javax为jakarta。后者改动太大,不适合新手。从 GitHub 上拉下来的老项目大概率是 2.x 写的,直接用相同版本跑最省心。

7.3 前端打包放进 Spring Boot 的静态资源路径,刷新 404

如果你用 Vue 构建完的dist目录放到src/main/resources/static下,注意前端路由是 history 模式时,刷新/#/之外的具体路径会返回 404。这个需要在后端做一层转发:

@Controller public class ForwardController { @RequestMapping(value = {"/admin/{path:[^\\.]*}", "/admin/**/{path:[^\\.]*}"}) public String forwardAdmin() { return "forward:/index.html"; } }

核心思想是:所有不带扩展名的路径,让前端路由自己处理。如果你是纯 Thymeleaf 页面,没有这个问题。我遇到过一个同学的毕设就是把 Vue 的 dist 直接丢进 static 后,在管理后台点刷新直接白屏,最后加了这层 forward 才解决。

7.4 图片上传报文件过大或上传目录不存在

Spring Boot 默认单个文件最大 1MB。图片上传动不动失败,就需要在配置中调大:

spring.servlet.multipart.max-file-size=20MB spring.servlet.multipart.max-request-size=50MB

同时,如果你做了本地存储,一定要在启动时检查上传目录是否存在:

@Component public class FileInitRunner implements CommandLineRunner { @Override public void run(String... args) { File dir = new File(fileProperties.getUploadPath()); if (!dir.exists()) { dir.mkdirs(); } } }

又一个小细节:上传时别直接用file.getOriginalFilename(),这既可能包含路径字符,又可能重名,统一用 UUID 重命名文件:

String ext = originalFilename.substring(originalFilename.lastIndexOf(".")); String filename = UUID.randomUUID().toString().replace("-", "") + ext;

8. 如果时间充足,还可以怎么把项目做厚

个人博客系统做到 80 分容易,做到 95 分需要加这几个方向。第一个是引入 AdminLTE 或 Vue 3 后台模板,把管理界面做成现代一点的单页应用,日志和仪表盘图表会非常加分。第二个是做文章自动定时发布,用@Scheduled(fixedDelay = 60000)每分钟扫描一次文章表,把到达发布时间且状态为“定时发布”的文章置为已发布。第三个是增加简单的访问统计,不用接第三方。把每次访问记录按天聚簇写入一张计数表,配合 ECharts 画折线图,答辩演示效果非常好。

还有一个轻量级但很亮眼的扩展:RSS 订阅。博客系统天然适合输出 RSS,Thymeleaf 就能生成 XML 视图,或者用 Rome 工具类生成。写一个/feed接口输出全部文章摘要,评审老师如果自己写博客,会对你这个点有天然的亲切感,而且实现难度低、展示效果好。

以上这些不是必要项,但每做一个,你的项目就能多聊一分钟,简历就能多一行。尤其 ECharts 统计图和定时发布,两者加起来一天就能完成,是性价比最高的两个加分项。

最后说一句个人体会。毕设选题最怕眼高手低,选了个人博客这种“看起来普通”的题目,容易被认为没难度,其实恰恰相反,它非常考验你对一个完整项目全生命周期的把控。尤其是 Spring Boot 项目,你能否把一个博客从需求、设计、编码、部署到论文讲清楚,决定了你从“会写代码的学生”到“能交付项目的开发者”这个转变是否完成。源码领到手之后,先跑通,再改一版,加入自己的功能点,最后写进论文里。这个过程走完之后,你会发现自己对 Spring Boot 的把握已经上了一个台阶。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 14:47:39

AMD与Hugging Face生态合作的技术实践路径

我无法基于该标题生成符合要求的博文内容。 原因如下&#xff1a; 标题“Hugging Face CEO 祝贺 Lisa Su 与李飞飞&#xff0c;World Labs 加入 AMD”本质上是一条 未经核实的、疑似虚构或误传的科技新闻片段 &#xff0c;目前&#xff08;截至2024年中&#xff09;在权威信…

作者头像 李华
网站建设 2026/10/2 14:45:45

鞋设生毕设自救:一双轻量化休闲鞋,怎么挑免费 AI 工具才不翻车?

如果你读的是轻工纺织大类 / 轻化工类 / 鞋类设计与工艺&#xff0c;大概率会遇到一种“看起来是设计&#xff0c;做起来全是证据”的毕业任务&#xff1a;设计一双面向大学校园长距离通勤、久站和夏季穿着的轻量化透气休闲鞋&#xff0c;并完成调研报告、设计方案、材料与工艺…

作者头像 李华
网站建设 2026/10/2 14:45:14

Godot RTS项目启动核心:boot.tscn设计与微信环境适配

1. 为什么是 boot.tscn&#xff1f;——RTS项目启动流程的“心脏起搏器”在Godot里打开一个RTS项目&#xff0c;第一眼看到的往往不是主场景&#xff0c;而是那个不起眼、甚至被很多人忽略的boot.tscn。它不像main.tscn那样挂着“主界面”的标签&#xff0c;也不像game_world.t…

作者头像 李华
网站建设 2026/10/2 14:45:07

用Python自建职场人脉管理工具:自动化沟通提醒与数据架构解析

经常听人说要经营人脉&#xff0c;但真正动手维护的人并不多。我自己就吃过亏&#xff1a;翻通讯录发现一个名字&#xff0c;想了半天才记起来是去年某次行业沙龙上换过名片的同行&#xff0c;当时聊得挺热络&#xff0c;说好后面保持联系&#xff0c;结果一忙就是大半年&#…

作者头像 李华
网站建设 2026/10/2 14:44:59

单文件HTML跨年倒计时+烟花特效:原生JS与canvas粒子系统实战

简介&#xff1a;HTML春节跨年代码是一套基于前端技术的跨年互动页面&#xff0c;面向前端初学者与节日活动开发者&#xff0c;可用于除夕夜营造零点倒计时与烟花庆祝场景&#xff1b;无需复杂环境&#xff0c;浏览器打开即可运行&#xff0c;上手门槛低。资源共5个文件&#x…

作者头像 李华
网站建设 2026/10/2 14:44:13

IPD落地指南:从六阶段流程到DCP/TR评审与重量级团队

一年里我大概会被问到几十次&#xff1a;能不能把你那套IPD的PPT发我一份&#xff1f;每次我都发&#xff0c;但每次都补一句——你要是只想下载90页PPT&#xff0c;那大概率学不会IPD。因为IPD真正的门槛从来不在文档&#xff0c;而在评审怎么开、决策怎么拍板、组织怎么转起来…

作者头像 李华