☰
SpringBoot+Vue+Redis商城源码实战:从跑通到改造的避坑指南
2026/10/9 15:08:50 网站建设 项目流程

简介:这是一套面向计算机相关专业毕业设计与课程作业的网上商城实战项目,采用SpringBoot+Vue+Redis前后端分离架构,后端以SpringBoot简化开发流程,前端用Vue专注视图层,Redis承担缓存以提升读写与并发性能,适合想完整跑通电商业务链路的初中级开发者练手。压缩包共2034个文件,以1358个md说明文档、562个js脚本、69个json配置为主,另含少量docx、html与sh脚本,整体约117.18MB,源码与SQL脚本齐备,导入即可对照README梳理商品展示、购物车、订单处理、用户管理等模块的实现方式。目前已有124人学习下载。项目经严格测试验证可正常运行,读者可借此理解前后端分离下的数据交互与接口设计,并参考文档快速定位目录结构与关键逻辑,仅限交流学习,请勿用于商业用途。

1. 从一份已调试的 SpringBoot+Vue+Redis 商城源码说起

拿到一份标着「已调试」的前后端分离网上商城项目,很多人的第一反应是解压、导入 IDE、点运行,然后被一堆报错劝退。这份springboot+vue+redis前后端分离网上商城项目003的价值不在于它是个商城,而在于它把一套完整的工程骨架跑通了:后端 SpringBoot 提供 REST 接口,前端 Vue 做单页应用,Redis 承担缓存与会话,MySQL 存业务数据。对想入门前后端分离、想拿一个能跑的项目改造成自己作品的开发者来说,这种「已调试」的源码省掉了最耗时的环境对齐环节。但它也不是拿来即用的成品,配置、依赖版本、跨域、缓存穿透这些坑一个不少。这篇笔记就按我实际复现这类项目的顺序,把选型理由、启动步骤、参数设置和排错经验讲清楚,让你能真正把它跑起来、改得动。

2. 前后端分离商城的骨架拆解与选型理由

2.1 为什么是 SpringBoot + Vue + Redis 这套组合

先想清楚这套技术栈各自解决什么问题,后面改代码才不会乱。SpringBoot 负责后端,核心优势是自动装配和起步依赖,一个spring-boot-starter-web就把内嵌 Tomcat、SpringMVC、Jackson 全带进来,省掉传统 SSM 那套 XML 配置。Vue 负责前端,单文件组件把模板、逻辑、样式收在一个.vue文件里,配合 Vue Router 做前端路由、Axios 发请求,天然适合前后端分离。Redis 在这里不是可有可无的装饰,它承担两类活:一是缓存热点数据(商品详情、分类列表),减少 MySQL 压力;二是存会话或令牌,让后端可以无状态水平扩展。

为什么不用 JSP 或 Thymeleaf 做服务端渲染?因为商城的商品列表、购物车、订单这些交互频繁,服务端渲染每次都要整页刷新,体验差、后端压力大。前后端分离后,前端只管渲染,后端只吐 JSON,职责清晰,前端还能独立部署到 Nginx。这套组合在中小型电商项目里是主流做法,资料多、招人好招,出问题也容易搜到答案。

2.2 目录结构与模块职责

解压后典型的结构分两块:后端一个 Maven 工程,前端一个 Node 工程。后端常见分层是controller(接收请求)、service(业务逻辑)、mapper或dao(数据库访问)、entity(实体)、config(配置类)、utils(工具)。前端常见是src/api(接口封装)、src/views(页面)、src/components(公共组件)、src/router(路由)、src/store(状态管理)。

模块职责常见文件
controller暴露 REST 接口,参数校验UserController.java
service业务编排、事务控制OrderServiceImpl.java
mapperSQL 映射,MyBatis 接口ProductMapper.xml
config跨域、拦截器、Redis 序列化CorsConfig.java
api前端接口统一封装request.js
router前端路由与权限守卫index.js

理解这个结构后,你要加一个「优惠券」功能,就知道该在 controller 加接口、service 写逻辑、mapper 写 SQL、前端 api 加方法、views 加页面,路径是固定的。

2.3 数据库表与 Redis 键的设计关系

商城核心表一般有用户表、商品表、分类表、购物车表、订单表、订单明细表。Redis 的键设计要和这些表对应起来,常见做法是:商品详情用product:detail:{id},分类列表用category:list,用户令牌用token:{userId}。键名带业务前缀是为了避免不同业务键冲突,也方便用keys product:*排查(生产环境别用 keys,用 scan)。

注意:Redis 里存对象时,序列化方式要和读取时一致。后端用 Jackson 序列化成 JSON 存,前端或另一个服务读的时候也得按 JSON 解析,否则拿到的是带类名的乱码。

3. 把项目在本地跑起来的最小步骤

