ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SpringBoot2+Vue3全栈实战:动物领养平台搭建与部署指南

SpringBoot2+Vue3全栈实战:动物领养平台搭建与部署指南 做全栈项目最怕的就是“跑不起来”和“不知道怎么跑”。动物领养平台这个项目SpringBoot2 Vue3 MyBatis-Plus MySQL8.0的经典组合可以说是当前Java Web开发里最主流的配置之一。如果你正在找一套能完整跑通前后端、又带文档参考的源码项目这篇文章会从技术拆解到环境搭建再到实际运行中会踩的坑把整个链路都捋一遍。我不打算做那种“复制粘贴README”的流水账而是以实际动手的视角把这个平台拆成可复用的模块来分析。适合正在做毕业设计的学生、想转全栈的Java开发以及想快速搭一个管理系统模板的前端同学参考。1. 整体设计思路与技术选型1.1 为什么偏偏是这套组合先说技术栈选择的逻辑。Java Web领域里SpringBoot早就成了事实标准但2.x和3.x的分水岭很明显。3.x要求JDK17起步不少学校机房和老项目还在JDK8所以SpringBoot2依然有巨大的存量需求。配合MyBatis-Plus等于把单表CRUD和基础分页从“手写一大串XML”变成“几行代码搞定”这对中小型管理类项目来说是极大的效率提升。Vue3现在已经是前端主流组合式APIComposition API配合script setup写法代码组织比Vue2的Options API清晰得多特别是在组件多了之后逻辑复用和TypeScript支持都有优势。MySQL8.0则是数据库侧当前最稳妥的选择性能、JSON支持、窗口函数都比5.7强一截。这个项目有意思的地方在于“动物领养平台”这个业务选型。它不是一个脱离实际的DEMO而是有一套真实的管理逻辑普通用户领养人浏览动物列表、提交领养申请管理员管理动物信息、审核领养申请、管理用户状态系统需要处理图片上传、状态流转、数据分页展示这些需求几乎覆盖了管理系统开发中的全部高频场景。用这套代码当一个通用后台管理模板来改造完全没问题。1.2 前后端分离架构下需要提前想清楚的事前后端分离的核心问题有三个跨域、鉴权、接口约定。跨域在开发环境一般通过Vite代理解决后端不用关心。生产环境则配合Nginx反向代理把/api转发到后端服务自然就没有跨域问题。鉴权这里必须提前考虑。如果项目用了Spring Security JWT那么前端每次请求都要带token后端放行白名单接口。如果项目用的是简单的登录拦截器或者Shiro原理类似。真正容易出问题的是“token过期刷新”和“用户被禁用后的状态同步”这些边界情况在没文档参考的项目里往往要自己摸索半天。接口约定则建议遵循RESTful风格配合统一返回体。如果项目里已经封装了类似ResultT这种统一响应结构前端拦截器也做了相应处理那恭喜你省了很多联调时间。这也是我建议拿到源码后第一件事去看的东西不是去看业务代码而是先搞清楚返回结构、异常处理和分页参数约定。2. 核心模块拆解与数据库设计2.1 数据模型背后的业务逻辑拿到源码先别急着启动把数据库脚本打开看一遍基本就能理解整个业务了。动物领养平台通常包含这五张核心表表名核心字段作用用户表用户名、密码、手机号、角色、状态区分管理员和普通领养人动物表名称、种类、年龄、性别、健康状态、图片、领养状态平台的商品核心领养申请表用户ID、动物ID、申请理由、状态、时间领养流程的状态流转载体公告表标题、内容、发布时间平台资讯发布收藏表用户ID、动物ID用户的意向收藏这里面关键是动物表和领养申请表的状态设计。动物有“待领养”“已申请”“已领养”三种状态领养申请有“待审核”“已通过”“已拒绝”三种状态。两个表的状态必须联动更新否则就会出现“动物已领养但申请还挂着”的数据不一致问题。在代码里实现状态联动我的建议是更新领养申请状态时的同一事务里直接更新动物状态。千万别用“先改申请状态再调另一个接口去改动物状态”的两步操作事务分离的情况下一旦中间出错数据就脏了。2.2 MyBatis-Plus用的顺不顺手看这几个细节MyBatis-Plus让单表操作变得无脑简单但用不好也会埋坑。我建议拿到项目后重点看这几个地方第一逻辑删除配置。TableLogic注解加了之后所有查询会自动追加WHERE deleted 0。这是好事但如果你在XML里写了自定义SQL忘记在条件里拼接逻辑删除字段就会出现“明明删了还能查出来”的诡异问题。而且逻辑删除会影响唯一索引比如用户名做了唯一索引删除后再次注册同名用户会失败这点要留意。第二自动填充。create_time和update_time建议用TableField(fill FieldFill.INSERT)配合MetaObjectHandler实现自动填充而不是在业务代码里手动setCreateTime(new Date())。前者不会漏字段代码也干净。很多源码项目会忽略这一点直接在Service里手动塞时间一旦某些入口忘了set就出现时间为空的数据。第三分页插件。MyBatis-Plus的分页需要配置PaginationInnerInterceptor而且一定不要忘记配置数据库类型为MySQL。不配置类型的后果是分页SQL生成异常或者查出来总数不对。拿到源码后第一件事就去确认MybatisPlusInterceptor这个Bean是否配置正确。至于LambdaQueryWrapper建议项目中统一使用。相比字符串写死的QueryWrapperLambda版本在编译期就能发现字段名拼写错误重构时也更安全。3. 环境搭建与项目启动全流程3.1 MySQL8.0的安装和配置MySQL8.0的安装方式现在主要有两种本机安装和Docker运行。本机安装建议直接去官网下MySQL Installer选Server only即可。安装过程中有一个步骤要选认证方式这里务必选“Use Legacy Authentication”否则一些老版本的工具和驱动连不上。MySQL8.0默认的caching_sha2_password认证方式对老客户端不够友好选Legacy模式可以省掉后续一堆密码认证报错。如果机器上已经装了Docker用容器跑更干净不会污染宿主机环境docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD123456 \ -e MYSQL_DATABASEanimal_adopt \ mysql:8.0这里MYSQL_DATABASE会自动帮你建好库。等容器起来后用docker exec -it mysql8 mysql -uroot -p123456就能进去看到库。启动后调整字符集很重要。MySQL8.0默认字符集虽然已经是utf8mb4但为了保险建议在配置文件Linux下是/etc/my.cnfWindows下是my.ini里显式加上[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci不然你插入中文数据可能正常但某些特殊表情符号emoji会报错。做领养平台动物描述里出现emoji太正常了。3.2 JDK、Maven和Node环境的版本搭配这一步是新手最容易踩坑的地方。SpringBoot2.x对应JDK8或JDK11都可以但如果代码里用了var或者List.of()这类语法就必须JDK11以上。Maven建议用3.6.3以上版本太老的Maven解析SpringBoot依赖时可能出错。前端方面Vue3项目默认需要Node 16以上Vite 4需要Node 14.18或16Vite 5则需要Node 18。如果启动前端时提示“Node.js version must be 18”就直接去Node官网下载最新的LTS版本重装。这里有个建议用nvm管理Node版本切换项目时不用反复重装。环境版本对应关系整理如下组件推荐版本注意事项JDK8或11看代码里是否有高版本语法Maven3.6.3依赖下载慢就配国内镜像Node.js16/18 LTSVite版本不同要求不同MySQL8.0.x认证方式选LegacyIDEIDEA 2022自带SpringBoot插件3.3 后端启动的详细步骤后端启动流程看起来就两步启动MySQL、运行SpringBoot但里面有几个配置文件必须提前检查application.yml里的数据库连接信息要和本地一致spring: datasource: url: jdbc:mysql://localhost:3306/animal_adopt?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue username: root password: 123456这串JDBC URL里的参数每个都有讲究serverTimezoneAsia/Shanghai不指定的话MySQL驱动会拿服务器默认时区跟国内相差8小时查出来的时间全不对。useSSLfalse本地开发没配SSL证书true会报警告。allowPublicKeyRetrievaltrueMySQL8.0用caching_sha2_password认证时不设这个会报Public Key Retrieval is not allowed。数据库初始化方面源码一般会附一个.sql文件。记得在Navicat或命令行里执行之前先确认SQL文件中是否包含CREATE DATABASE语句。包含的话直接执行即可不包含就得先手动建库再选择该库执行。执行之后顺手验证几张核心表的数据USE animal_adopt; SHOW TABLES; SELECT * FROM sys_user;这两条语句能确认表是否建全、初始管理员账号是否存在。后端启动前还要检查代码里的Redis配置。很多管理系统会引入Redis做缓存或存储token如果直接用${REDIS_HOST}这种写法而本地没有Redis启动就会报错。如果项目里确实用了Redis本地要先用Docker跑一个docker run -d --name redis -p 6379:6379 redis:7application.yml里再对应把host改为localhost密码去掉或留空。3.4 前端启动的完整流程前端项目结构一般长这样animal-adopt-front/ ├── src/ │ ├── api/ # 接口请求封装 │ ├── components/ # 公共组件 │ ├── router/ # 路由配置 │ ├── store/ # Pinia状态管理 │ ├── views/ # 页面 │ ├── App.vue │ └── main.js启动前先安装依赖。这里不推荐用npm直接装国内网络环境下经常卡住用淘宝镜像源会快很多npm config set registry https://registry.npmmirror.com npm install依赖装完后看package.json里的scripts字段确认启动命令。一般是npm run dev。跑起来后注意Vite的端口配置默认5173。如果后端接口路径是写死在代码里的http://localhost:8080/api那没问题如果用的是相对路径/api则需要配置Vite代理。打开vite.config.js确认代理配置server: { port: 5173, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } }代理配好后前端代码里axios.get(/api/animals)这类请求会自动转发到后端8080端口浏览器控制台不会出现跨域报错。启动过程中如果报模块找不到优先检查package-lock.json是否存在且与根目录匹配。经常有同学把前端代码拷到新电脑后重新npm install装了一堆不同版本依赖导致启动报错此时删掉node_modules和package-lock.json重新安装最省事。4. 核心功能场景的实操走查4.1 初始化账号与首次登录运行成功后第一件事是登录系统。源码里通常会预置一个管理员账号常见的是admin/admin123之类。登录逻辑背后涉及两条链路后端登录接口接收账号密码校验通过后生成JWT令牌返回。后续请求头带Authorization: Bearer xxxSpring Security或拦截器解析令牌后把用户信息塞进上下文。前端拿到token后存在Pinia localStorage里路由守卫判断是否有token有则放行无则跳转登录页。我拿到源码后会做的第一件事是去后端代码里搜/login接口的实现确认密码的加密方式。如果数据库里的密码是密文加密算法一般是BCrypt也就是PasswordEncoder相关接口。这里有个很容易掉进去的坑如果自己去数据库里手动插入一条用户记录密码直接填了明文登录时永远提示密码错误因为BCrypt的比对结果是false。4.2 动物信息的CRUD流程走查动物管理是平台的核心业务通常包含新增动物、编辑信息、上下架状态切换、图片上传。建议从新增一只动物开始完整走一遍前端控制台、后端日志、数据库记录三处对照着看。新增动物时图片上传的返回格式特别容易出问题。如果后端返回的是一个字符串图片URL前端直接用image: url保存即可。如果返回的是JSON对象就要确认是否包了一层{ url: xxx }。两者的代码写法完全不同这就是联调时最常见的扯皮点。另一个容易出问题的是表单校验。前端校验比如年龄必须是非负整数、描述不能为空通常用Element Plus的rules配置实现但后端Service里同样要做一次参数校验。原因很简单前端校验只是用户体验后端校验才是安全防线。学这个项目的时候注意观察后端是否用了Validated或手动if判断。4.3 领养申请的状态流转逻辑领养申请这个功能是整个平台最“业务”的地方。用户选一只动物提交申请管理员审核通过后动物状态改为“已领养”其他用户就看不见这条动物了或者看到的是“已领养”的置灰状态。状态机虽然简单但实现时至少涉及三个表的更新领养申请表插入一条记录状态为“待审核”动物表状态改为“申请中”防止别的用户重复申请用户表可能还要记录申请次数或标记领养人身份看源码时重点关注Service层的Transactional注解是否加在正确位置。加在Controller上是错误示范加在Service的公开方法上才是正确做法。事务一定要在业务方法入口处开启否则同类内部this调用的方法不会被事务拦截。如果你发现了重复提交申请的问题用户手快点了两次提交按钮生成了两条申请记录这就涉及幂等性问题。解决方案很简单前端提交后立刻置灰按钮同时对“同一用户对同一动物只能有一条待审核记录”做唯一约束或逻辑判断。很多项目不做这个所以这是可以优化后写进简历的亮点。5. 部署上线环节的实战记录5.1 后端打包的两种方式后端部署的核心是把SpringBoot项目打成可执行Jar包常见两种方式第一种在IDEA右侧Maven面板双击package输出在target/目录下mvn clean package -DskipTests第二种命令行直接打包cd 项目根目录包含pom.xml mvn clean package打包配置里有一个点需要重点检查pom.xml中是否引入了spring-boot-maven-plugin。没有这个插件打出来的Jar包不能直接用java -jar运行报“没有主清单属性”错误。加了这个插件才会把依赖和启动逻辑一起打进去。打包完成后找animal-adopt-0.0.1-SNAPSHOT.jar放到服务器上跑nohup java -jar animal-adopt-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod app.log 21 这里--spring.profiles.activeprod是指定生产环境配置。生产环境和开发环境的数据库密码、日志级别通常都是分开的用Profile机制切换源码里应该有application-prod.yml之类文件供参考。5.2 前端构建与Nginx部署Vue3项目构建之后生成的是纯静态文件部署到Nginx即可npm run build构建完成后在dist/目录下生成一堆静态资源。把整个dist目录传到服务器放在Nginx配置的root路径下。Nginx配置/etc/nginx/conf.d/adopt.confserver { listen 80; server_name your-domain.com; root /var/www/animal-adopt; index index.html; location / { try_files $uri $uri/ /index.html; } location /api { 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; } }关键点是try_files $uri $uri/ /index.html这句的作用是实现前端路由的history模式。Vue3项目如果用createWebHistory()创建路由并且不做这个配置用户在地址栏刷新/animals页面时Nginx会返回404因为服务器上根本没有这个物理路径。开发环境Vite会自动处理这个所以本地跑没问题部署到服务器就翻车这是最常见的生产环境事故之一。Nginx配好后执行nginx -t验证配置再nginx -s reload生效。如果服务器没有域名直接用IP访问也可以不用配server_name。5.3 HTTPS和上线后的必要检查项如果绑定了域名建议直接把HTTPS也配上。Let‘s Encrypt的免费证书配合Certbot申请一条命令搞定不用花一分钱。上线后必须检查这几项一是日志滚动。SpringBoot默认的logback配置如果不设置大小和时间滚动日志文件会无限增长几个月后磁盘被撑爆。生产环境至少要有按天滚动的策略。二是数据库备份。动物领养平台的数据库不算高频更新但日备份还是很有必要的。最简单的方案是每天用crontab跑一次mysqldump0 2 * * * mysqldump -uroot -p123456 animal_adopt /backup/animal_adopt_$(date \%Y\%m\%d).sql三是后端内存参数。默认的java -jar用的是JVM默认堆大小服务器上是物理内存的四分之一。如果服务器内存是2G堆只有512M稍微多一点并发就频繁Full GC。加参数启动更稳妥java -jar animal-adopt.jar --server.port8080 -Xms512m -Xmx1024m6. 常见运行问题速查与排查思路运行这种全栈项目遇到报错太正常了关键是有没有一套清晰高效的排查顺序。很多人拿到报错直接百度复制粘贴效率其实很低。我的做法是先看后端控制台再看前端控制台最后看浏览器Network面板。后端报错看堆栈前端报错看请求响应码。下面贴几个刷这个项目最容易碰到的问题按“症状-原因-解法”列个表照着套就行现象原因解决方案后端启动报Access denied for user rootlocalhost数据库密码不对检查yml配置和MySQL实际密码后端启动报Unknown database animal_adopt未执行SQL脚本或建库失败执行初始化SQL或手动建库前端npm install卡死或下载慢网络源不稳定切换淘宝镜像源再装前端启动报vite不是内部或外部命令依赖没装上或node_modules不完整删掉node_modules重新npm install登录时前端报Network Error后端未启动或跨域未配置确认后端在8080端口运行检查代理配置查询列表接口报Table doesnt exist表名和实体类不一致查看TableName注解是否正确接口返回401token缺失或过期登录后检查请求头是否携带token接口返回500后端代码执行异常查看后端日志的Exception堆栈数据库中文乱码字符集配置不对确保库、表、连接串均为utf8mb4图片加载失败上传路径和访问路径不一致确认虚拟路径映射配置是否正确碰到404先确认请求URL和Controller的RequestMapping是否一致。有时候前端写的路径是/animals后端定义的是/animal拼接后对不上这个靠肉眼排查比靠Debug快得多。502则要看Nginx转发目标是否在线。在服务器上执行curl -I http://127.0.0.1:8080/api/animals如果返回正常但Nginx访问报502那就是Nginx配置里proxy_pass地址写错了。还有数据库连接池报错的情况。SpringBoot2默认用的是HikariCP它的maximum-pool-size默认是10。如果本地用Navicat开了好几个连接再加上后端连接池的连接可能把MySQL的max_connections打满。本地开发环境把maximum-pool-size调到5就够了生产环境再根据并发量调整。排查问题的基本顺序可以总结为环境问题版本不匹配→ 配置问题账号密码、端口路径→ 代码问题业务逻辑、SQL错误。百分之八十的启动问题都在前两步别一上来就把代码翻个底朝天。7. 基于这套源码可以做哪些二次扩展7.1 给项目增加Redis缓存如果源码没引入Redis加一个其实非常简单。场景就是首页热门动物列表或公告列表在Controller查询前先查缓存查不到再查数据库回填缓存并设置过期时间。核心配置只需要加依赖和改yml。不过在改造前必须想清楚一件事不是所有接口都适合加缓存只有高频查询、低频更新的数据才值得。动物的领养状态是高频变更的缓存反而容易显示脏数据这属于典型的缓存一致性问题。可以说让整个项目更有“含金量”的最快途径不是堆功能而是把缓存、日志、全局异常处理这些基础能力打磨好。7.2 用Axios拦截器统一处理错误前端请求如果到处写try-catch遇到异常时处理逻辑就会很散。更规范的做法是在axios拦截器中统一处理把错误提示消息组件弹Toast、401跳转登录等逻辑集中起来每个页面的业务代码里只需要关心成功分支。改造方法就是创建一个src/utils/request.js在里面封装好axios实例设置请求拦截器和响应拦截器然后把所有页面里的axios.get替换成request.get引用即可。7.3 增加数据统计报表如果一个平台只有CRUD做完了总觉得少了点说服力。加一个统计报表页本质是给前端引一个ECharts图表后端写一个统计接口返回聚合数据。比如“按动物种类统计数量”SELECT category, COUNT(*) AS cnt FROM animal GROUP BY category接口返回给前端前端用ECharts画饼图或柱状图一张管理员驾驶舱页面就出来了。如果代码里已经有ECharts依赖那只需要补接口和页面工作量很低但整个项目看起来会完整很多。7.4 为项目加上定时任务动物领养平台也可以加一个定时任务场景定期将“待审核超过7天”的申请自动通知管理员或者定期清理长期未登录的临时账号。SpringBoot2里只需要在启动类上EnableScheduling然后在Service里写一个带Scheduled(cron 0 0 9 * * ?)的方法即可。定时任务要注意的是多实例部署时会重复执行幂等处理必须做好。8. 一些拿源码练手的实用建议最后说几点个人建议。第一源码拿到手后别急着启动先花半小时通读一遍结构。后端看controller、service、mapper三层是否清晰前端看api、views、router是否规范。一个好项目结构本身就说明问题。如果连包结构都是乱的那大概率后面代码也乱。第二一定要自己从零启动一次而不是依赖“老师已经配好的环境”。只有踩过端口冲突、依赖版本不一致、MySQL认证模式不匹配这些坑换一台电脑才知道怎么排查。第三建议做一次集中走查专门找“极端输入会怎样”新增动物时年龄填负数提交领养时快速点两下按钮用不存在的用户ID直接调接口上传超大图片文件连续查询不存在的ID详情把这些场景的预期行为判断一遍把明显不符合预期的修掉。这一轮做完你对项目的理解深度会明显上一个大台阶远比自己按文档过一遍代码效果好。第四记得把这份源码的项目结构和改造点沉淀成自己的笔记。面试聊项目时能说出“我把定时任务加在了xx场景解决了xx问题”和“我跑通了项目”是完全两个水平。前者展示的是解决问题的能力后者只是证明动手能力。动物领养平台这个题很常见但能把状态流转、缓存控制、部署细节讲清楚的人其实并不多。
返回列表