☰
校园交友网站源码实战:SpringBoot+Vue前后端分离跑通与避坑指南
2026/10/7 16:56:48 网站建设 项目流程

简介:这份资源是面向计算机专业毕业设计场景的校园交友网站完整项目源码,采用SpringBoot后端与Vue前端分离架构,基于B/S结构开发,数据库使用MySQL 5.7,适合需要完成Java方向毕设的学生或想练手全栈项目的开发者参考。压缩包共808个文件,约73.46MB,其中115个java文件承载后端业务逻辑,45个vue与164个js文件构成前端页面与交互,另有41个html、53个css及大量svg、gif、png等静态资源,并附带sql脚本、bat启动脚本与docx论文文档,目录结构完整。系统区分管理员与用户两类角色:管理员负责用户管理、线下活动管理、交友信息管理、活动报名管理、交流论坛及系统管理;用户端可浏览线下活动、交友信息、公告信息,并在个人中心与后台完成交友信息、活动报名等操作。目前已有1001人学习下载,配套论文、答辩PPT与演示视频,便于快速理解业务模块划分与前后端联调思路。

1. 校园交友网站源码拆开看:SpringBoot + Vue 这套组合到底能跑出什么

很多同学拿到「基于SpringBoot+Vue的校园交友网站源码」这类项目,第一反应是解压、改端口、npm run dev,然后发现登录接口 404、图片上传报跨域、打包后刷新页面直接白屏。问题不在源码本身,而在于没搞清楚这套前后端分离架构里,哪些是业务代码、哪些是脚手架约定、哪些是环境配置。校园交友网站的核心链路其实就四条:注册登录、资料展示、匹配推荐、私信互动,剩下的都是围绕这四条做的权限、上传、分页和状态管理。SpringBoot 负责把 MySQL 里的用户、动态、消息表暴露成 REST 接口,Vue 负责把这些接口渲染成可交互的页面。适合谁看?适合手里已经有一份源码、想把它跑起来并改造成自己毕设或课程设计的人,也适合想理解前后端分离项目完整落地路径的初学者。下面按「先跑通、再拆解、后避坑」的顺序讲,每一步都给出可复现的命令和参数。

2. 把源码跑起来:从数据库建表到前后端联调的最小闭环

2.1 环境版本对齐:JDK、Node、MySQL 三个不能错的地方

拿到源码先别急着改代码,先把版本对齐。SpringBoot 项目对 JDK 版本敏感,springboot版本太高是热搜里高频出现的问题,根源往往是源码用 JDK 8 编译,你本地却用 JDK 17 跑,导致javax包找不到。常见做法是看pom.xml里的<java.version>标签,它写 1.8 你就装 JDK 8,写 17 就装 JDK 17。Node 这边同理,Vue 2 项目用 Node 16 比较稳,Vue 3 项目可以上 Node 18,vue安装及环境配置踩坑最多的地方就是 Node 版本和node-sass不兼容。

组件推荐版本检查命令常见报错
JDK8 或 17java -versionNoClassDefFoundError
Maven3.6+mvn -v依赖下载超时
Node16 或 18node -vnode-sass编译失败
MySQL5.7 或 8.0mysql --version时区、驱动类名不一致

数据库这块,MySQL 8.0 的驱动类名是com.mysql.cj.jdbc.Driver,5.7 是com.mysql.jdbc.Driver,源码里写错一个字母就连不上。连接串里还要加serverTimezone=Asia/Shanghai,否则插入时间字段会差 8 小时。

2.2 建库建表与配置修改:三处必须改的配置项

源码一般会带一个sql文件夹,里面是建表语句和初始数据。先建库再导入:

# 登录 MySQL 并创建数据库,字符集用 utf8mb4 支持 emoji mysql -u root -p CREATE DATABASE campus_friend DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE campus_friend; SOURCE /path/to/source/sql/campus_friend.sql;

导入完成后,去后端src/main/resources/application.yml改三处:数据库账号密码、数据库名、文件上传路径。文件上传路径建议用绝对路径,比如D:/campus/upload/,用相对路径在打包成 jar 后容易找不到目录。

spring: datasource: url: jdbc:mysql://localhost:3306/campus_friend?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver servlet: multipart: max-file-size: 10MB # 单文件上限,头像够用 max-request-size: 20MB # 单次请求上限 file: upload-path: D:/campus/upload/ # 绝对路径,避免 jar 运行找不到

max-file-size和max-request-size要一起改,只改前者上传大图仍会失败。upload-path末尾必须带斜杠,否则拼接文件名时会少一个分隔符。

