ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SpringBoot+Vue+MySQL前后端分离新闻资讯系统源码实操解析

2026/9/9 16:02:43 拓冰建站 浏览量
SpringBoot+Vue+MySQL前后端分离新闻资讯系统源码实操解析 市面上打着“可直接运行”旗号的新闻资讯系统源码很多但真正下载下来能一次跑通的其实不多。这套SpringBoot Vue MySQL的前后端分离项目算是我见过完成度比较高的从管理员发布新闻、分类管理到前端门户展示、用户浏览整个业务闭环是完整的而且没有那些花里胡哨的微服务架构就是最经典的单体后端加SPA前端特别适合用来学习主流Java后端技术栈也是毕业设计的高频选题。这篇文章我会从代码结构、核心业务实现、环境搭建到常见坑位排查把整套系统如何从零跑起来以及背后的设计逻辑拆开讲清楚。无论你是准备拿它来做课设、学习前后端分离开发模式还是想在上面二次开发接私活这篇应该都能帮你省掉不少时间。1. 内容整体设计与思路拆解1.1 这个项目解决了什么问题先说说这个系统本身。新闻资讯系统信息管理系统简单来说就是一个内容发布管理平台核心用户有两类一类是后台的管理员负责维护新闻栏目分类、发布文章、管理公告另一类是前台访客浏览新闻列表、查看新闻详情、按分类筛选内容。它的业务逻辑不复杂但胜在完整。从软件工程的教学角度看它覆盖了前后端分离开发的几乎所有关键环节RESTful API设计、数据库建模、权限拦截、跨域处理、前端路由守卫、组件化开发这些都能在代码里找到对应实现。相比那些只有增删改查的“玩具项目”这套系统明显更有诚意。从实用角度看这类系统在企业内部通知发布、中小型门户网站内容管理、甚至政务信息公开平台里都能找到影子。把它的代码吃透你做其他内容管理类系统的上手速度会快很多因为核心思路是通用的。1.2 技术选型背后的理由技术栈选SpringBoot Vue MySQL可以说是当前Java后端入门最务实的一套组合。SpringBoot能做到零XML配置启动Web服务内嵌Tomcat打一个jar包就能跑这比起早期SSH框架省了太多配置成本也符合现在微服务时代模块化开发的习惯。Vue作为前端框架响应式数据绑定和组件化开发能让你用很轻量的方式实现数据驱动页面更新配合Element UI这类组件库后台管理界面可以做得又快又好看。MySQL则是最经典的关系型数据库互联网公司中小型项目的主力资料多、社区活跃遇到问题基本都能搜到解决方案。这套组合的另一个好处是招聘市场需求量大。你会发现很多中小型公司的技术栈就是SpringBoot Vue MySQL会这套东西你至少具备了快速融入团队的基础能力。1.3 前后端分离模式的核心思想所谓前后端分离是指前端和后端各自独立开发、独立部署、通过HTTP接口通信。后端只负责业务逻辑和数据处理返回JSON格式数据给前端前端只负责页面渲染和用户交互通过Axios发起异步请求获取数据。项目里面SpringBoot后端默认跑在8080端口Vue前端开发服务器跑在5173Vite或8081Webpack之类的端口两者通过HTTP协议交互。这就必然会碰到跨域问题——浏览器的同源策略会拦截不同端口的请求。项目里常见的解决方案是后端加CORS配置类或在Controller上加CrossOrigin注解前端Vite配置proxy代理转发。后面实操部分我会详细说这个。当时我拿到这套源码第一件事就是把整个项目的目录结构过了一遍确认它是标准的前后端分离结构后才开始配置环境。我的建议是你拿任何项目之前都不要急着启动先把代码结构看清这样后面遇到问题才有的放矢。2. 核心细节解析与实操要点2.1 后端SpringBoot工程结构拆解后端源码的包结构分得很清楚。常见的是com.xxx.news下面拆controller、service、mapper、entity、config几个子包。Controller层负责接收前端请求和返回数据Service层处理业务逻辑Mapper层跟数据库打交道Entity层对应数据表结构Config层放置一些配置类比如跨域配置、拦截器配置。关键点在于Mapper层用了MyBatis还是MyBatis Plus。这两个差异挺大的。传统MyBatis需要手写XML映射文件表的字段变更后要同步修改XML里的resultMapMyBatis Plus则内置了通用的增删改查方法大部分简单操作不用写SQL。我看这套系统用的是MyBatis Plus的自动填充功能比如create_time、update_time这两个字段就是自动填充的不需要手动set值。实现自动填充的方式是定义一个MetaObjectHandler接口的实现类重写insertFill和updateFill方法在里面设置当前时间。代码大致是这样的Component public class MyMetaObjectHandler implements MetaObjectHandler { Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, createTime, LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, updateTime, LocalDateTime.class, LocalDateTime.now()); } Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, updateTime, LocalDateTime.class, LocalDateTime.now()); } }对应的实体类字段上需要加TableField(fill FieldFill.INSERT)和TableField(fill FieldFill.INSERT_UPDATE)注解。这就是为什么你往数据库插入数据的时候不需要手动传时间也能自动带上。还有一个容易忽略的点就是MyBatis Plus的分页插件需要手动配置不配置的话分页查询会查出全部数据。配置方式是新建一个MybatisPlusConfig配置类注册PaginationInnerInterceptor。你拿到源码后可以检查一下有没有这段配置没有的话要自己加上Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }2.2 前端Vue工程结构与页面流转前端部分用的是Vue全家桶。入口文件main.js里通过createApp(App)创建Vue实例同时全局注册了Element UI组件库、Pinia或Vuex状态管理、Vue Router路由。如果项目用的是Vue 3那大概率配的是Vite构建工具开发启动命令是npm run dev如果是Vue 2那用webpack命令是npm run serve。页面路由设计上一般分为两块面向游客的portal门户页面和面向管理员的后台管理页面。门户页面有首页新闻列表、新闻详情、分类浏览后台有登录页、控制台、新闻管理、分类管理等。这两类页面通过路由的元信息meta和导航守卫做访问控制比如后台页面要求必须带着token才能进入。前端组件化是这套代码的一个亮点。新闻列表、新闻卡片、分页组件、评论列表这些都被拆成了独立Vue组件通过props接收数据、通过emit向父组件抛事件。比如新闻详情页通常会引入一个CommentList组件评论提交成功后子组件把事件抛给父组件父组件重新拉取评论数据刷新列表。前端环境安装这块是很多人第一次跑项目的大坑。建议Node.js装16或18的LTS版本版本太高或太低都容易出依赖兼容问题。装好之后在项目根目录执行npm install安装依赖如果是在国内网络环境下记得先把npm源切换到淘宝镜像npm config set registry https://registry.npmmirror.com如果不换源node-sass这类依赖下载会卡到你怀疑人生。另外注意package.json里的依赖声明如果里面写着node-sass这玩意儿对Node版本非常敏感你要是Node版本过新构建会报错。遇到这种情况要么降Node版本要么把它改成sassdart-sass代码不用改构建就正常。2.3 数据库表设计与初始化数据库初始化脚本一般放在源码根目录下的sql文件夹里文件名叫init.sql或news.sql。导入之前你需要先在MySQL里建一个空数据库比如CREATE DATABASE news DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;然后再source导入脚本。表结构设计上核心的表至少有这几张用户表sys_user存管理员账号字段包括用户名、密码BCrypt加密后的密文、昵称、头像、状态等。密码加密方面SpringSecurity或Sa-Token框架一般内置BCryptPasswordEncoder加密后的密码形如$2a$10$......你直接用明文去数据库里对比肯定验不过。新闻资讯表news_info是核心业务表字段包括标题、摘要、正文内容、封面图URL、分类ID、作者、发布时间、状态草稿/已发布等。状态字段很关键前台页面查询时必须要过滤掉草稿状态只展示已发布内容。分类表news_category存新闻栏目比如国内新闻、国际新闻、科技新闻、体育新闻等通过sort字段控制排序。评论表news_comment记录用户对新闻的评论关联新闻ID和用户ID。这几张表之间通过外键逻辑关联但实际开发中很多人不会在数据库层面真建外键约束而是靠业务代码保证数据一致性因为外键对性能有影响而且在分布式场景下会带来麻烦。这套代码也是这个风格表之间用字段逻辑关联删除新闻时业务代码里手动把对应评论也删掉。2.4 后端跨域处理与安全配置跨域是个必聊的话题。开发模式下前端在5173端口后端在8080端口前端请求后端接口浏览器判定这属于跨域调用默认会拦截。这个项目里通常用两种方式解决。一种是在后端写一个CorsConfig类实现WebMvcConfigurer接口重写addCorsMappings方法允许所有来源访问Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }另一种是开发环境下前端Vite配置proxy代理原理是让前端开发服务器把/api开头的请求转发给后端浏览器看到的是同源请求就不存在跨域了。两种方案各有好处后端配置CORS适合前后端分开部署的生产环境前端代理只在开发模式下有效生产环境还是要靠后端放行。安全这块系统一般集成了Sa-Token或者SpringSecurity做登录认证和接口权限控制。以Sa-Token为例用户登录成功后拿到一个token后续请求在请求头里带上token后端通过拦截器解析token校验身份。后台管理接口需要管理员权限拦截器里判断当前登录用户的角色没有权限直接返回401。这个逻辑在拦截器配置类里可以看到通常是继承SaInterceptor或者实现HandlerInterceptor。3. 实操过程与核心环节实现3.1 环境准备清单提前把环境装好能省去后面80%的麻烦。先说版本我建议的搭配是这样的JDK用1.8或11都行但如果你用的SpringBoot版本是2.7以上建议JDK 11起步。SpringBoot 3.x要求JDK 17这个要注意看项目pom.xml里spring-boot-starter-parent的版本号。Maven用3.6以上版本IDEA里配置好仓库镜像到阿里云不然依赖下载会让你等到崩溃。MySQL建议装8.0版本5.7也可以但pom.xml里的mysql-connector-java版本要对应上。8.0版本的驱动类名是com.mysql.cj.jdbc.Driver5.7用com.mysql.jdbc.Driver驱动包版本不对会报ClassNotFoundException。Node.js装16.20.2这个版本最稳妥装完把npm源切到淘宝镜像。开发工具方面后端用IDEA前端可以用IDEA也可以VSCode数据库工具用Navicat或者IDEA自带的Database面板都行。3.2 后端启动完整步骤先把项目源码解压到一个没有中文和空格路径的目录里比如D:\projects\news-system。这个细节很多人不注意路径里有中文的话Maven打包偶尔会出奇怪的编码问题。用IDEA打开后端文件夹一般叫news-server或server打开后会提示你加载Maven项目等依赖下载完成。然后在src/main/resources/application.yml里修改数据库连接信息server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/news?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 你的数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver注意url里这些参数的含义useUnicodetrue和characterEncodingutf8保证中文不乱码serverTimezoneAsia/Shanghai指定时区不然连MySQL 8.0的时候会报时区错误useSSLfalse关掉SSL证书验证。启动前确保MySQL服务已启动、数据库已导入、账号密码正确。然后运行主启动类看到类似Started NewsApplication in x.x seconds的日志就说明后端起来了。验证方式很简单浏览器访问http://localhost:8080/能看到一段JSON说明SpringBoot正常返回访问http://localhost:8080/api/news/list这种实际接口能返回数据说明数据库连接也没问题。3.3 前端启动完整步骤前端文件夹一般叫news-ui或web。用IDEA或VSCode打开在终端执行npm install。这个过程时间长短取决于网络状况装完后执行npm run dev或npm run serve。如果启动成功终端会打印出本地访问地址通常是http://localhost:5173/。打开浏览器看到首页但这时候页面数据可能还是空的因为前端请求的接口地址还没配通。前端请求后端地址的配置一般在两个地方Vite的vite.config.js或vue.config.js里面的proxy配置以及src/utils/request.js里Axios的baseURL。开发模式下走代理是最省事的配置这样写// vite.config.js export default defineConfig({ server: { port: 5173, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })这样前端请求/api/news/list就会被代理转发到http://localhost:8080/api/news/list既解决跨域又保持代码里接口路径的相对一致性。3.4 从登录到数据流全链路走通整个系统能不能跑通最直观的验证方式就是走一遍完整的用户操作链路。我建议按这个顺序测试打开前台门户首页能看到新闻列表正常展示新闻封面图正常加载。点击一篇新闻进入详情页能看到正文内容和评论列表如果没登录就提交评论系统应该提示你先登录。进入后台登录页用源码里自带的管理员账号登录一般是admin/123456或admin/admin123具体看sql脚本里的初始化数据。登录成功后进入管理界面尝试发布一篇新新闻填标题、选分类、传封面图、写正文保存然后回到前台首页刷新能看到这篇新闻出现在列表里。这条链路走通说明你的前端路由、后端接口、数据库读写、文件上传存储全部正常。上传图片这里有个小知识点图片一般有两种存法一种是本地磁盘路径后端把文件保存到本地某个目录然后通过静态资源映射让前端能访问另一种是存OSS对象存储服务。这套源码大概率是本地存储配置文件里可能有个upload.path之类的参数图片上传后的访问路径是这个参数拼上文件名。注意如果上传图片后前端显示不出来多半是上传目录和静态资源映射没对上或者相对路径写死了localhost:8080你改过端口导致访问不到。4. 常见问题与排查技巧实录4.1 数据库连接相关报错数据库连接是报错重灾区。驱动类找不到大概率是依赖没下完整或者版本不对Access denied for user说明用户名密码错Unknown database说明数据库没建Communications link failure说明MySQL服务没启动或url里端口不对。这里特别说一下时区问题。很多人导入数据库后启动后端报这个错The server time zone value й׼ʱ is unrecognized or represents more than one time zone这就是在url里没加serverTimezoneAsia/Shanghai导致的。还有一种情况是mysql-connector-java的版本和MySQL服务器版本差太远5.x驱动连8.x数据库会有兼容警告建议驱动版本和数据库版本保持一致或略高。排查技巧不要光看报错最后一行往上翻异常堆栈找到Caused by那一行那才是根因。很多新手被一堆报错信息吓住其实Caused by一行就说明问题了。4.2 前端访问后端接口报404或500访问接口报404先确认后端那个接口路径是否跟前端请求路径完全一致。用浏览器的开发者工具看Network面板找到这条请求对照Controller里的RequestMapping路径。最容易出错的地方是漏了Context Path比如你在application.yml里配置了server.servlet.context-path: /news那么所有接口的访问路径都得加上这个前缀前端代理和目标地址都要对应改。报500则基本是后端代码执行出错看后端控制台或日志文件里的异常堆栈。常见的是SQL写错、字段类型映射不对、空指针这几种。如果是查询数据时报SQLSyntaxErrorException检查实体类字段名和数据表字段名是否一致MyBatis Plus的下划线转驼峰映射没有全局开启的话字段名对不上就会报错。4.3 前端依赖安装失败npm install时最常见的报错有几种node-sass安装失败、网络超时、依赖版本冲突。node-sass的问题前面说过改成sass就好网络问题换淘宝镜像或设置代理版本冲突一般出现在package-lock.json里锁定的版本跟你本机Node不兼容最简单的办法是把node_modules目录和package-lock.json删掉重新npm install。还有一个很隐蔽的问题是npm cache损坏安装到一半进程被杀掉容易导致缓存异常可以执行npm cache clean --force再重装。4.4 前端页面样式错乱或组件库不生效页面能渲染但样式不对常见原因是Element UI按需引入配置出问题或者全局样式覆盖了组件库样式。检查main.js里是否正确引入了Element Plus的样式文件。如果你用的是Element Plus全局引入就写import ElementPlus from element-plus import element-plus/dist/index.css如果是按需自动引入用unplugin-vue-components插件这个插件会在编译时自动把用到的组件和样式打包进去如果配置漏了样式转译那一步就会出现“组件功能正常但没样式”的情况。4.5 登录后token失效或登录状态丢失登录成功后跳转回登录页这通常有三个原因。第一后端返回的token没被前端正确保存检查登录接口拿到数据后是不是存到了localStorage或sessionStorage第二Axios请求拦截器里没把token塞进请求头后端校验不到token就会返回401第三路由守卫的判空逻辑有问题比如用responsive的方式判断token是否存在时用了错误的字段名。我建议你在浏览器开发者工具的Application面板里看一下localStorage里到底有没有token值有的话再看Network面板里接口请求的Headers里有没有Authorization字段。这样一段段排查很快能定位是哪一环断了。4.6 项目启动顺序与端口占用问题后端和前端有没有固定的启动顺序严格来说没有你想先起哪个都行反正两边是通过HTTP通信的你只要保证测试时两个服务都在运行就行。但我个人的习惯是先起后端因为前端页面上看一眼就要调接口后端起来了我好提前确认数据接口正常。端口被占用也是高频问题。启动前端时提示Port 5173 is in use说明有别的进程占了这个端口。Windows下用netstat -ano | findstr 5173查看占用进程PID然后taskkill /PID 进程号 /F杀掉也可以直接改vite.config.js里的端口配置。后端8080被占用同理改application.yml里的server.port即可但要注意前端代理target的端口也要同步改。4.7 数据库字符集设置中文乱码问题要是出现先别急着改代码大概率是数据库表结构的问题。建库用utf8mb4建表也要指定utf8mb4字符集连接url里加上characterEncodingutf8这三个地方全都对了才不会乱码。如果是已经导入的库出现乱码用ALTER TABLE xxx CONVERT TO CHARACTER SET utf8mb4;转换一下。区分utf8和utf8mb4是MySQL里的老生常谈。utf8在MySQL里最多3字节存emoji或生僻字就会失败报错utf8mb4是完整的Unicode实现4字节任何字符都能存。现在的项目一律建议utf8mb4别再用utf8了。5. 二次开发建议与进阶方向5.1 可以扩展的功能点这套系统跑通之后我建议你别停在“能运行”就完事了往里面加几个功能对理解项目的帮助会非常大。比如加一个浏览记录功能。同一IP或同一用户访问新闻详情时往浏览记录表里插入一条数据如果已存在则更新时间。这个功能看似简单实际要处理高并发下的重复插入问题、数据量大后的清理策略这些都很有实战价值。比如加一个新闻关键字搜索功能。最简单的方案是MySQL的LIKE模糊查询sql里写where title like concat(%, keyword, %)数据量小完全够用。数据量上来后可以优化为fulltext全文索引或者引入Elasticsearch但那是另一套架构了。再比如给新闻表加一个浏览量字段每次点击详情时1。这个方案在高并发下有性能问题你会接触到Redis原子自增、异步刷盘这些优化手段也是面试常问的场景。5.2 生产部署要考虑的问题如果要把这套系统部署到云服务器上有几个东西要改。前端需要执行npm run build打包生成dist目录里面是纯静态文件可以丢到Nginx的html目录里也可以用docker镜像里挂一个nginx容器来服务。后端打成可执行jar包用java -jar news.jar命令启动生产环境建议用systemd或supervisor托管保证进程崩溃后能自动拉起。数据库层面需要把数据库脚本导出在服务器上重新导入一遍同时修改后端配置文件里的数据库连接为服务器的MySQL地址。注意生产环境的跨域配置。前端部署到Nginx后浏览器访问的是Nginx的80端口后端跑在8080还是跨域。两种解法Nginx配置反向代理把/api路径转发到本机的8080端口或者后端开启CORS把allowedOriginPatterns配置为你的前端域名。5.3 学习路径建议如果你是个后端方向的学生或初级开发者我建议的学习顺序是先看懂整个项目的请求流转链路从浏览器地址栏输入URL到页面最终渲染这一步你画一张流程图出来把所有环节串起来你对全栈开发的理解会上一个台阶。然后专注于某个模块纵向深入。比如新闻发布这个模块从前端表单校验、文件上传到后端接收、参数校验、数据库落库整个链路里的每一行代码都看懂再想想哪里有漏洞、哪里性能可以优化这种纵向深挖比横向看十个项目都有效。最后是动手改代码。改一个字段、加一个接口、调一个Bug都比看十遍源码来得实在。这套项目本来就是开箱即用的非常适合边跑边改边验证。我在实际跑这套项目的时候最大的感受是它不只是一个“能运行”的源码而是一套完整的教学素材。你把里面每个注解、每个配置文件、每个拦截器都弄清楚SpringBoot Vue这套主流组合的核心知识算是掌握得差不多了。下一步哪怕是去面实习岗聊到项目经验的时候能把这个系统的表结构设计思路、权限控制的实现方式、跨域处理的两种方案讲明白面试官基本就能确认你是真的动过手写代码的人。