SpringBoot+Vue音乐网站实战:数据库设计到前后端联调全解析
发布时间:2026/9/26 11:42:01来源:尧图网络
每年这个时候计算机专业的朋友们就开始为毕业设计发愁了。音乐网站系统算是Java Web方向最经典的题目之一乍一看到处都是但真正能跑通、能讲清楚原理、能过答辩的项目其实不多。我前阵子刚帮人完整梳理过一套基于SpringBoot Vue的音乐网站项目的代码从数据库设计到前后端联调一步步走了一遍在这里把整套思路和实操经验完整整理出来希望对正在做类似毕设或者想学全栈开发的朋友有点实际帮助。这套系统的核心就是两条线后端用SpringBoot做接口服务前端用Vue做页面交互中间通过RESTful API通信数据落在MySQL里。用户能注册登录、浏览歌曲、搜索歌手、管理歌单、收藏音乐、在线播放管理员可以维护歌曲、歌手、封面、歌词等基础数据。功能不算花哨但麻雀虽小五脏俱全正好覆盖了一个网站系统该有的核心链路用户体系、资源管理、关联关系、文件上传、前端路由与状态管理。1. 项目定位与模块拆解1.1 这套系统到底在做什么先说清楚它要解决什么问题。音乐网站本质上是一个内容管理 用户互动的系统。你可以把它拆成两个视角来看普通用户希望快速找到想听的歌、建自己的歌单管理员希望方便地录入歌曲信息、管理歌手、控制上传的文件。所以项目的功能边界大概是这样的用户端注册登录、浏览歌手和歌曲、搜索、创建歌单、收藏歌曲、听歌实际上就是HTML5的audio播放、写评论。管理端歌曲CRUD、歌手CRUD、歌单管理、用户管理通常只做到禁用或重置密码。至于要不要做成后台管理界面大部分毕设是分开做的也就是前台展示用Vue后台管理用另一个Vue页面或同一套系统的不同路由。我见过不少参考项目把管理端做成admin子应用这样职责清晰答辩的时候也好讲。1.2 技术选型背后的逻辑有人问为什么这类题目几乎都选SpringBoot Vue其实答案很实际。后端用SpringBoot而不是SSH、SSM是因为它在极大程度上省掉了繁琐的XML配置。我记得以前用SSM搭一个项目光配置文件就要写四五份什么spring-mvc.xml、mybatis-config.xml、web.xml光应付这些就能耗掉一个新手两周时间。SpringBoot用自动配置和起步依赖把配置量压到了极低让我们能把精力放在业务代码上。对于毕设周期来说这是绝对优势。前端选Vue而不是React是因为Vue的上手曲线平缓模板语法直观还有Element UI这一整套现成的组件库页面做出来不至于太难看。Vue的生态在面对这种管理系统类型的项目时效率确实高。数据库必然用MySQL免费、资料多、各种工具链成熟遇到问题一搜就有答案。ORM层面我推荐用MyBatis-Plus不是因为别的就是因为它自带CRUD方法不用写一堆重复的Mapper XML对赶进度的人非常友好。1.3 角色权限与模块划分这个系统我建议分成三种角色虽然很多参考代码只做用户和管理员但把“普通用户”和“管理员”严格分开会更好角色能做什么游客看首页、看榜单、搜索、听歌部分项目允许注册用户收藏、评论、建歌单、管理自己的歌单管理员维护歌曲歌手数据、管理用户、上传文件权限控制这块后端用拦截器 JWT前端用路由守卫两个地方都要做不能只靠前端隐藏按钮来“假装”有权限。2. 数据库设计先想清楚数据怎么落地数据库是这类系统最不能糊弄的部分。我见过很多毕设代码表结构混乱字段含义不清关联查询也写不明白答辩的时候被老师一问就露馅。这里把我的表设计思路完整列出来。2.1 六张核心表结构一个音乐网站最核心的表我认为有六张用户表、歌手表、歌曲表、歌单表、歌单歌曲关联表、收藏表、评论表如果用心做评论表也加上。下面逐个拆解。用户表CREATE TABLE user ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL COMMENT 登录账号, password varchar(255) NOT NULL COMMENT 密码BCrypt加密, nickname varchar(50) DEFAULT NULL COMMENT 昵称, avatar varchar(255) DEFAULT NULL COMMENT 头像地址, email varchar(100) DEFAULT NULL COMMENT 邮箱, role tinyint(1) NOT NULL DEFAULT 1 COMMENT 1普通用户 2管理员, status tinyint(1) NOT NULL DEFAULT 1 COMMENT 1正常 0禁用, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这里特别提醒几个字段的用意role用于区分用户和管理员status用于管理员禁用违规账号password字段长度留255是因为BCrypt加密后的字符串超过50位用长度50的字段会存不进去。歌手表和歌曲表CREATE TABLE singer ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL COMMENT 歌手名, avatar varchar(255) DEFAULT NULL COMMENT 歌手头像, introduction text COMMENT 歌手简介, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE song ( id int(11) NOT NULL AUTO_INCREMENT, singer_id int(11) NOT NULL COMMENT 歌手ID, name varchar(100) NOT NULL COMMENT 歌曲名, album varchar(100) DEFAULT NULL COMMENT 专辑名, url varchar(255) NOT NULL COMMENT 音频文件地址, cover varchar(255) DEFAULT NULL COMMENT 封面图地址, lyric text COMMENT 歌词, duration int(11) DEFAULT 0 COMMENT 时长秒, play_count int(11) DEFAULT 0 COMMENT 播放次数, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;歌曲表里有一个play_count字段很多人的代码里根本没用到但排行榜功能就靠它。虽然真正的大型音乐平台会引入Redis来计数但毕设用MySQL直接UPDATE就能应付页面按播放次数倒序排列即可。歌单、关联、收藏、评论表CREATE TABLE song_list ( id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL COMMENT 创建者ID, title varchar(100) NOT NULL COMMENT 歌单标题, cover varchar(255) DEFAULT NULL, description varchar(500) DEFAULT NULL, play_count int(11) DEFAULT 0, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE song_list_song ( id int(11) NOT NULL AUTO_INCREMENT, song_list_id int(11) NOT NULL, song_id int(11) NOT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE favorite ( id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL, song_id int(11) NOT NULL, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_user_song (user_id, song_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE comment ( id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL, song_id int(11) NOT NULL, content varchar(500) NOT NULL, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这里有两个设计细节值得注意song_list_song是典型的关联表用来实现歌单和歌曲的多对多关系前端传一个歌单ID和歌曲ID数组后端就是对这个表做批量插入和批量删除favorite表加了一个联合唯一索引uk_user_song防止同一个用户重复收藏同一首歌这个约束在数据库层面做最稳妥比在Java代码里先查再判断靠谱得多。2.2 表关系与业务联动表之间的关系画在脑子里是这样的user一端连着song_list、favorite、commentsinger是一方song是多方song又通过song_list_song关联到song_list。查询的时候最复杂的SQL也就是两三张表联查。我一个同事当初在歌单详情接口上卡了两天其实就是没有想清楚关联表。后来逻辑理清了就很简单查歌单基本信息一张表通过song_list_song查出song_id列表再用IN语句查歌曲信息外加LEFT JOIN查出歌手的名字。SQL长这样SELECT s.id, s.name, s.album, s.url, s.cover, s.duration, sg.name AS singer_name FROM song s LEFT JOIN singer sg ON s.singer_id sg.id WHERE s.id IN (SELECT song_id FROM song_list_song WHERE song_list_id #{songListId})用子查询而不是三表JOIN可读性高也方便后面分页。2.3 初始化数据怎么准备初始化数据也有讲究。第一至少准备10个以上歌手、50首以上歌曲数据太少页面看着空旷第二歌曲文件和封面图注意版权和质量毕设展示尽量用自己录制或版权开放的素材不要在论文和PPT里放明显有版权争议的商用歌曲截图第三默认管理员账号要固定一个比如admin / 123456初始化SQL里直接用BCrypt加密后的密码字符串写入方便后端启动后直接登录。3. 后端SpringBoot实现的核心模块3.1 项目结构与分层策略这套系统的后端项目结构我建议严格按照标准Maven结构来组织包名按业务分层com.example.music ├── controller # 接口层 ├── service # 业务层 │ └── impl ├── mapper # MyBatis-Plus持久层 ├── entity # 实体类 ├── dto # 请求/响应对象 ├── config # 配置类如CORS拦截器 ├── common # 统一返回结果、异常处理 └── utils # JWT、文件上传工具为什么要分层因为答辩的时候老师一定会问“你项目的架构是什么样的”。能清楚讲出Controller只接收参数、Service处理业务逻辑、Mapper负责数据库交互这种基础的三层架构认知在老师眼里就算合格了。很多C盘代码全堆在Controller里200行一个方法虽然能跑但一被追问就露馅了。3.2 JWT登录鉴权实现登录鉴权是每个系统都绕不开的核心。现在基本不用Session了主流做法是JWT。流程是这样的用户提交用户名密码 - 后端校验 - 生成Token返回前端 - 前端存到localStorage - 每次请求带在Header里 - 后端拦截器解析Token并放行。JWT工具类里需要三样东西密钥、过期时间、生成和解析的方法。代码如下Component public class JwtUtil { Value(${jwt.secret}) private String secret; Value(${jwt.expire}) private Long expire; public String generateToken(Long userId, String username, Integer role) { return Jwts.builder() .setSubject(username) .claim(userId, userId) .claim(role, role) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() expire)) .signWith(SignatureAlgorithm.HS256, secret) .compact(); } public Claims parseToken(String token) { return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); } }配置文件里我用的密钥是一个足够长的随机字符串过期时间设为24小时。实际开发中密钥要放在配置里不要写死在代码中。拦截器里对所有需要登录的接口做校验注意两个坑一是放行登录注册接口和静态资源二是对管理员接口额外校验role字段。拦截器的写法是在SpringBoot里实现HandlerInterceptor接口然后在WebMvcConfigurer中注册并指定拦截路径。核心逻辑就是获取Header里的Authorization去掉Bearer 前缀解析Token成功就放行并把用户信息存入ThreadLocal或者request的attribute中方便后续业务取当前用户ID。3.3 歌曲管理、上传与播放统计歌曲和歌手的增删改查用MyBatis-Plus的IService接口就顺手完成了。真正要用心的是文件上传。毕设里歌曲文件、封面图都是通过上传接口保存的。上传路径我踩过一个很典型的坑用绝对路径保存导致换一台电脑运行就找不到文件。正确的姿势是在配置文件中定义一个上传根目录应用启动时确保目录存在然后把文件保存进去同时把访问路径映射成静态资源。SpringBoot配置里加一行Configuration public class WebConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/files/**) .addResourceHandler(file: uploadPath /); } }这样上传后的文件对外访问路径就是http://localhost:8080/files/xxx.mp3前端直接拼URL就能用。播放次数统计也不复杂在播放接口里对play_count做自增更新但这要控制频率。我见过实现比较简单的情况每次点播放都调一个计数接口。对毕设来说完全够用但对生产来说肯定不行答辩时如果有人问就说可以引入Redis做缓存计数、定时刷入数据库这个回答可以显示你有进阶思考。3.4 歌单、收藏与评论的接口设计这类接口的关键是搞清楚返回结构。我整理一下常见的端点方法路径说明GET/api/song/list歌曲列表支持关键词搜索、分页GET/api/song/detail/{id}歌曲详情含歌手名POST/api/song新增歌曲管理员PUT/api/song修改歌曲管理员DELETE/api/song/{id}删除歌曲管理员GET/api/songList歌单列表POST/api/songList创建歌单登录POST/api/songList/{id}/songs歌单添加歌曲DELETE/api/songList/{id}/songs/{songId}歌单移除歌曲POST/api/favorite收藏歌曲DELETE/api/favorite/{songId}取消收藏POST/api/comment发布评论接口路径要有语义统一返回结构。我定义一个ResultT类里面放code、message、data三个字段成功code是200失败是500未登录是401这样前端axios拦截器可以统一处理错误提示而不是每个请求单独写一遍。3.5 统一返回、异常处理与跨域配置写接口时最忌讳每个方法返回类型五花八门有的返回Map有的直接返回实体。老老实实统一用Result包装。异常处理用RestControllerAdvice做全局异常捕获业务异常抛自定义的BusinessException系统异常统一返回500并记录日志。跨域配置是前后端分离项目必配的。用CorsFilter注册一个Bean允许的前端端口是http://localhost:5173Vite默认或http://localhost:8081Vue CLI默认允许的Header里必须包含Authorization否则前端带的Token会被浏览器拦截。4. 前端Vue页面与交互实现4.1 项目搭建与目录划分前端我建议用Vue CLI或Vite创建项目UI组件库用Element UI。如果你是Vue 3项目对应版本是Element Plus如果是Vue 2项目就用Element UI老版本。两者写法略有差异但整体思路一样。我这里的示例以Vue 2 Element UI为主因为它资料最多踩坑也好查。前端目录结构参考src ├── api # 接口封装 ├── assets # 静态资源 ├── components # 通用组件如播放条 ├── router # 路由配置 ├── store # Vuex状态管理 ├── views # 页面组件 ├── utils # 工具类如axios封装 └── App.vue4.2 路由设计与登录守卫路由配置要预设好页面。常见页面有首页推荐位 热门歌单、歌手列表、歌手详情、歌曲搜索、歌单详情、个人信息页、后台管理页。这里我特别说明一个点播放页到底要不要单独一个路由。我的做法是不单独开页面而是做一个全局固定的底部播放条组件全局只有一个audio元素。这样切换页面音乐不会中断用户体验也舒服。这个组件的逻辑是点击任何歌曲时把歌曲信息提交到Vuex底部播放条监听Vuex状态变化然后设置audio的src并播放。路由守卫负责登录校验router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.meta.requiresAuth !token) { next(/login) } else if (to.meta.role to.meta.role ! store.state.user.role) { next(/) } else { next() } })这里要提一个容易忽略的细节刷新页面时Vuex数据会丢失所以用户信息要同时存一份到localStorage页面初始化时再从localStorage恢复。否则用户登录后一刷新页面就不知道当前用户是谁了很多人的毕设都有这个bug。4.3 axios封装与接口对接axios封装的核心是请求拦截器加Token、响应拦截器处理错误码。登录接口返回的Token存在localStorage里请求拦截器每次把Token塞进Header。响应拦截器如果拿到401就清除本地登录信息并跳转登录页。import axios from axios import { Message } from element-ui import router from /router const service axios.create({ baseURL: /api, timeout: 10000 }) service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization Bearer ${token} } return config }) service.interceptors.response.use( response { const res response.data if (res.code 401) { localStorage.clear() router.push(/login) } return res }, error { Message.error(error.message || 请求失败) return Promise.reject(error) } ) export default service注意baseURL这里用的是/api开发环境下需要在Vue CLI的vue.config.js里配代理转发把/api开头请求转发到8080端口。这是前端遇到跨域问题的最简解法比后端配CORS还省事。4.4 播放器组件的核心逻辑播放条算是这个项目前端最有含金量的组件。核心代码并不复杂但逻辑要理清楚audio是HTML元素Vue通过ref拿到它然后监听Vuex中的当前歌曲变化更新audio的src并调用play方法。播放/暂停按钮控制audio的play和pause进度条更新时监听timeupdate事件拖动进度条时修改currentTime音量控制同理。template div classplayer-bar audio refaudioRef :srccurrentSong.url/audio div classsong-info img :srccurrentSong.cover alt div p{{ currentSong.name }}/p span{{ currentSong.singerName }}/span /div /div div classcontrols i classel-icon-video-pause v-ifisPlaying clickpause/i i classel-icon-video-play v-else clickplay/i span{{ formatTime(currentTime) }}/span el-slider :maxduration v-modelcurrentTime changeseek/el-slider span{{ formatTime(duration) }}/span /div /div /template这里有几个常见的坑audio的src一旦变化要重新load才能生效歌曲可能因为CORS问题不能播放这就需要后端对音频接口也放行播放失败时要catch住Promise否则会在控制台刷一堆Uncaught的错误。还有一个体验细节el-slider在拖动过程中频繁更新currentTime会卡顿正确的做法是拖动时只更新本地临时值松手时才写audio的currentTime。另外歌词展示很多人忽略。其实很简单歌词格式是LRC解析成正则匹配时间戳的数组audio的timeupdate事件里去匹配当前时间对应的歌词行。算是一个加分项写出来效果很好。4.5 页面渲染与交互细节页面渲染用Element UI的列表组件很顺手。首页的推荐位用一个轮播图组件展示专辑封面歌单卡片用row和col布局实现栅格排列歌单详情页用表格展示歌曲列表每行有一个播放按钮点击调用Vuex的setCurrentSong提交歌曲信息。搜索功能建议做防抖用户在输入框打字时不要每敲一个字符都请求一次接口用setTimeout和clearTimeout把请求频率降下来或者简单点用el-input的keyup.enter触发搜索。虽然毕设不要求高并发性能但写防抖在答辩中是个加分细节可以表示你不是完全没考虑过性能。5. 本地跑通全套代码的完整步骤拿到这套源码很多人第一步就卡住。SpringBoot版本不匹配、Node版本太高、Maven依赖下载不下来这些坑我都见过。下面按顺序走一遍。5.1 环境准备与版本检查建议环境版本固定为JDK 1.8如果用的是SpringBoot 2.x或 JDK 17SpringBoot 3.xMaven 3.6Node.js 16.xVue 2项目用太新的Node会报OpenSSL错误MySQL 5.7或8.0这里最需要注意的就是Node版本。用Vue CLI创建的老项目在Node 17以上版本运行npm run serve时会报ERR_OSSL_EVP_UNSUPPORTED原因就是Webpack 4依赖的OpenSSL算法在新版Node里被禁用了。解决办法是装Node 16或者在package.json的scripts里加NODE_OPTIONS--openssl-legacy-provider但加参数的方式在Windows上还有兼容问题不如直接切Node版本省心。JDK版本同理。SpringBoot 2.x在JDK 17下虽然能跑但一些旧依赖会有兼容问题稳妥起见用JDK 8。5.2 引入数据库初始化脚本先在MySQL里建一个库名字可以叫music_db字符集utf8mb4排序规则utf8mb4_general_ci。然后执行项目里的sql脚本。如果脚本里没有管理员账号的密码需要自己手动用BCrypt工具生成一段密文插入。这个工具可以自己写个main方法调SpringSecurity的BCrypt也可以直接用网上的在线工具注意生成后核对前缀是$2a$开头即可。数据导入后可以在服务器上直接用SQL查一下关键表的行数确认singer、song、user三张表都有数据避免启动后端后前端页面一片空白。5.3 后端启动与常见启动问题后端启动的步骤在IntelliJ IDEA中打开pom.xml所在的目录等待Maven加载依赖第一次下载依赖耗时较长然后修改application.yml里的数据库连接配置spring: datasource: url: jdbc:mysql://localhost:3306/music_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你的密码 servlet: multipart: max-file-size: 100MB max-request-size: 100MB jwt: secret: 一个足够长的随机字符串 expire: 86400000启动时最常遇到的报错是时区问题一般表现为serverTimezone相关SQL异常记得在连接串上追加serverTimezoneAsia/Shanghai。如果提示数据库连接失败先用Navicat测试本地连接排除账号密码错误和MySQL服务没启动的问题。如果Maven依赖下载缓慢可以换阿里云镜像这个在settings.xml里配置属于常规操作了。启动成功后后端默认端口8080在浏览器访问http://localhost:8080/api/song/list如果返回JSON数据说明后端正常。5.4 前端启动与代理配置在前面代码部分提过前端开发环境配的是代理所以vue.config.js里这样写module.exports { devServer: { port: 5173, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }这样一个代理就解决了跨域问题前端里所有的请求路径都以/api开头实际上被转发到了后端。changeOrigin必须设置为true否则后端可能会因为Host头对不上而拒绝请求。启动时如果提示node_modules不存在先执行npm install。这个过程可能遇到警告found 100 vulnerabilities不用慌这是依赖版本的安全提示对本地开发运行没实际影响。安装完成后执行npm run serve看到Compiled successfully提示后打开浏览器访问即可。5.5 功能验证清单系统跑起来后按这个清单快速过一遍注册一个新账号确认能登录、能跳转。用管理员账号登录添加一首歌确认歌曲列表能看到、能播放。普通用户收藏歌曲去个人中心确认收藏列表有数据。创建一个歌单往歌单里加几首歌再提交时刷新页面确认数据持久化了。搜索一个不存在的关键词确认返回空列表且不报错。每一步都走通基本上功能就齐了。后端的SQL日志可以在application.yml里配置mybatis-plus.configuration.log-impl: org.apache.ibatis.logging.stdout.StdOutImpl这样控制台会打印SQL排查问题非常有用。6. 常见问题与排查技巧实录6.1 前端请求被拦截页面报跨域错误这个是我看到最多的问题。报错特点明显浏览器控制台出现Access-Control-Allow-Origin相关字样Network面板里请求显示为CORS error。解决策略分两个方向一是前端配proxy代理二是后端配CorsFilter。如果你已经配了proxy还报错检查是不是直接把axios的baseURL写成了http://localhost:8080绕过了代理。前端如果配了代理请求路径必须写相对路径/api/xxx而不是完整的后端地址。6.2 请求401或403Token没带上Token的传递链路是这样的登录接口返回Token - 前端存到localStorage - 下次请求时在拦截器里取出来放Header。常见问题有两个一是localStorage的key写错了存的时候叫token取的时候写成了Token二是后端拦截器放行的路径写错把需要登录的接口也放行了导致接口拿不到当前用户信息返回空指针。调试技巧在浏览器F12的Network里看请求头确认有没有Authorization字段没有就是前端问题有但后端还不认就是后端解析逻辑问题。6.3 图片和音频上传成功但访问404这个问题的根因几乎永远是路径映射没配好。文件保存到了本地磁盘的某个目录但SpringBoot没有把这个目录映射成静态资源路径前端访问/files/xxx.jpg自然404。解决办法参考前面WebConfig代码把uploadPath和/files/**正确对应上。另外一个坑是文件保存时用了绝对路径拼接Windows下路径分隔符是\Linux下是/在网页URL里只能用/。保存数据库的时候一定统一存储为相对路径例如/files/20240101/xxx.jpg。6.4 音频跨域导致无法播放音频地址和后端接口不在同一个域时audio元素的请求会被浏览器拦截控制台报跨域错误。如果前端用了proxy而后端又配了CORS要注意两边的Header是否冲突。更稳妥的做法是后端对/files/**的静态资源也设置跨域允许用addCorsMappings在资源映射里同时配置或者直接用http.cors()配置全局。还有一个容易忽略的点音频请求有时不经过axios是audio自己发起的所以axios里配的Header不会带上去后端如果对音频接口要求鉴权就会返回401导致播放失败。我的处理是音频接口不做强制鉴权或者用签名URL的方式但对于毕设直接放行最省事。6.5 MyBatis-Plus分页不生效用了分页插件后如果发现分页没生效返回的还是全部数据八成是没配置分页拦截器。MyBatis-Plus在SpringBoot里要手动注册一个PaginationInterceptor3.4版本后叫MybatisPlusInterceptor遗漏这步的话Page参数会被当成普通参数忽略。检查一下配置类里有没有写这个Bean注意版本对应的类名。写到这里这套系统的核心链路算是完整走了一遍。我自己的体会是音乐网站这种题目虽然常见但想做得扎实并没那么容易。很多同学拿到一个源码就急着跑跑通了就认为万事大吉结果答辩时连“你的表结构是怎么设计的”都答不上来。既然这套代码里凝聚了前后端的完整知识链路与其背代码不如沉下心把每张表、每个接口、每条数据流都理清楚。这样到了答辩现场无论老师从哪条线追问你都能接得住。最后再分享一个小技巧把项目跑通后挑一个功能点做一次完整的“数据流讲解”练习例如从用户点击播放按钮到audio出声中间经历了哪些方法和接口把这个讲顺了整个项目你就真正吃透了。
网站建设高端定制企业官网