最近在帮学弟学妹们看毕业设计发现一个挺普遍的现象很多同学选择了SpringBoot Vue这个前后端分离的架构想法很好但实际做起来总是在几个关键地方“卡壳”比如前端调不通后端接口、登录状态老是丢、最后不知道怎么部署到服务器。今天我就结合自己做过的一个项目把从零搭建到部署上线的完整流程梳理一遍希望能帮你避开这些坑高效完成毕设。1. 为什么我们总在“跨域”和“部署”上栽跟头在做毕设初期大家最容易遇到的两个拦路虎就是跨域CORS和部署。跨域问题你的 Vue 项目运行在localhost:8080SpringBoot 后端跑在localhost:8081浏览器出于安全考虑会阻止前端页面访问不同源的接口。于是你会在浏览器控制台看到那个经典的Access-Control-Allow-Origin错误。很多同学一开始就卡在这里不知道是前端问题还是后端问题。接口混乱没有统一的响应格式成功返回{“code”: 200, data: {…}}失败返回{“error”: “xxx”}甚至直接抛出一堆异常栈信息。前端同学处理起来非常痛苦每个接口都要写不同的判断逻辑。部署流程黑盒本地跑得好好的一上传到云服务器就各种 404、500 错误。前端打包后的dist文件夹放哪里Nginx 怎么配置反向代理后端 Jar 包怎么在服务器上持续运行这些问题往往在答辩前夕集中爆发让人手忙脚乱。2. 技术选型为什么是 SpringBoot Vue市面上组合很多比如 SpringBoot Thymeleaf非分离或者 Node.js Vue 全栈。对于毕设来说我依然推荐SpringBoot Vue原因很实在学习成本与市场匹配SpringBoot 是 Java 领域绝对的主流资料多、社区活跃毕业后找工作也实用。Vue 相比于 React 和 Angular上手更平滑模板和语法对新手友好。职责分离结构清晰前端负责页面渲染和用户交互后端专注数据和业务逻辑。这种模式让项目结构一目了然也方便你和队友分工协作。生态成熟SpringBoot 有 Spring Security 做安全MyBatis-Plus 简化数据库操作。Vue 有 Vue Router 管理路由Vuex/Pinia 管理状态Element Plus 提供现成的UI组件。这些都能极大加快你的开发速度。3. 核心实现细节打造健壮的前后端通信桥梁这是项目的骨架搭建好了后面添砖加瓦就轻松了。3.1 后端SpringBoot核心配置第一步统一 API 响应格式这是规范化的第一步。我们定义一个通用的结果类R让所有控制器都返回它。// CommonResult.java Data public class RT implements Serializable { private Integer code; // 状态码如 200成功500失败 private String msg; // 提示信息 private T data; // 返回的数据 public static T RT success(T data) { RT r new R(); r.setCode(200); r.setMsg(操作成功); r.setData(data); return r; } public static T RT error(String msg) { RT r new R(); r.setCode(500); r.setMsg(msg); return r; } // 可以定义更多构造方法如带状态码的success/error }然后在 Controller 里无论成功失败都返回R对象。这样前端就能用一套统一的逻辑处理响应了。第二步解决跨域CORS在 SpringBoot 中配置一个全局的 CORS 过滤器非常简单。// CorsConfig.java Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); // 允许所有来源生产环境应替换为具体前端地址 config.addAllowedOriginPattern(*); // 允许的请求方法 config.addAllowedMethod(*); // 允许的请求头 config.addAllowedHeader(*); // 允许携带凭证如Cookie config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); // 对所有接口路径生效 source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }第三步JWT 登录鉴权使用 JSON Web Token 实现无状态登录。流程是用户登录 - 后端验证并生成Token - 前端保存Token并在后续请求中携带 - 后端拦截器验证Token。引入依赖在pom.xml中添加jjwt相关依赖。编写 JWT 工具类包含生成Token、解析Token、校验Token是否过期等方法。创建登录拦截器这是关键。拦截除了登录接口外的所有请求从请求头中取出Token进行验证。// JwtInterceptor.java Component public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 1. 从请求头中获取 token String token request.getHeader(Authorization); // 2. 判断 token 是否存在或有效这里调用你的JWT工具类进行校验 if (token null || !JwtUtil.verifyToken(token)) { // 3. 无效则返回未授权错误这里使用我们统一的R对象 response.setContentType(application/json;charsetutf-8); response.getWriter().write(JSON.toJSONString(R.error(无效或过期的Token请重新登录))); return false; } // 4. 如果Token有效可以在这里将用户信息如userId存入请求属性供后续使用 String userId JwtUtil.getUserIdFromToken(token); request.setAttribute(userId, userId); return true; } }注册拦截器通过WebMvcConfigurer配置拦截器并设置放行登录、注册等公开接口的路径。3.2 前端Vue核心配置第一步封装 Axios 请求不要在每个页面里直接写axios.get(‘...’)。封装一个统一的请求实例便于管理基础URL、超时时间、请求/响应拦截器。// request.js (通常在 src/utils 目录下) import axios from axios import { ElMessage } from element-plus // 假设使用Element Plus的提示组件 import router from /router // 创建axios实例 const service axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 从环境变量读取基础URL timeout: 10000 // 超时时间 }) // 请求拦截器 service.interceptors.request.use( config { // 在发送请求前做些什么例如统一添加Token const token localStorage.getItem(token) // 从本地存储获取token if (token) { config.headers[Authorization] token // 按后端要求设置请求头字段 } return config }, error { // 对请求错误做些什么 console.error(Request Error:, error) return Promise.reject(error) } ) // 响应拦截器 service.interceptors.response.use( response { // 对响应数据做点什么处理我们统一的R对象 const res response.data if (res.code 200) { return res.data // 直接返回后端给的data数据这样页面中then里拿到就是纯净的数据 } else { // 业务逻辑错误如密码错误提示后端返回的msg ElMessage.error(res.msg || 请求失败) return Promise.reject(new Error(res.msg || Error)) } }, error { // 对响应错误做点什么处理HTTP状态码错误如401, 404, 500 console.error(Response Error:, error.response) if (error.response.status 401) { ElMessage.error(登录已过期请重新登录) localStorage.removeItem(token) router.push(/login) // 跳转到登录页 } else if (error.response.status 500) { ElMessage.error(服务器内部错误) } return Promise.reject(error) } ) export default service然后在你的页面组件中引入这个service进行请求代码会非常简洁。第二步管理登录状态登录成功后将后端返回的Token存储到localStorage或Vuex/Pinia中。并在路由守卫router.beforeEach中检查用户是否已登录来决定是否允许进入需要权限的页面。4. 安全性与性能的几点考量毕设项目虽然规模不大但良好的习惯很重要。密码加密存储千万不要明文存密码使用 Spring Security 的BCryptPasswordEncoder进行加密和匹配。它是加盐的哈希非常安全。Token 刷新机制JWT Token 有过期时间。可以在前端拦截响应时判断如果是401错误且原Token未过期太久则尝试调用刷新Token的接口获取新Token然后重试失败的请求。这能提升用户体验。避免内存泄漏在 Vue 组件中如果你使用了定时器setInterval或绑定了全局事件监听器一定要在组件的beforeUnmount或unmounted生命周期钩子中清除它们。API 接口防护对重要的操作如删除、修改接口除了Token鉴权还可以考虑添加简单的验证码或二次确认防止误操作。5. 生产环境部署避坑指南这是最后一步也是最容易出问题的一步。后端部署使用mvn clean package打包生成可执行的your-project.jar文件。上传到云服务器如 Linux 系统的/app目录。使用nohup java -jar your-project.jar --spring.profiles.activeprod app.log 21 命令在后台运行。--spring.profiles.activeprod会激活application-prod.yml配置文件用于设置生产环境的数据库连接等。更推荐使用systemd或Docker来管理进程保证应用崩溃后能自动重启。前端部署运行npm run build生成dist文件夹。将dist文件夹内的所有文件上传到服务器的某个目录例如/usr/share/nginx/html/your-project。配置 Nginx核心是两件事一是托管前端静态文件二是将 API 请求反向代理到后端 SpringBoot 应用。# nginx.conf 部分配置示例 server { listen 80; server_name your-domain.com; # 你的域名或服务器IP # 前端静态资源 location / { root /usr/share/nginx/html/your-project; # 前端dist文件路径 index index.html index.htm; try_files $uri $uri/ /index.html; # 支持Vue Router的history模式 } # 反向代理后端API location /api/ { # 约定所有以/api开头的请求都代理到后端 proxy_pass http://localhost:8081; # 你的SpringBoot应用地址 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 如果前端和后端不在同一域名下可能还需要在这里设置CORS头 } # 可以添加静态资源缓存等优化配置 location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires 1y; add_header Cache-Control public, immutable; } }修改前端请求的baseURL为/api或你配置的路径这样请求就会发给 Nginx再由 Nginx 转发给后端。日志规范在后端应用中使用Slf4j注解配合 Logback 配置文件将不同级别的日志INFO, ERROR输出到不同的文件并设置日志滚动策略方便日后排查问题。写在最后按照上面的步骤走下来一个结构清晰、具备基本鉴权能力、易于部署的 SpringBoot Vue 前后端分离毕设项目骨架就搭好了。你可以在这个基础上去实现你的具体业务功能比如用户管理、数据增删改查、文件上传等等。这个架构的扩展性也很好。当你完成基础功能后可以思考引入 WebSocket实现实时通知、聊天功能。实现 RBAC 权限模型让不同角色的用户看到不同的菜单和拥有不同的操作权限这会让你的项目在答辩时更有亮点。接入第三方服务比如用阿里云OSS做文件存储用短信服务做注册验证。毕业设计是一个很好的实践机会不要只满足于“跑通”。多思考每一步为什么这么做遇到问题多搜索、多调试。动手把这个项目搭起来你收获的将不仅仅是一个毕业设计更是一套可复用的工程化开发思维。祝你答辩顺利