2.3 前端依赖安装与接口代理:解决跨域和 404

前端目录一般叫vue-front或web,进去先装依赖。如果npm install卡在node-sass,换成npm install --registry=https://registry.npmmirror.com再试。装完看vue.config.js或vite.config.js里的代理配置,这是前后端联调的关键。

// vue.config.js 里的 devServer 代理配置 module.exports = { devServer: { port: 8081, proxy: { '/api': { // 所有以 /api 开头的请求转发给后端 target: 'http://localhost:8080', // 后端实际地址 changeOrigin: true, // 允许跨域 pathRewrite: { '^/api': '' } // 去掉 /api 前缀再转发 } } } }

pathRewrite要不要写,取决于后端接口有没有/api前缀。后端 Controller 写的是@RequestMapping("/user"),前端请求/api/user/login,就必须把/api去掉。如果后端本身就有/api,那这行删掉。改完重启npm run serve,浏览器 F12 看 Network,请求地址变成http://localhost:8080/user/login就说明代理生效了。

3. 拆解核心模块:注册登录、资料展示、匹配推荐怎么落地

3.1 注册登录:JWT 令牌怎么发、怎么存、怎么校验

校园交友网站的登录不能用 Session,因为前后端分离后跨域携带 Cookie 很麻烦。常见做法是 JWT:后端校验账号密码通过后,用密钥签一个 token 返回,前端存 localStorage,后续请求放在请求头Authorization里。后端写一个拦截器统一校验。

// JWT 工具类核心方法,密钥从配置文件读,不要硬编码 public class JwtUtil { private static final String SECRET = "campus-friend-secret-key-2024"; private static final long EXPIRE = 7 * 24 * 60 * 60 * 1000L; // 7天 public static String createToken(Long userId) { return Jwts.builder() .setSubject(String.valueOf(userId)) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + EXPIRE)) .signWith(SignatureAlgorithm.HS256, SECRET) .compact(); } public static Long parseToken(String token) { Claims claims = Jwts.parser() .setSigningKey(SECRET) .parseClaimsJws(token) .getBody(); return Long.valueOf(claims.getSubject()); } }

SECRET长度要够,HS256 要求密钥至少 256 位,太短会抛WeakKeyException。EXPIRE设 7 天是校园项目的常见值,太长不安全,太短用户老要重新登录。拦截器里从request.getHeader("Authorization")取 token,解析失败就返回 401,前端收到 401 统一跳登录页。

3.2 资料展示与图片上传:静态资源映射的两种写法

用户头像、动态配图上传后要能访问,SpringBoot 需要把上传目录映射成静态资源路径。有两种写法,推荐第二种,因为打包成 jar 后仍然有效。