3.1 后端启动:改配置、建库、跑起来

第一步永远是看配置文件。后端配置文件通常是application.yml或application.properties,重点改三处:数据库连接、Redis 连接、服务端口。

# application.yml 关键配置 server: port: 8080 # 后端服务端口,前端代理要对应 spring: datasource: url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver redis: host: localhost port: 6379 database: 0 timeout: 3000ms

serverTimezone必须设,否则 MySQL 8 连接会报时区错误。characterEncoding=utf8防止中文乱码。Redis 的database默认 0,如果你本机跑过别的项目,建议换成 1 避免键冲突。改完配置,先在 MySQL 里建库,再导入项目自带的.sql文件。

# 建库并导入 SQL mysql -uroot -p -e "CREATE DATABASE mall DEFAULT CHARACTER SET utf8mb4;" mysql -uroot -p mall < mall.sql

导入后确认表和数据都在,再启动后端。用 IDE 直接运行主类,或命令行mvn spring-boot:run。看到控制台打印 Tomcat 启动在 8080 端口、没有异常堆栈,后端就算起来了。如果报Table 'mall.xxx' doesn't exist,说明 SQL 没导全或库名对不上。

3.2 前端启动:装依赖、配代理、连后端

前端进目录先装依赖,再改接口基地址。很多项目在src/utils/request.js或.env文件里配baseURL。

// request.js 里配置 axios 实例 import axios from 'axios' const service = axios.create({ baseURL: '/api', // 走开发服务器代理,避免跨域 timeout: 5000 }) service.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) config.headers['Authorization'] = token // 带上令牌 return config }) export default service

baseURL设成/api是为了走 Vue 开发服务器的代理,把/api开头的请求转发到后端 8080,这样浏览器看到的是同源请求,不会触发跨域。代理配置在vue.config.js:

// vue.config.js module.exports = { devServer: { port: 8081, proxy: { '/api': { target: 'http://localhost:8080', // 后端地址 changeOrigin: true, pathRewrite: { '^/api': '' } // 去掉 /api 前缀再转发 } } } }

pathRewrite要不要写,取决于后端接口路径带不带/api。如果后端 controller 映射是/user/login,前端请求/api/user/login,就必须 rewrite 掉/api。装依赖用npm install,启动用npm run serve,浏览器打开 8081 端口能看到页面就成功了一半。

3.3 验证三层是否真的打通

页面能打开不代表数据通了。按顺序验证:先直接访问后端接口,比如浏览器或 Postman 请求http://localhost:8080/user/login,看是否返回 JSON;再在前端页面触发一次登录,打开浏览器开发者工具的 Network 面板,看请求是否 200、响应体是否是预期数据;最后看 Redis 里有没有写入令牌。

# 连上 Redis 查看键 redis-cli -n 0 > keys token:* > get token:1

如果接口返回 401 或 403,多半是拦截器没放行登录接口;如果 Network 里请求地址是 8081 而不是 8080,说明代理没生效,检查vue.config.js是否被正确加载(改完要重启前端)。这三步走完,项目才算真正跑通。

4. Redis 缓存与登录态的落地细节

4.1 商品缓存:什么时候写、什么时候删

缓存最怕的是数据不一致。常见做法是「读时缓存、写时删除」:查商品先读 Redis,命中就返回,没命中查 MySQL 再写回 Redis;更新商品时先更新 MySQL,再删除对应 Redis 键,而不是更新缓存。删除比更新安全,因为并发下更新缓存可能写入旧值。

// 商品详情缓存逻辑 public Product getProductById(Long id) { String key = "product:detail:" + id; String cached = redisTemplate.opsForValue().get(key); if (cached != null) { return JSON.parseObject(cached, Product.class); // 命中直接返回 } Product product = productMapper.selectById(id); if (product != null) { redisTemplate.opsForValue().set(key, JSON.toJSONString(product), 30, TimeUnit.MINUTES); } return product; }

30是过期时间,单位分钟。设过期时间是为了兜底:万一删除逻辑漏了,缓存最多脏 30 分钟。过期时间设多长看业务,商品详情变化不频繁可以设长,库存这种高频变化的建议不缓存或设很短。

4.2 登录令牌:Redis 存什么、存多久

前后端分离下,后端不存 session,登录成功后生成一个令牌返回前端,前端存 localStorage,每次请求带上。令牌和用户信息的映射放 Redis,键是token:{token},值是用户 ID 或用户对象,设一个过期时间,比如 2 小时。

// 登录成功后写令牌 String token = UUID.randomUUID().toString().replace("-", ""); redisTemplate.opsForValue().set("token:" + token, userId, 2, TimeUnit.HOURS);

