
简介一份基于Spring Boot与Vue框架的智能家居系统完整设计与实现源码围绕用户信息、图片素材、视频素材等管理模块采用Java、SpringBoot、Vue、Ajax、Maven、MySQL、MyBatisPlus等技术栈适合Java开发者、计算机专业学生及毕设选题人群作为学习参考或二次开发起点。压缩包共收录368个文件包含77个Java后端源文件、46个Vue前端组件、161个SVG图标资源并配套JavaScript脚本、CSS样式、XML配置、数据库访问及相关构建运行脚本压缩后仅15.22MB目录层次完整从系统分析、数据库设计到功能实现均有清晰划分。目前已有239人学习浏览整体项目体量适中非常适合作为毕业设计或课程设计模拟项目。压缩包中的必读推荐文档、一键安装/启动批处理、演示视频和音频素材能帮助使用者快速搭建环境、查看界面效果并理解前后端交互流程。此外源码注释与结构便于定位核心模块可在此基础上增加智能控制、设备联动等功能极大节约从零开发成本。1. 基于 Spring Boot 的智能家居系统毕设级前后端项目直接跑起来才是真的手里拿到这套基于 Spring Boot 的智能家居系统时我的第一个动作不是去翻摘要里的论文目录而是去看 install.bat、build.bat、run.bat 这三个脚本。原因很简单这种毕设级管理系统源码价值高低完全取决于能不能在本地跑起来。如果环境搭不通后面所有 Java 代码和 Vue 页面都等于黑匣子。这套项目的技术栈是 Java Spring Boot Vue Ajax Maven MySQL MyBatisPlus前端是 Vue CLI 打包后嵌进 Spring Boot 静态目录的所以不需要单独启动 Node 服务后端一起来登录页就能访问。它解决的是智能家居场景里的后台管理需求——用户信息维护、图片素材管理、视频素材管理说白了就是一个典型的 CRUD 系统加上文件上传展示。适合三类人做 Spring Boot 毕业设计的学生、想快速复现一个完整前后端项目的初级 Java 开发以及需要给客户演示管理后台的工程师。接下来我按自己拆项目时的顺序把技术栈、运行过程、联调逻辑和常见坑都过一遍照着走基本能复现。2. 项目技术栈拆解Spring Boot Vue MyBatisPlus 为什么是毕设的稳妥组合2.1 后端分层与依赖选型Controller-Service-Mapper 四层结构这个项目的后端不是重业务的重型系统而是典型的后台管理单体应用。打开 pom.xml映入眼帘的应该是 spring-boot-starter-web、mybatis-plus-boot-starter、mysql-connector-java、lombok 这些基础依赖。MyBatisPlus 在这个技术栈里承担的是持久层框架职责它的 BaseMapper 直接为每个实体提供增删改查方法不需要像原生 MyBatis 那样手写很多 XML。比如对用户表操作只要接口继承 BaseMapper IService 和 ServiceImpl 就能把业务层也省下一大截样板代码。常见做法是在 config 包下加一个 MybatisPlusConfig 配置类把分页插件注册进去否则后期做分页列表时会踩坑。下面这段配置是这个项目里非常关键的一段Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); PaginationInnerInterceptor pagination new PaginationInnerInterceptor(DbType.MYSQL); pagination.setMaxLimit(100L); interceptor.addInnerInterceptor(pagination); return interceptor; } }这段代码的逻辑是向 MyBatisPlus 容器中注册一个拦截器 BeanPaginationInnerInterceptor 专门处理分页 SQL 拼接。DbType.MYSQL 告诉它方言是 MySQLsetMaxLimit(100L) 表示单页最大 100 条这是防护性设置防止有人传入超大页码把数据库打崩。很多复现者遇到的“分页查询 total 一直为 0”问题根源就是缺少这个配置类。实体类与数据库表的映射也要提前确认。MyBatisPlus 默认开启驼峰转下划线所以实体里的 createTime 会自动映射到表字段 create_time。如果表名字段名不规范需要用 TableName 和 TableField 显式指定。这里给一个用户实体的写法Data TableName(user) public class User { TableId(type IdType.AUTO) private Long id; private String username; private String password; private String role; private Integer status; private LocalDateTime createTime; }Data 是 Lombok 提供的注解自动生成 getter/setter少写很多冗余代码。TableName(user) 把实体类和数据库表绑定TableId(type IdType.AUTO) 表示主键采用数据库自增策略。这样写之后Mapper 接口里一个方法都不用定义直接调用 selectById、insert、updateById 即可完成基础 CRUD。对于毕设演示来说这个分层已经够用而且面试时也能讲清每一层职责。2.2 前端 Vue ElementUI Ajax为什么后台管理用这种组合最省力前端部分的打包产物里有 app.377831ff.css、chunk-vendors.1f0a25b2.css 和 index.html这是 Vue CLI 构建后的典型特征。chunk-vendors 是第三方库打包后的文件名带 hash 是为了缓存更新。这个项目没有独立的前端服务而是把 npm run build 生成的 dist 目录内容直接放进了 Spring Boot 的 src/main/resources/static 下后端启动后访问 http://localhost:8080/ 就能看到登录页。为什么这种组合在毕设里最省力因为它把页面开发、接口联调、部署三件事分开互相又不拆家。Vue 负责页面ElementUI 负责表格、表单、弹窗这些组件Ajax 负责与后端通信。你不需要为前端单独配置 Nginx 或 CORS因为前后端同源省去跨域问题。这种 B/S 架构下浏览器只负责发请求和渲染所有业务判断都落在后端接口里答辩时也容易讲清楚。前端调用后端接口的常见姿势是使用 jQuery Ajax 或 axios下面这段代码演示了登录请求$.ajax({ url: /api/login, method: POST, contentType: application/json, data: JSON.stringify({ username: admin, password: 123456 }), success: function (res) { if (res.code 200) { localStorage.setItem(token, res.data.token); window.location.href /index.html; } else { alert(res.msg); } } });这段请求的逻辑是向 Spring Boot 的 /api/login 接口发送 JSON 数据后端返回统一结果对象 Result里面包含 code、msg、data 三个字段。前端根据 code 判断是否登录成功成功就把 token 存进 localStorage然后跳转到管理首页。注意这里的 url 必须以 /api 开头这是后端 Controller 类上的 RequestMapping 前缀如果项目配置了 server.servlet.context-path这个前缀还要再叠加否则会 404。ElementUI 在页面里主要用来渲染表格和表单比如用户管理页的 el-table 绑定列表数据el-dialog 弹窗承载新增编辑表单。这些组件本身不需要额外学习看官方文档就能上手。重点要理解的数据流向是Vue 的 methods 里调用 Ajax 获取数据成功后把响应赋值给 data 中的数组表格通过 :data 绑定这个数组。这个模式理解了整个系统的页面代码都能看懂。2.3 数据库设计用户信息、图片素材、视频素材三张核心表系统的业务模块集中在用户信息管理、图片素材管理、视频素材管理对应数据库里应该有三张核心表。用户表负责登录认证和角色区分素材表负责记录文件路径和归属人。智能家居项目里的图片素材一般是产品图、场景效果图视频素材是演示视频或操作指引。我按常见做法给出一套便于复现的表结构字段命名与 MyBatisPlus 的驼峰映射规则保持一致表名字段类型说明useridbigint主键自增userusernamevarchar(50)登录名唯一userpasswordvarchar(100)加密后的密码userrolevarchar(20)管理员/普通用户imageidbigint主键imagetitlevarchar(100)图片名称imageurlvarchar(255)图片访问路径imageuser_idbigint上传人videoidbigint主键videotitlevarchar(100)视频名称videourlvarchar(255)视频访问路径videocovervarchar(255)封面图路径videouser_idbigint上传人建表语句要注意 MySQL 的版本差异。5.7 支持 utf8mb4 正常8.0 的驱动类要用 com.mysql.cj.jdbc.Driver同时 url 里必须带 serverTimezone。用户表建议用反引号包起来因为 user 在某些 MySQL 版本里属于系统库关键字容易引起歧义。素材表里存的是文件相对路径不是二进制内容这样数据库体积小文件系统也好管理。下面这段建表 SQL 可以直接在 Navicat 或命令行执行CREATE TABLE user ( id bigint(20) NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL, password varchar(100) NOT NULL, role varchar(20) DEFAULT ADMIN, status tinyint(4) DEFAULT 1, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户信息表; CREATE TABLE image ( id bigint(20) NOT NULL AUTO_INCREMENT, title varchar(100) DEFAULT NULL, url varchar(255) NOT NULL, user_id bigint(20) DEFAULT NULL, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT图片素材表;建表之后还需要准备一条初始管理员账号否则登录页进不去。常见做法是在启动前执行一条 INSERT或者在 data.sql 里通过 SQL 初始化。考虑到 Spring Boot 的 JPA 和 MyBatisPlus 默认不会自动建表手动执行 SQL 是最稳妥的。把这条数据插入后用户信息管理模块的列表查询、编辑、删除才有操作对象图片和视频素材模块也能通过 user_id 关联到上传人。理解了这三张表的关系整个系统的数据流基本就清楚了登录校验走 user素材列表查 image/video上传成功后记录路径到对应表的 url 字段。3. 本地跑通三步曲install.bat、build.bat、run.bat 背后到底做了什么3.1 环境准备JDK、Maven、MySQL 与 IDE 的版本核对我在复现这个项目时第一个卡点不是代码而是环境版本。Spring Boot 2.x 通常要求 JDK 8 以上3.x 必须用 JDK 17。这套系统既然采用了 jQuery Ajax 和 Vue CLI 打包嵌入方式大概率是 Spring Boot 2.x建议直接装 JDK 8兼容性最不容易出问题。Maven 用 3.6 以上IDEA 2020 以后都能正常识别。MySQL 建议 5.7 或 8.0但注意 8.0 的驱动类名和时区配置与 5.7 不同后面我会展开说。环境检查可以在命令行执行 java -version、mvn -v、mysql --version 三条命令输出信息确认无误后再往下走。很多学生卡在“启动后页面打不开”回头排查才发现是 JDK 配了多个版本IDEA 用的还是老的 jre。这里有一个经验IDEA 里 File - Project Structure - Project SDK 要明确选到 JDK 8同时 Settings - Maven - Runner 里的 JRE 也要选一致否则 Maven 编译时用的可能是默认 JDK。如果你本机同时装了 MySQL 5.7 和 8.0我建议把不用的实例从系统服务里停掉只保留一个省得端口和驱动都乱。数据库初始化时把项目里的 sql 文件导入到库中可以用 Navicat 或 DBeaver 执行脚本。解压项目后第一时间打开里面的必读推荐.docx那里面通常会写清楚数据库脚本位置和初始账号比看代码猜配置快得多。3.2 一键脚本拆解与手动执行命令对照项目里给了三个 bat 脚本从命名看它们是有执行顺序的1-install.bat、3-build.bat、2-run.bat。这里的数字不是乱标的而是告诉你先装依赖、再构建前端、最后跑后端。我建议第一次复现不要直接双击而是打开命令行逐条执行便于看到报错信息。先看 install.bat 的内容大概是下面这样echo off echo Start install... call mvn clean install -DskipTests cd frontend call npm install --registryhttps://registry.npmmirror.com call npm run build cd .. echo Install finished.逻辑很直白它先让 Maven 编译后端并跳过测试再进入 frontend 目录执行 npm install 和 npm run build。-DskipTests 表示跳过单元测试节省构建时间--registry 参数给 npm 指定镜像源国内网络环境下比官方源快很多。build 完成后会在 frontend/dist 下生成 index.html 和一堆 css/js 文件。如果项目的 pom.xml 配置了前端资源复制插件这些产物会自动拷到 Spring Boot 的 static如果没有你需要手动把 dist 内文件复制过去。接下来是 run.bat它的作用是启动后端服务。最简单的情况是执行 mvn spring-boot:run如果你已经用 mvn clean install 打过包也可以直接跑 java -jar target/xxx.jar。注意 jar 包文件名应该和 pom.xml 里的 artifactId 一致。我一般不建议直接双击 run.bat因为一旦启动失败窗口会秒关日志根本来不及看。正确姿势是在项目根目录打开命令行手动执行 mvn spring-boot:run这样控制台会留驻能看到完整的异常堆栈。手动执行命令对照表里还有一步是启动前确认静态资源位置打开 target/classes/static 或 src/main/resources/static确认里面存在 index.html。如果不存在说明前端产物没有复制成功回去重新构建。3.3 配置文件修改application.yml 里必改的三个参数后端服务是否能连通数据库完全取决于 application.yml 或 application.properties 里的配置。这个项目用的是 yml 格式结构比 properties 清晰。我举一个典型的配置示例server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/smart_home?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath*:mapper/*.xml type-aliases-package: com.smarthome.entity configuration: map-underscore-to-camel-case: true upload: dir: D:/smart_home/upload必改参数有三个第一个是 url 里的数据库名 smart_home必须和实际建的库名一致第二个是 username 和 password改成你自己的 MySQL 账号第三个是 upload.dir这是文件上传的本地保存路径Windows 下要保证目录存在否则 Spring Boot 启动不报错但上传图片时 transferTo 会抛 FileNotFoundException。serverTimezone 建议保留 Asia/Shanghai否则日期字段查询会差 8 小时。driver-class-name 在 MySQL 8.0 下必须用 com.mysql.cj.jdbc.Driver老版的 com.mysql.jdbc.Driver 只适用于 5.7 及以下这一点经常引发启动时的加载异常。配置文件改完后最好先单独验证数据库连接在本机用 Navicat 或命令行连接 MySQL执行 show tables; 能看到刚才建的三张表再启动后端。这一步能避免把数据库连接失败误判成代码问题。启动成功后控制台会打印 Spring Boot 的 banner 和 Tomcat started on port(s): 8080看到这行就说明后端起来了。3.4 后端启动后的验证清单后端启动不等于系统能用至少要做三件事验证。第一浏览器访问 http://localhost:8080/页面应该出现登录框按 F12 看 Console 没有红色报错。第二用配置的账号密码尝试登录如果跳转到管理首页说明登录链路通。第三去数据库执行 select count(*) from user能看到登录时产生的更新时间变化或者去 upload 目录确认上传文件是否生成。如果你是用命令行启动的还可以用 curl 快速检查接口是否活着curl -X POST http://localhost:8080/api/login \ -H Content-Type: application/json \ -d {\username\:\admin\,\password\:\123456\}返回 JSON 里 code 为 200 就说明接口正常。curl 的好处是不依赖浏览器特别适合在服务器上排查问题。如果返回的是 404 或 500再回到 application.yml 检查路径和配置。这套验证顺序我每次换电脑复现都会走一遍能省下很多后期联调的麻烦。4. 前后端联调实战登录流程与用户信息管理模块的实现逻辑4.1 用户登录的 Controller-Service-Mapper 链路登录是这个系统里最典型的一条完整链路从浏览器 Ajax 请求到数据库校验中间经过三层。Controller 层接收请求并返回统一结构Service 层处理业务逻辑Mapper 层通过 MyBatisPlus 查询数据库。下面这段登录接口代码是常见写法RestController RequestMapping(/api) public class AuthController { Autowired private UserService userService; PostMapping(/login) public Result login(RequestBody LoginParam param) { User user userService.lambdaQuery() .eq(User::getUsername, param.getUsername()) .one(); if (user ! null user.getPassword().equals(param.getPassword())) { return Result.success(user); } return Result.error(用户名或密码错误); } }登录逻辑并不复杂先用 username 查询用户再比对密码。如果数据库里的 password 是明文这种方式可以跑通但毕设答辩时我会建议换成 BCrypt 加密因为明文存储很容易被面试官追问。LambdaQuery 是 MyBatisPlus 提供的链式查询eq 方法设置等值条件one() 返回唯一记录。这里有个容易翻车的点如果用户表没有设置 username 唯一索引查询出多条记录时 one() 会抛异常所以建表时一定要给 username 加唯一约束。这里配套的 Result 类最好是全局统一。它的内部结构是 code、msg、data静态方法 success 和 error 分别返回成功和失败结果。这样的好处是前端只用判断 code业务数据全放在 data 里后续扩展分页、列表、上传都能复用。实际项目里密码加密是有争议的不过这里我提供一个升级思路在注册接口中在 Service 中用 BCryptPasswordEncoder 加密登录时调用 matches 方法校验。但要注意数据库里已有的明文数据需要先重置否则升级后老用户全部无法登录。对于毕设演示保持简单可以但讲解时要能说清为什么可以简化。4.2 图片素材上传与展示的 Ajax 调用细节图片素材管理是系统里的另一个高频功能。上传的核心动作是把 MultipartFile 文件保存到本地磁盘再把相对路径写入数据库前端通过相对路径拼接出完整 URL 访问图片。后端接口的关键代码大概是这个样子PostMapping(/image/upload) public Result uploadImage(RequestParam(file) MultipartFile file, RequestParam(userId) Long userId) { String originalFilename file.getOriginalFilename(); String suffix originalFilename.substring(originalFilename.lastIndexOf(.)); String newFilename System.currentTimeMillis() suffix; String dir uploadDir /image; File target new File(dir, newFilename); if (!target.getParentFile().exists()) { target.getParentFile().mkdirs(); } file.transferTo(target); imageService.save(new Image(userId, /upload/image/ newFilename)); return Result.success(newFilename); }uploadDir 来自 application.yml 里自定义的 upload.dir这里建议在类上用一个 Value(${upload.dir}) 注入。时间戳加原来的后缀是为了避免同名文件互相覆盖mkdirs 确保目录存在transferTo 是 Spring 封好的文件写入方法比 MultipartFile.getInputStream 的流式拷贝简洁。路径拼接成 /upload/image/xxx.jpg 后需要把上传目录映射成静态资源否则浏览器无法直接访问下面这个配置放在 WebMvcConfigurer 里Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceLocations(file: uploadDir /); }注意 addResourceHandler 是 URL 前缀addResourceLocations 是磁盘绝对路径file: 前缀不能丢。文件上传成功后前端获取返回的文件名再调用新增接口把 title、url、userId 提交到 image 表列表页就能用 渲染图片。这个流程里最常见的错误是上传时机不对前端把表单提交和文件上传分成了两个请求先上传拿到路径再提交表单数据顺序反了就会导致数据库里没有 URL。删除图片素材的时候除了删掉 image 表里的记录还应该把磁盘上对应文件清理掉。很多复制来的项目只做 deleteById文件还留在 upload 目录时间长了全是僵尸文件。可以在删除方法里先查 url再用 File 对象 delete 掉物理文件删除失败也不影响主流程记一条日志就行。4.3 视频素材管理的权限与参数校验视频素材和图片素材的 CRUD 结构几乎一样区别在文件校验和权限控制。视频文件往往比图片大上传时要检查文件大小和格式常见做法是在前端限制文件类型后端再校验一次后缀名。默认允许 mp4、avi、mov 三种格式单个文件限制在 500MB 以内超过就返回错误信息。这个限制是通过 MultipartFile 的 getSize() 和文件名后缀实现的避免用户上传一个 2GB 的视频把磁盘写满。权限控制方面这个系统大概率没有引入 Spring Security而是通过拦截器判断请求头里的 token 或 session。管理后台的操作按钮需要根据当前登录用户的角色显示如果 role 是 ADMIN就显示删除和编辑按钮普通用户只能查看。前端通常在路由守卫里判断后端接口也要做同样的校验否则直接调接口就能绕过界面这在答辩时是加分的点。实现方式可以是定义一个 HandlerInterceptor在 preHandle 方法里从 headers 取 token解析出用户角色再放行。视频列表的展示也比图片多一层因为视频文件大列表页一般只显示封面图点击播放时才加载完整视频。所以 video 表里单独设计了 cover 字段有点类似视频网站的封面管理。新增视频时前端先上传封面图拿到路径再上传视频拿到路径最后把两个路径一起提交到后端。这个流程在演示时很有视觉冲击也符合智能家居系统的场景化展示需求。5. 避坑指南从安装到运行最常见的 5 个坑这个项目我拆了两遍第一遍卡了整整一个下午问题全不是代码而是环境与配置。所以这部分专门记录复现过程中最容易踩到的五个坑按“现象-原因-解决”的方式列出来你可以把它当成排查手册用遇到时直接对照。5.1 现象MySQL 连接报错 Communications link failure打开后端日志满屏的 Communications link failure 和 connection reset偶尔伴随着 Access denied for user。原因基本集中在两个地方一是 MySQL 服务没有启动Windows 下需要到系统服务里确认 MySQL 的状态是正在运行二是数据库名或账号密码和 application.yml 里对不上。第三种比较少但很致命MySQL 8.0 的密码加密规则是 caching_sha2_password老驱动不识别或者 url 少了 serverTimezone 参数也会导致连接被秒断。解决路径很固定先通过服务面板确认 mysqld 进程在跑然后在命令行用 mysql -u root -p 实际登录一次输错三次就该意识到是密码问题最后检查 driver-class-name 和 url 时区参数。之后再用 IDEA 右侧 Database 面板测试连接成功后再启动 Spring Boot一个问题一个问题排除远比对着堆栈猜快。5.2 现象Maven 依赖下载慢或失败现象是执行 mvn clean install 时停在某个依赖一直不动或者最后报错具体到 spring-boot-starter-web 等依赖上有红色波浪线。原因通常是本地 Maven 使用默认中央仓库地址国内访问极不稳定。解决方法是修改 settings.xml 中的 mirror 配置把中央仓库指向阿里云或腾讯云镜像。注意修改的是 Maven 安装目录下 conf/settings.xml不是项目里的 pom.xmlIDEA 里 Maven 的 User settings file 也要指向同一个文件否则改了半天它根本不读。改完镜像后还要跑到项目根目录执行 mvn clean install -U强制更新快照和依赖。如果某个 jar 已经损坏报错信息里会出现 invalid LOC header这时候删掉本地仓库对应目录让它重新下载比用任何刷新机制都管用。5.3 现象Vue 打包后接口请求 404登录页能打开但点击登录后浏览器 Network 面板显示请求 /api/login 返回 404。个别情况下页面都打不开只有 Spring Boot 的 404 白页。原因有两个打包后的 dist 没有放进 static或者放进了但请求路径没有带上 context-path。如果是前者静态资源目录下看不到 index.html明显是构建脚本没复制如果是后者部署时改了 server.servlet.context-path导致接口 URL 变成 /smart_home/api/login前端仍然请求 /api/login。解决方式是先打开 dist 目录确认文件再检查前端请求的 baseURL 配置在 axios 或 Ajax 里加上对应的前缀。这里也顺便提醒如果用 hash 模式路由前端页面跳转是走 # 的刷新不会 404如果改用 history 模式刷新会直接打到后端需要在后端把非 /api 的路径都转发到 index.html否则会很疼。5.4 现象MyBatisPlus 分页查不到数据页面列表能打开但总条数 total 显示 0或者第二页没数据。这个问题几乎可以断定是分页插件没有注册因为 MyBatisPlus 的 selectPage 方法在没有分页拦截器时会返回一个只有当前页数据、total 为 0 的假分页对象。很多时候不是查询 SQL 的问题而是少了第二章里那一段 MybatisPlusConfig。解决方式是在 config 包里加上分页插件的 Bean然后重启项目。另一种情况是 2.3 版本的 MyBatisPlus 中 PaginationInnerInterceptor 的构造需要 DbType不传会默认识别失败建议显式传 DbType.MYSQL。如果你的项目是 3.5.x分页拦截器导入包路径也变了旧代码的 import 会直接编译不过升级时尤其注意。5.5 现象端口冲突导致启动失败启动时抛出 Port 8080 was already in use这种问题最好解决。先打开命令行执行 netstat -ano | findstr 8080 找到占用进程的 PID然后 taskkill /F /PID 对应编号。要注意的是不要随便找进程就杀有可能把别的开发服务干掉。如果这个端口是必须保留的也可以在 application.yml 里把 server.port 改成 8081前端请求如果不做跨域记得同步修改前端请求端口。很多新版 IDEA 默认会占 8080 端口尤其是装了 Spring Boot Dashboard 插件的它会先把端口占住这时你的 Spring Boot 再启动自然失败。所属权搞清楚后再决定是换端口还是杀进程这种问题三分钟能解决但卡住时确实让人抓狂。6. 验证系统跑通后的进阶检查从“能登录”到“能答辩”6.1 用浏览器开发者工具核对请求链路登录成功后不要急着截图。按 F12 打开开发者工具切到 Network 面板刷新页面逐条看请求状态。重点核对三条登录接口是否返回 200图片上传接口是否返回 JSON静态图片资源是否返回 200。如果某个接口返回 500切到 Console 或 Preview能看到异常堆栈通常是数据库字段缺失或 Mapper 映射不正确。通过这个习惯你能快速定位大多数运行期问题。6.2 把打包产物放进 Spring Boot 静态资源目录的两种做法第一种是手动复制前端 npm run build 后把 dist 里所有文件复制到后端 src/main/resources/static后端 mvn clean package 重新打包。第二种是用插件自动完成在 pom.xml 里配置 frontend-maven-plugin让 Maven 在 package 阶段自动执行 npm install 和 npm run build。我一般更推荐第二种因为团队合作时不会出现镜像仓库里少文件的情况。下面是最简配置片段plugin groupIdcom.github.eirslett/groupId artifactIdfrontend-maven-plugin/artifactId version1.12.1/version executions execution idnpm build/id phaseprepare-package/phase goalsgoalnpm/goal/goals configuration argumentsrun build/arguments /configuration /execution /executions /plugin这个 plugin 里的 phase 是 prepare-package意思是 Maven 打包前先执行前端构建版本 1.12.1 是当前较稳定的一个。配置到位后你拿到的 jar 本身就是前后端完整版不用手动维护两套文件。6.3 答辩前的数据备份与交接清单如果这项目是用来做毕设答辩最后一步是数据备份。建议导出数据库 SQL 文件和本地上传目录用压缩包整体提交给导师或放进文档附件。sql 文件里要包含表结构和初始化数据上传目录里要保留演示用的图片视频否则换一台电脑演示时图片素材模块会一片空白。我在拆这个项目时吃过这个亏换了机器后忘记拷贝 upload 目录演示到图片管理时全是裂图场面非常尴尬。从那以后我每次拿到这种前后端一体的 Spring Boot 项目都会先做三件事跑通脚本、核对配置、备份数据库和上传目录再开始改代码。环境版本、分页插件、上传路径这三个点几乎覆盖了八成的启动失败问题。希望这份实战拆解能帮你在自己的机器上少折腾几个小时把精力省下来留给系统功能和答辩准备真正让这套基于 Spring Boot 的智能家居系统成为你拿得出手的项目。本文还有配套的精品资源点击获取