很多Java开发者,尤其是学生和求职者,都有一个共同的困惑:简历上的“项目经验”一栏,除了课程设计,还能写点什么有分量的东西?直接写个“图书管理系统”或“学生选课系统”,在面试官眼里可能已经缺乏新意。但如果你能展示一个功能完整、技术栈主流、并且真正部署上线的个人博客系统,情况就完全不同了。
这个项目之所以成为“毕设简历必备”,不是因为它技术多高深,而是因为它精准地踩中了几个关键点:它用Spring Boot和Vue 3这两个最主流的技术栈,串联了从前端到后端、从数据库设计到部署上线的完整流程,并且最终产出一个“看得见、摸得着”的线上作品。对于面试官而言,这比任何空洞的描述都更有说服力。
本文将手把手带你从零开始,用Spring Boot + Vue 3构建一个功能完整的博客管理系统。我们不止于“跑通代码”,更会深入讲解为什么这样设计、实际开发中会遇到哪些坑,以及如何将这个项目打磨成你简历上的亮点。你将获得一套可直接运行的源码,并理解其背后的工程化思考。
1. 项目核心价值:为什么是个人博客?
在开始敲代码之前,我们需要先想清楚:为什么个人博客项目如此受青睐?它解决的远不止“写文章”这个表面需求。
1.1 技术栈的绝佳练兵场一个博客系统麻雀虽小,五脏俱全。它天然涵盖了Web开发的绝大多数核心场景:
- 后端(Spring Boot):RESTful API设计、用户认证与授权(JWT)、数据库CRUD(MyBatis-Plus/Spring Data JPA)、文件上传、缓存、事务管理、全局异常处理。
- 前端(Vue 3):组件化开发、路由管理(Vue Router)、状态管理(Pinia)、异步请求(Axios)、富文本编辑器集成、响应式布局。
- 前后端交互:清晰的接口契约、跨域问题解决、请求拦截与响应处理。
- 工程化:Maven/Gradle构建、前后端分离部署、简单的CI/CD思路。
通过完成这个项目,你能系统性地实践一套现代Web应用的标准开发流程。
1.2 面试话题的天然素材库这个项目能衍生出无数高质量的面试问题:
- “你的博客如何实现用户登录状态保持?” → 引出JWT vs Session的讨论。
- “文章列表分页是怎么做的?” → 考察数据库分页优化(深度分页问题)。
- “富文本内容如何安全存储和展示?” → 涉及XSS攻击防护。
- “前端是如何调用后端接口的?” → 考察Axios封装、请求拦截器。
- “项目是如何部署的?” → 引出Docker、Nginx反向代理、Linux基础。
当你对项目了如指掌时,面试就变成了分享经验,而不是被动答题。
1.3 从“学习者”到“构建者”的思维转变课程作业通常是实现既定需求。而个人博客项目,你需要自己扮演产品经理和架构师:设计数据库表结构、规划API接口、构思用户体验。这种主动设计和决策的能力,正是初级开发者向中级开发者迈进的关键。
2. 技术选型与核心概念解读
我们的技术栈非常明确:Spring Boot 2.x + Vue 3。这是目前企业级应用和现代前端开发最主流、最稳定的组合之一。
2.1 后端技术栈详解
- Spring Boot:我们的基石。它通过“约定大于配置”的理念,极大地简化了Spring应用的初始搭建和开发过程。我们不需要再被繁琐的XML配置困扰。
- MyBatis-Plus:一款强大的MyBatis增强工具。它提供了通用的Mapper和Service,只需简单配置,即可实现单表CRUD操作,极大提升开发效率。同时,它完全兼容原生MyBatis的功能,复杂SQL依然可以手写。
- Spring Security + JWT:用于解决安全问题。Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。我们将结合JWT(JSON Web Token)实现无状态的API认证。用户登录后,服务器生成一个Token返回给前端,前端后续请求在Header中携带此Token,服务器验证Token有效性即可。
- MySQL:关系型数据库,用于存储用户、文章、分类等结构化数据。
- Maven:项目构建和依赖管理工具。
2.2 前端技术栈详解
- Vue 3 + Composition API:Vue.js的最新主要版本。我们使用
<script setup>语法和Composition API,相比Vue 2的Options API,逻辑组织更灵活,代码复用性更强。 - Vite:下一代前端构建工具。它基于原生ES模块,启动速度极快,热更新迅速,开发体验远超传统的Webpack。
- Vue Router 4:Vue.js的官方路由管理器,用于构建单页面应用(SPA)。
- Pinia:Vue官方推荐的状态管理库,替代了之前的Vuex。它的API更简洁,且完美支持TypeScript。
- Element Plus:基于Vue 3的桌面端组件库。我们将用它快速搭建出美观且交互一致的博客管理后台界面。
- Axios:基于Promise的HTTP客户端,用于向后端发起请求。
2.3 前后端分离架构这是现代Web开发的标准模式。后端仅提供数据接口(API),前端负责页面渲染和用户交互。两者通过HTTP协议(通常是JSON格式)进行通信。这种架构的好处是前后端可以独立开发、测试和部署,职责清晰。
3. 环境准备与项目初始化
在开始编码前,请确保你的开发环境已就绪。
3.1 基础环境准备
- JDK:版本 8 或 11(推荐11)。安装后配置
JAVA_HOME环境变量。 - Node.js:版本 16 或以上。安装后会自带包管理工具
npm。建议使用nvm(Node Version Manager)来管理多个Node版本。 - MySQL:版本 5.7 或 8.0。安装并启动服务,记住root密码。
- IDE:
- 后端:IntelliJ IDEA(社区版或旗舰版)或 Eclipse(需安装Spring插件)。
- 前端:Visual Studio Code(轻量高效)或 WebStorm。
- Maven:IDEA通常内置,也可单独安装。
- 浏览器:Chrome 或 Edge(用于调试前端)。
3.2 创建后端Spring Boot项目使用Spring Initializr( start.spring.io )或IDEA内置的Spring Initializr创建项目。
- Project: Maven
- Language: Java
- Spring Boot: 选择2.7.x或3.x(本文以2.7.x为例,3.x需注意部分依赖变化)
- Project Metadata:
- Group:
com.yourname - Artifact:
blog-backend
- Group:
- Dependencies: 添加以下依赖:
- Spring Web
- MyBatis Framework
- MySQL Driver
- Lombok(简化POJO类代码)
生成项目后,用IDEA打开。
3.3 创建前端Vue 3项目打开终端(命令行),执行以下命令:
# 使用Vite官方模板创建项目 npm create vue@latest blog-frontend # 根据提示进行选择: # ✔ Add TypeScript? ... No (根据喜好选择,本文用JavaScript) # ✔ Add JSX Support? ... No # ✔ Add Vue Router for Single Page Application development? ... Yes # ✔ Add Pinia for state management? ... Yes # ✔ Add Vitest for Unit Testing? ... No # ✔ Add an End-to-End Testing Solution? » No # ✔ Add ESLint for code quality? ... Yes # 进入项目目录并安装依赖 cd blog-frontend npm install # 安装额外需要的依赖库 npm install axios element-plus @element-plus/icons-vue # 如果网络慢,可以使用淘宝镜像:npm config set registry https://registry.npmmirror.com至此,前后端两个空项目骨架已经创建完成。
4. 后端核心功能实现
我们将后端功能模块化,逐步实现。
4.1 数据库设计与建表在MySQL中创建数据库blog_db,并执行以下SQL创建核心表:
-- 用户表 CREATE TABLE `sys_user` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', `username` varchar(64) NOT NULL COMMENT '用户名', `password` varchar(128) NOT NULL COMMENT '密码(加密后)', `avatar` varchar(512) DEFAULT NULL COMMENT '头像链接', `email` varchar(128) DEFAULT NULL COMMENT '邮箱', `status` tinyint NOT NULL DEFAULT '1' COMMENT '状态(0-禁用,1-正常)', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; -- 文章表 CREATE TABLE `blog_article` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', `user_id` bigint NOT NULL COMMENT '作者ID', `category_id` bigint DEFAULT NULL COMMENT '分类ID', `title` varchar(256) NOT NULL COMMENT '文章标题', `cover_image` varchar(512) DEFAULT NULL COMMENT '封面图', `content` longtext NOT NULL COMMENT '文章内容(HTML格式)', `summary` varchar(512) DEFAULT NULL COMMENT '文章摘要', `view_count` int DEFAULT '0' COMMENT '阅读量', `is_top` tinyint DEFAULT '0' COMMENT '是否置顶(0-否,1-是)', `status` tinyint NOT NULL DEFAULT '1' COMMENT '状态(0-草稿,1-发布)', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`), KEY `idx_category_id` (`category_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文章表'; -- 分类表 CREATE TABLE `blog_category` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(64) NOT NULL COMMENT '分类名称', `description` varchar(256) DEFAULT NULL COMMENT '分类描述', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文章分类表';4.2 集成MyBatis-Plus与配置
- 在
pom.xml中添加MyBatis-Plus依赖:
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3</version> </dependency>- 配置
application.yml(或application.properties):
server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/blog_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: your_password # 替换为你的数据库密码 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台打印SQL,生产环境关闭 global-config: db-config: logic-delete-field: deleted # 全局逻辑删除字段名(如果表中有此字段) logic-delete-value: 1 # 逻辑已删除值 logic-not-delete-value: 0 # 逻辑未删除值4.3 实体类、Mapper与Service以User实体为例,展示MyBatis-Plus的便捷用法。
- 实体类 (
User.java):
// 文件路径:src/main/java/com/yourname/blogbackend/entity/User.java package com.yourname.blogbackend.entity; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import java.time.LocalDateTime; @Data @TableName("sys_user") // 指定表名 public class User { @TableId(type = IdType.AUTO) // 主键自增 private Long id; private String username; private String password; private String avatar; private String email; private Integer status; @TableField(fill = FieldFill.INSERT) // 插入时自动填充 private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) // 插入和更新时自动填充 private LocalDateTime updateTime; }- Mapper接口 (
UserMapper.java):
// 文件路径:src/main/java/com/yourname/blogbackend/mapper/UserMapper.java package com.yourname.blogbackend.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.yourname.blogbackend.entity.User; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserMapper extends BaseMapper<User> { // 继承BaseMapper后,基础的CRUD方法已自动拥有,无需编写XML }- Service接口与实现 (
IUserService.java&UserServiceImpl.java):
// 文件路径:src/main/java/com/yourname/blogbackend/service/IUserService.java package com.yourname.blogbackend.service; import com.baomidou.mybatisplus.extension.service.IService; import com.yourname.blogbackend.entity.User; public interface IUserService extends IService<User> { // 可以在此定义复杂的业务方法 User getUserByUsername(String username); }// 文件路径:src/main/java/com/yourname/blogbackend/service/impl/UserServiceImpl.java package com.yourname.blogbackend.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yourname.blogbackend.entity.User; import com.yourname.blogbackend.mapper.UserMapper; import com.yourname.blogbackend.service.IUserService; import org.springframework.stereotype.Service; @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService { @Override public User getUserByUsername(String username) { // 使用MyBatis-Plus的QueryWrapper构建查询条件 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("username", username); return this.getOne(queryWrapper); } }4.4 实现JWT认证与授权
- 添加JWT依赖(如
jjwt)到pom.xml。 - 创建
JwtUtil工具类,用于生成和解析Token。 - 创建
LoginController处理登录请求,验证用户名密码后生成JWT返回。 - 创建
JwtAuthenticationTokenFilter过滤器,在请求到达Controller前,从Header中解析Token并设置用户身份信息到SecurityContext。 - 配置
Spring Security,放行登录接口和静态资源,保护其他API。
4.5 实现文章管理API创建ArticleController,提供标准的RESTful接口:
GET /api/articles:分页获取文章列表。GET /api/articles/{id}:根据ID获取文章详情。POST /api/articles:创建新文章(需要登录)。PUT /api/articles/{id}:更新文章(需要登录且为作者本人)。DELETE /api/articles/{id}:删除文章(需要登录且为作者本人或管理员)。
关键点:分页查询使用MyBatis-Plus的Page对象;创建和更新时,需要从SecurityContext中获取当前登录用户的ID作为user_id。
5. 前端核心功能实现
前端我们将构建一个包含后台管理界面和博客展示界面的SPA。
5.1 项目结构初始化与配置
- 在
src目录下创建清晰的模块化结构:src/ ├── api/ # 所有axios请求封装 ├── assets/ # 静态资源 ├── components/# 公共组件 ├── router/ # 路由配置 ├── stores/ # Pinia状态管理 ├── utils/ # 工具函数 └── views/ # 页面组件 - 配置
main.js,引入Element Plus和图标库:
// 文件路径:src/main.js import { createApp } from 'vue' import App from './App.vue' import router from './router' import { createPinia } from 'pinia' // 引入Element Plus import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import * as ElementPlusIconsVue from '@element-plus/icons-vue' const app = createApp(App) // 注册所有图标 for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component) } app.use(createPinia()) app.use(router) app.use(ElementPlus) app.mount('#app')5.2 封装Axios与API模块在src/utils/request.js中创建axios实例,并配置请求/响应拦截器,用于自动添加JWT Token、处理通用错误等。
// 文件路径:src/utils/request.js import axios from 'axios' import { ElMessage } from 'element-plus' import router from '@/router' const service = axios.create({ baseURL: 'http://localhost:8080/api', // 后端API基础地址 timeout: 10000 }) // 请求拦截器 service.interceptors.request.use( config => { // 从localStorage中获取token const token = localStorage.getItem('blog_token') if (token) { config.headers['Authorization'] = `Bearer ${token}` } return config }, error => { return Promise.reject(error) } ) // 响应拦截器 service.interceptors.response.use( response => { const res = response.data // 假设后端统一返回格式为 { code: 200, data: ..., message: 'success' } if (res.code !== 200) { ElMessage.error(res.message || 'Error') // 如果是401未授权,跳转到登录页 if (res.code === 401) { localStorage.removeItem('blog_token') router.push('/login') } return Promise.reject(new Error(res.message || 'Error')) } else { return res.data // 直接返回data字段 } }, error => { ElMessage.error(error.message || 'Request Error') return Promise.reject(error) } ) export default service在src/api目录下创建模块化的API文件,如article.js:
// 文件路径:src/api/article.js import request from '@/utils/request' export function getArticleList(params) { return request({ url: '/articles', method: 'get', params // params 包含 pageNum, pageSize, categoryId 等 }) } export function createArticle(data) { return request({ url: '/articles', method: 'post', data }) } // ... 其他增删改查接口5.3 实现登录与权限管理
- 创建登录页面 (
Login.vue),调用登录API,成功后保存Token至localStorage并跳转到后台首页。 - 在路由守卫 (
router/index.js的beforeEach钩子) 中检查访问权限,保护需要登录的路由。 - 使用Pinia (
src/stores/user.js) 全局管理用户登录状态和基本信息。
5.4 构建后台管理界面使用Element Plus的布局组件 (el-container,el-header,el-aside,el-main) 搭建经典的后台管理布局。
- 侧边栏菜单:使用
el-menu组件,根据路由动态生成。 - 文章管理页:
- 表格展示:使用
el-table展示文章列表,包含标题、分类、状态、发布时间等列。 - 分页组件:使用
el-pagination,并与后端分页API联动。 - 操作按钮:编辑、删除、发布/下架。
- 搜索与筛选:表单区域,可按标题、分类、状态筛选。
- 表格展示:使用
- 文章编辑页:
- 集成富文本编辑器:推荐使用
@wangeditor/editor-for-vue(轻量) 或tinymce-vue(功能强大)。 - 表单验证:使用
el-form配合async-validator。
- 集成富文本编辑器:推荐使用
5.5 构建博客前台展示页创建一个新的路由和视图,用于对外展示博客。
- 首页 (
HomeView.vue):展示文章列表、分类导航、热门文章等。 - 文章详情页 (
ArticleDetail.vue):根据路由参数id请求文章详情并渲染。 - 布局:可以设计得更简洁美观,与后台管理风格区分开。
6. 前后端联调与运行
6.1 解决跨域问题前端运行在localhost:5173(Vite默认端口),后端在localhost:8080,浏览器会因同源策略阻止请求。在后端添加一个全局CORS配置即可解决:
// 文件路径:src/main/java/com/yourname/blogbackend/config/CorsConfig.java package com.yourname.blogbackend.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.@WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 对所有接口 .allowedOriginPatterns("*") // 允许所有来源,生产环境应指定具体域名 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }6.2 启动与验证
- 启动后端:在IDEA中运行
BlogBackendApplication的main方法,控制台看到Spring Boot启动日志,无报错。 - 启动前端:在
blog-frontend目录下执行npm run dev。终端会输出本地访问地址,通常是http://localhost:5173。 - 功能验证:
- 打开前端页面,尝试登录(需先在数据库
sys_user表手动插入一条用户记录,密码需为BCrypt加密后的字符串)。 - 登录成功后,进入后台,尝试创建分类、撰写并发布文章。
- 访问博客前台首页,查看发布的文章是否正常显示。
- 打开前端页面,尝试登录(需先在数据库
7. 常见问题与排查思路
在开发过程中,你几乎一定会遇到下面这些问题。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
前端页面空白,控制台报错Failed to load resource: net::ERR_CONNECTION_REFUSED | 后端服务未启动,或端口不对。 | 1. 检查后端控制台是否成功启动。 2. 在浏览器直接访问 http://localhost:8080/api/test(假设有个测试接口)。 | 确保后端服务在指定端口正常运行。 |
前端请求接口返回404 | 1. 后端接口路径写错。 2. 后端Controller未添加 @RestController或@RequestMapping。 | 1. 核对前端请求URL和后端接口定义。 2. 在后端IDE中使用“Find in Path”搜索接口路径。 | 修正URL或后端注解。使用Swagger或Knife4j生成API文档有助于核对。 |
登录成功,但后续请求返回401 (Unauthorized) | 1. 前端未正确携带Token。 2. Token已过期。 3. 后端JWT解析失败。 | 1. 浏览器开发者工具Network面板,查看请求Header中是否有Authorization。2. 检查后端JWT密钥、过期时间配置。 3. 查看后端日志是否有解析异常。 | 1. 检查axios拦截器逻辑。 2. 延长JWT过期时间或实现Token刷新机制。 3. 确保前后端使用的JWT密钥一致。 |
| 插入中文到MySQL出现乱码 | 数据库、表或连接字符串字符集不是utf8mb4。 | 1. 检查数据库CREATE DATABASE语句。2. 检查表 CREATE TABLE语句。3. 检查JDBC连接URL参数。 | 确保数据库、表字符集为utf8mb4,连接URL添加characterEncoding=utf-8。 |
| MyBatis-Plus查询不到数据 | 1. 实体类字段名与数据库列名未正确映射。 2. 逻辑删除字段导致查询自动附加条件。 | 1. 使用@TableField注解指定映射。2. 检查实体类是否有 deleted字段,并查看全局配置。 | 1. 开启SQL日志 (mybatis-plus.configuration.log-impl),查看实际执行的SQL。2. 在查询时使用 .eq(“deleted”, 0)覆盖全局逻辑删除条件。 |
| Element Plus组件样式未生效 | 1. 未正确引入CSS文件。 2. Vue版本与Element Plus版本不兼容。 | 1. 检查main.js中是否import 'element-plus/dist/index.css'。2. 查看控制台是否有相关警告。 | 1. 确保CSS引入语句在createApp之后,app.mount()之前。2. 查阅Element Plus官网的安装指南,核对版本。 |
8. 项目优化与进阶建议
完成基础功能后,你可以从以下几个方向深化项目,这会让你的项目在简历中更加出彩。
8.1 安全性加固
- 密码加密:务必使用
BCryptPasswordEncoder等强哈希算法存储密码,切勿明文存储。 - SQL注入防护:坚持使用MyBatis-Plus的QueryWrapper或MyBatis的
#{}预编译,杜绝字符串拼接SQL。 - XSS防护:对富文本内容,入库前进行白名单过滤(如使用Jsoup库),输出时进行转义。
- 接口限流与防刷:对登录、评论等接口添加限流(如使用Guava RateLimiter或Spring Boot Actuator)。
- 敏感信息脱敏:在日志或返回前端的用户信息中,对手机号、邮箱等进行脱敏处理。
8.2 性能与体验优化
- 后端缓存:对不常变动的数据(如分类列表、热门文章)使用Redis或Caffeine进行缓存。
- 数据库索引优化:为
article表的user_id,category_id,create_time等查询条件字段添加索引。 - 前端路由懒加载:在Vue Router配置中使用
() => import(‘…’)语法,拆分代码包,提升首屏加载速度。 - 图片上传与CDN:将用户上传的图片存储到OSS(对象存储服务,如阿里云OSS、七牛云),并返回CDN链接,减轻服务器压力。
- 文章列表分页优化:避免使用
limit offset, size进行深度分页,可改用基于id的条件查询。
8.3 功能扩展
- 文章标签系统:实现多对多关系,让一篇文章拥有多个标签。
- 文章评论与回复:设计评论表,支持楼中楼回复。
- 全文搜索:集成Elasticsearch,为文章标题和内容提供高效的全文检索功能。
- 数据统计仪表盘:在后台首页展示文章数、用户数、访问趋势等图表(可集成ECharts)。
- SEO优化:为博客前台页面生成静态化或服务端渲染(SSR),添加合理的
meta标签,利于搜索引擎收录。
8.4 部署上线
- 后端打包:使用
mvn clean package生成可执行的JAR文件。 - 前端构建:运行
npm run build生成静态文件到dist目录。 - 服务器准备:购买一台云服务器(如阿里云ECS),安装JDK、MySQL、Nginx。
- 部署流程:
- 将后端JAR文件上传至服务器,使用
nohup java -jar blog-backend.jar &后台运行。 - 将前端
dist目录下的文件上传至服务器,配置Nginx将请求代理到后端API,并托管前端静态资源。 - 为域名配置SSL证书,启用HTTPS。
- 将后端JAR文件上传至服务器,使用
完成以上步骤,你的个人博客就不再是本地玩具,而是一个真正的线上项目。在简历中附上项目地址,其说服力将成倍增加。
这个博客项目是一个起点,而非终点。它的价值在于为你提供了一个完整的、可扩展的现代Web应用实践范本。通过它,你不仅学会了Spring Boot和Vue 3的语法,更理解了如何将多个技术组件有机地组合在一起,去解决一个真实的业务问题。
接下来,你可以根据“优化与进阶建议”部分,选择一两个方向深入实践。例如,尝试集成Redis缓存,或者为博客添加一个简单的评论功能。每解决一个实际问题,你对整个技术体系的理解就会加深一层。当你再去学习微服务、分布式、高并发等更高级的主题时,你会发现自己有了更扎实的根基和更明确的目标。