@Configuration public class WebConfig implements WebMvcConfigurer { @Value("${file.upload-path}") private String uploadPath; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // 访问 /upload/xxx.jpg 时,去本地磁盘 uploadPath 找 registry.addResourceHandler("/upload/**") .addResourceLocations("file:" + uploadPath); } }

addResourceLocations里的file:前缀不能少,少了会当成 classpath 路径去找。上传接口用MultipartFile接收,存盘时用 UUID 重命名避免同名覆盖,返回给前端的 URL 拼成/upload/文件名。前端<img :src="baseUrl + user.avatar">就能显示。

3.3 匹配推荐:用标签交集做最小可用版本

校园交友的匹配逻辑,源码里常见的是按性别、年级、兴趣标签做筛选。最简版本是标签交集排序:用户注册时选若干兴趣标签,推荐时算两个用户标签的交集数量,交集越多排越前。

-- 查询与当前用户标签交集最多的前 10 个用户 SELECT u.id, u.nickname, u.avatar, COUNT(*) AS match_score FROM user_tag ut1 JOIN user_tag ut2 ON ut1.tag_id = ut2.tag_id AND ut2.user_id != #{userId} JOIN user u ON u.id = ut2.user_id WHERE ut1.user_id = #{userId} AND u.gender != #{myGender} -- 按需过滤性别 GROUP BY u.id ORDER BY match_score DESC LIMIT 10;

match_score就是交集标签数,直接当匹配度展示。如果数据量上万,这个查询会慢,可以在user_tag表的user_id和tag_id上各建一个索引。更复杂的协同过滤不是校园项目该上的,标签交集够用且可解释。

4. 避坑与排查:源码跑不起来时先查这五条

4.1 启动报Table 'xxx' doesn't exist

现象:后端启动成功但调接口报 500,日志里说表不存在。原因:SQL 文件没导入完整,或者导入到了错误的数据库。解决:USE campus_friend;后再SHOW TABLES;确认表都在,缺哪张补哪张。注意 SQL 文件里如果有CREATE DATABASE语句,可能建了另一个库名,和application.yml里配的不一致。

4.2 前端请求全部 404 或跨域报错

现象:浏览器控制台报Access-Control-Allow-Origin或所有接口 404。原因:代理没配或配错,或者后端没启动。解决:先确认后端 8080 端口能访问,再检查vue.config.js的target地址和pathRewrite。如果后端加了@CrossOrigin注解,代理和注解二选一即可,同时用反而可能冲突。

4.3 图片上传成功但访问 404

现象:上传接口返回成功,数据库也存了路径,但<img>显示裂图。原因:静态资源映射没配,或者映射路径和返回的 URL 对不上。解决:确认addResourceHandlers里addResourceLocations的路径和file.upload-path一致,且末尾有斜杠。返回的 URL 如果是/upload/xxx.jpg,映射的 handler 必须是/upload/**。

4.4 打包后刷新页面白屏

现象:npm run build后放进 SpringBoot 的static目录,首页能开,刷新或直接访问子路由就 404。原因:Vue 是单页应用,路由由前端控制,服务器找不到对应路径的文件。解决:后端加一个兜底配置,把所有非 API 请求转发到index.html。

@Controller public class IndexController { @RequestMapping(value = "/{path:[^\\.]*}") public String forward() { return "forward:/index.html"; // 非静态资源请求全部回首页 } }

正则[^\\.]*表示路径里不含点,这样.js、.css请求不会被拦截。如果前端路由带了多级路径,正则要相应调整。

4.5 中文乱码或 emoji 存不进去

现象:昵称、动态内容里的中文变成问号,emoji 直接报错。原因:数据库字符集不是utf8mb4,或者连接串没指定编码。解决:建库时用utf8mb4,连接串加characterEncoding=utf8,MySQL 8.0 还要确认my.ini里character-set-server=utf8mb4。已经建好的库可以用ALTER DATABASE campus_friend CHARACTER SET utf8mb4;补救,但已有数据可能已经损坏。

5. 从能跑到好用:三个让源码变成自己项目的改造技巧

5.1 把硬编码的匹配规则抽成配置

源码里的匹配逻辑往往写死在 Service 里,性别、年级、标签权重都是魔法数字。改造第一步是把这些抽到application.yml,改需求不用动代码。

match: same-school-weight: 30 # 同校加分 same-grade-weight: 20 # 同年级加分 tag-intersect-weight: 10 # 每个共同标签加分 max-recommend: 20 # 推荐列表上限

Service 里用@Value注入,算分时按权重累加。这样答辩时被问「匹配规则怎么调」,你改配置重启就行,不用现场翻代码。

5.2 用分页插件统一列表接口

动态流、用户列表、消息列表都要分页,每个接口手写LIMIT容易漏。引入 MyBatis-Plus 的分页插件,一个配置类搞定。

@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }

Service 里用Page<User> page = new Page<>(pageNum, pageSize);再调mapper.selectPage(page, wrapper),返回结果自带total、pages,前端直接渲染分页组件。注意pageNum从 1 开始,不是 0。

5.3 加一个接口文档和健康检查

改造完接口,用 Knife4j 或 SpringDoc 生成在线文档,方便自己测也方便别人对接。再加一个/health接口返回数据库连接状态,部署后第一时间能确认服务活着。

@RestController public class HealthController { @Autowired private DataSource dataSource; @GetMapping("/health") public Map<String, Object> health() { Map<String, Object> result = new HashMap<>(); try (Connection conn = dataSource.getConnection()) { result.put("status", "UP"); result.put("database", conn.getCatalog()); } catch (Exception e) { result.put("status", "DOWN"); result.put("error", e.getMessage()); } return result; } }

这个接口不鉴权,放在拦截器白名单里。部署到服务器后curl http://localhost:8080/health返回UP就说明数据库通了。

我自己的习惯是,拿到任何一份源码,先不改业务代码,而是把/health和接口文档加上,再跑一遍所有接口。这样后面改出问题,能立刻分清是环境问题还是代码问题。校园交友网站源码的价值不在代码本身,而在于它提供了一个完整的前后端分离骨架,你把匹配规则、分页、文档这三块补上,它就能变成你自己的项目。希望帮到你。

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

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

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

立即咨询