拦截器里校验:取请求头的令牌,去 Redis 查,查不到就返回 401。这样后端可以多实例部署,令牌校验不依赖单机内存。令牌过期时间要和前端行为匹配,太短用户频繁掉线,太长有安全风险。常见做法是配一个刷新机制,或者前端在令牌快过期时静默续期。

4.3 缓存穿透、击穿、雪崩的应对

这三个词听着玄学,其实就是三种失效场景。穿透是查一个数据库里也没有的键,每次都打到 MySQL;击穿是某个热点键过期瞬间大量请求涌向数据库;雪崩是大量键同时过期。应对手段:穿透可以缓存空值或加布隆过滤器;击穿可以给热点键加互斥锁,只让一个请求去查库;雪崩给过期时间加随机值,别让键同时失效。

// 缓存空值防穿透 if (product == null) { redisTemplate.opsForValue().set(key, "", 5, TimeUnit.MINUTES); // 空值短过期 return null; }

空值过期时间要短,否则数据后来真有了,缓存里还是空。互斥锁用setIfAbsent实现,拿到锁的请求去查库,其他请求短暂等待后重试。这些手段不用全上,按业务量级选,小商城缓存空值基本够用。

5. 避坑与排查:那些让项目跑不起来的常见问题

5.1 跨域报错但代理已配

现象:浏览器控制台报Access-Control-Allow-Origin,但vue.config.js里代理明明配了。原因通常是请求没走代理,比如baseURL写成了完整地址http://localhost:8080,浏览器直接跨域请求后端。解决:baseURL用相对路径/api,让请求先到前端开发服务器再转发。另外改完vue.config.js必须重启npm run serve,热更新不会重载代理配置。

5.2 后端启动报数据源或 Redis 连接失败

现象:启动时抛Communications link failure或Unable to connect to Redis。原因多是 MySQL 没启动、端口不对、密码错,或 Redis 服务没开。解决:先用mysql -uroot -p和redis-cli ping确认两个服务都能连,再核对配置文件里的端口和密码。Redis 返回PONG才算正常。如果 Redis 设了密码,配置里要加password项,漏了会报NOAUTH。

5.3 前端页面空白或接口 404

现象:页面能打开但一片空白,或接口返回 404。原因可能是路由模式问题,history 模式在开发服务器下刷新会 404,改成 hash 模式或配 fallback;也可能是接口路径多了或少了前缀。解决:打开 Network 看实际请求 URL,和后端 controller 的@RequestMapping逐段比对。404 基本都是路径对不上,把前端请求路径和后端映射贴一起看,一眼就能发现。

5.4 中文乱码

现象:页面显示的商品名是问号或乱码。原因可能在数据库字符集、连接 URL 或响应编码。解决:建库用utf8mb4,连接 URL 带characterEncoding=utf8,后端返回 JSON 时确认Content-Type是application/json;charset=UTF-8。三处都对了才不会乱码。MySQL 8 默认字符集已经是 utf8mb4,老版本要手动设。

5.5 修改代码后不生效

现象:改了后端代码重启没变化,或改了前端页面刷新还是旧的。原因可能是 IDE 没重新编译、Maven 没重新打包,或前端浏览器缓存。解决:后端确认 target 目录里的 class 是新的,必要时mvn clean;前端硬刷新(Ctrl+F5)或禁用缓存。这类问题最没技术含量但最耗时间,养成改完先确认编译产物的习惯。

6. 把这套骨架改造成自己项目的方法

跑通只是起点,真正有价值的是把它改成你自己的东西。我的习惯是先做减法再做加法:删掉用不上的模块(比如原项目的秒杀、团购),只留用户、商品、订单三条主线,让代码量降下来,自己完全掌控。然后按业务加功能,每加一个功能都走一遍 controller→service→mapper→前端 api→views 的完整链路,链路走顺了,这套骨架就真成你的了。

改造时有两个技巧值得记。一是接口先定契约再写实现,用 Postman 或接口文档工具把请求参数、响应结构定死,前后端并行开发不互相等。二是缓存键统一管理,别在代码里到处硬编码字符串,抽一个RedisKeyUtil类集中定义,改键名时只改一处。

改造方向具体做法注意点
换主题改前端 views 和样式别动 api 层,接口不变
加支付新增 controller 和 service支付回调要验签、防重
加搜索引入搜索引擎或优化 SQL数据量大再上搜索引擎
部署上线前端打包丢 Nginx,后端打 jar生产环境关掉开发代理

验证改造是否成功,别只看页面能点,要压一压。用ab或wrk对商品列表接口打几百个并发,看响应时间和错误率;把 Redis 停掉,看系统是降级查库还是直接崩,这能暴露缓存逻辑的健壮性。我踩过最深的坑是缓存和数据库双写不一致,后来统一成「先更库再删缓存」才稳定。这套骨架不难,难的是每个细节都想到边界。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询