ARTICLE DETAIL

资讯详情

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

SSM + Vue3 全栈开发实战:从整合到联调的关键技术解析

SSM + Vue3 全栈开发实战:从整合到联调的关键技术解析 我平时带全栈训练营新人时发现一个很尴尬的现象不少人拿着Spring Boot玩得飞起一回到企业里遇到老项目SSM就傻眼前端则是会用Vue2写页面Vue3的组合式API看完文档就忘。我自己的看法是不管现在Spring Boot和微服务多火SSM这套东西在大量存量系统、外包项目、学校毕业设计里依然占着相当高的比例——不是因为它有多先进而是因为它结构直白、成本低、改起来快用一句话讲就是干活够用。与此同时Vue3经过这几年的迭代生态和稳定性已经非常成熟后台管理系统、商城一类的项目几乎默认用Vue3来写。把这两块拼起来就是一条非常典型的Java全栈开发路线也是很多人入行后第一个真正前后端打通的项目。这篇内容主要解决什么问题呢我打算不以SSM整合SSM这种老掉牙的配置轰炸为主而是围绕一条完整链路来讲SSM后端怎么整合、Vue3前端工程怎么搭、两者之间怎么联调、登录鉴权和CRUD这类真实业务怎么落到代码上最后再附上我事后复盘时整理的常见坑。适合谁看呢第一类是刚学完JavaWeb和Vue基础、想做一个完整全栈项目的学生第二类是准备把某个老系统改造为前后端分离的开发者第三类是毕设选了基于SSM的学生信息管理系统之类题目的同学——这题目这么多年了依然是毕业设计里的常青树你们懂的。SSM与Vue3整合的整体架构与思路拆解1.1 为什么到今天还要选择SSM搭配Vue3很多人都问过一次SSM都过时了为什么不直接上Spring Boot这个问题我理解但事情没那么绝对。SSM作为Spring、SpringMVC、MyBatis三件套的组合本质是把对象管理、HTTP处理、数据持久化三件事拆给三个框架各管一段。Spring Boot确实把这些都封装好了省去大量XML配置但对学习者来说Boot的自动配置其实是一层黑盒——你并不知道它底层替你干了什么。恰恰是SSM的所见即所得能让一个人把请求从浏览器打到数据库这条路上的每一个环节都搞清楚。有了这个底子再去学Spring Boot、Spring Cloud理解起来完全不是一个速度。再往后端看Vue3经过这几年的优化响应式系统换成了Proxy实现性能上比Vue2的Object.defineProperty强不少组合式API让代码复用和逻辑组织都清晰很多加上Vite带来的秒级启动体验现在新开一个前端项目几乎没有理由再用Vue2。所以SSM Vue3这个组合看起来很混搭实际上非常合理后端负责稳前端负责快两者通过JSON接口通信。对全栈开发而言你不需要一开始就驾驭微服务那种复杂度用一个SSM项目把前后端链路彻底跑通后续再往任何方向扩展都有底气。1.2 整体工程结构与一次完整请求的流转路径我先用一段大白话把整个项目的工作方式讲清楚。假设现在要做一个学生信息管理系统用户在浏览器里点击查询学生列表这个按钮接下来发生的事情是这样的前端Vue3项目中的某个组件监听到点击事件调用封装好的request函数向/api/student/list发送HTTP请求。请求被Vite开发服务器代理转发到后端Tomcat。Tomcat把请求交给SpringMVC的DispatcherServlet由它根据URL找到对应Controller中的方法。Controller调用Service层处理业务逻辑Service再调用Mapper接口。MyBatis根据Mapper接口找到对应的XML文件或注解SQL执行SQL语句操作数据库。查询结果一层层返回最后被转换成JSON格式回传给前端。Vue组件拿到数据更新页面上的表格。这个过程看起来平平无奇但任何一个环节没打通整个链路就断掉。Controller、Service、Mapper三层的分工很像餐厅Controller是服务员负责接收客人点单接收请求和端菜返回结果Service是后厨主管负责决定菜怎么做业务逻辑Mapper是传菜员负责把做菜需要的食材从仓库数据库里拿出来。把这三层的职责边界划清楚项目才不会写成一团乱麻。1.3 技术选型与版本选择建议SSM项目对版本非常敏感很多整合失败其实是版本搭配不对。我这里给出一个经过多次验证的稳妥组合照着配基本不会翻车。组件推荐版本说明JDK1.8 或 11老项目多为1.8新项目可选11SSM本身不挑高版本Maven3.6.3管理依赖和打包Spring5.3.x既兼容传统XML也支持全注解不建议用太老的4.xSpringMVC5.3.x与Spring一致父子版本要统一否则容器启动直接报错MyBatis3.5.x3.5版本对JDK8以上支持更好MyBatis-Spring2.1.x让MyBatis和Spring正常协作的关键桥接包Druid1.2.x阿里连接池自带监控页面调起参来直观Tomcat9.x对应Servlet 4.0SSM项目大都是war包部署Node.js16.20 或 18.x运行Vite和npm建议统一用18 LTS太老版本装新依赖会报错Vue3.4.x稳定版配合Vite 5使用体验最好Vite5.x开发服务器和构建工具替代老一代webpack方案Vue Router4.xVue3专用路由与Vue2时期的路由写法有差异Pinia2.xVue3官方推荐状态管理相对Vuex更轻量提示版本号不是越新越好。比如Spring 6和Jakarta EE那套命名空间跟互联网上大量SSM老教程完全不兼容新手如果选了新版导致死活启动不了很容易被劝退。建议先按上表这套稳定组合跑通再自己尝试升级。后端SSM整合的细节解析与实操要点2.1 两种配置方式之争XML还是全注解SSM整合第一个要做的决定就是用XML配置还是全注解配置。很多老教程都是XML为主的写法spring.xml、spring-mvc.xml、mybatis-config.xml三四个配置文件堆在一起新手一看就头大。但站在今天的角度我强烈建议优先选择全注解 少量配置类的方式。原因很简单第一项目里配置越多出错的可能性越大尤其当你复制粘贴网上配置时一个命名空间少了就启动失败第二现在Spring Boot主导的生态里大家默认都是注解开发从SSM阶段就习惯注解后面平滑迁移成本低。不过有些东西还是离不了配置文件。比如web.xml要配置ContextLoaderListener和DispatcherServletspring-mvc.xml里要开启注解驱动、配置视图解析器如果框架版本或容器版本不匹配这些配置踩坑概率很高。我的做法是核心配置用Java配置类写剩下的web.xml保留最小的必需项这样既有注解的简洁又方便排查问题。一个最小可用的SSM配置类长这样以SpringConfig和SpringMvcConfig两个类为核心Configuration ComponentScan(basePackages com.example.sms, excludeFilters { ComponentScan.Filter(type FilterType.ANNOTATION, classes Controller.class) }) public class SpringConfig { // 在这里配置数据源、SqlSessionFactory、事务管理器等 } Configuration ComponentScan(basePackages com.example.sms.controller) EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer { // 在这里配置静态资源映射、CORS跨域、JSON转换器等 }关键点在于SpringConfig扫描的时候要排除ControllerSpringMvcConfig只管Controller层。这个边界不清常常导致两套容器重复管理同一个Bean出现事务不生效或Bean类型冲突的怪问题。2.2 数据源与MyBatis连接数据库的配置要点数据源是整个项目里的基础设施这一层没配好后面所有CRUD都无从谈起。我推荐用Druid因为它在连接池的基础上带了一个内置监控页面可以实时看SQL执行情况、慢查询数量、连接池活跃数。对一个学生信息管理系统来说这些指标也许用不太上但从学习数据源原理的角度非常有帮助。数据源配置里最容易忽视的是几个参数initialSize初始化连接数建议5。项目一启动就预先建立连接避免第一个请求来临时临时建连接的延迟。maxActive最大活跃连接数建议20。太小的话并发一高就等待太大会占用数据库连接资源。validationQuery检测连接是否有效的SQL一般用SELECT 1。空闲连接被数据库回收后如果没有检测机制拿到已失效的连接会直接抛异常。connectionInitSqls首次建立连接时要执行的SQL。很多MySQL库默认时区不对导致数据库时间比本地少8小时可以通过连接参数socketTimeout结合服务端时区设置解决。连接池与数据库之间还有一个常见的坑是JDBC驱动版本。MySQL 5.x和MySQL 8.x对应的驱动类名和URL都不一样。MySQL 8以上要把driver-class-name配成com.mysql.cj.jdbc.DriverURL中还要显式加上serverTimezoneAsia/Shanghai和characterEncodingutf8否则中文写入乱码、日期错乱问题接踵而至。MyBatis在SSM整合中还需要注意驼峰映射的开启。数据库字段如果叫student_name实体类属性叫studentName不开启驼峰映射的话查询结果永远是null。有两种解决思路一是写SQL时给列取别名而是mybatis.configuration.map-underscore-to-camel-casetrue这个开关一开就全局生效推荐后者。2.3 Maven依赖清单与war包部署细节SSM项目用Maven管理依赖是最基本的操作。pom.xml里的依赖虽然多但可以归成几类Spring核心、SpringMVC、MyBatis、MyBatis-Spring桥接、数据库驱动、连接池、JacksonJSON序列化、Servlet API、文件上传组件、Lombok可选。下面是一个精简但可运行的依赖骨架properties spring.version5.3.30/spring.version mybatis.version3.5.13/mybatis.version /properties !-- Spring核心context、beans、core、aop、tx、webmvc -- dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version${spring.version}/version /dependency dependency groupIdorg.springframework/groupId artifactIdspring-webmvc/artifactId version${spring.version}/version /dependency !-- MyBatis与桥接包 -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version${mybatis.version}/version /dependency dependency groupIdorg.mybatis/groupId artifactIdmybatis-spring/artifactId version2.1.2/version /dependency !-- MySQL驱动 Druid连接池 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.2.20/version /dependency !-- JSON序列化 -- dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId version2.15.2/version /dependency !-- Servlet API、JSP API部署时不要打进war包 -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency部署细节上有两个非常容易犯的错误。第一个是用mvn package时打出来的war包如果特别大或者运行后报Jackson相关错误多半是slf4j-simple、commons-logging等日志组件在多个依赖里重复出现导致类冲突。第二个是Tomcat的lib目录下如果有旧版本的servlet-api也会与项目里的jar包冲突表现就是明明本地启动正常扔到服务器上就报NoSuchMethodError这时优先检查是否重复引入了servlet-api。2.4 SSM整合时最常见的一批启动报错我统计了一下带新人做项目时遇到最多的启动阶段报错大概使下面五类第一类SpringMVC配置类扫描不到Controller。表现是启动不报错但访问任何一个URL都404。原因多半是SpringMvcConfig的ComponentScan写成了com.example把Controller以外的类也扫了或者扫了com.example.controller但类上没加RestController注解。第二类MyBatis映射文件没找到。表现是启动时报Invalid bound statement (not found)。这个最坑因为编译时XML文件如果放在src/main/java目录下Maven默认不会把它复制到classes目录。解决办法是在pom.xml里配置resources节点将src/main/java下的XML文件也包含进构建产物。第三类数据库连接失败。表现是启动时Druid数据源初始化异常或者第一次请求时抛出Cannot create PoolableConnectionFactory。优先检查MySQL服务是否启动、账号密码是否正确、端口是否被占用。如果是在云服务器上部署还需要检查安全组是否放行3306端口。第四类事务不生效。表现是Service方法里插入数据后异常但数据还是写进去了。原因是SpringConfig里忘记加EnableTransactionManagement。另外一个典型的低级错误是事务管理器配了但Service类没有被Spring扫到导致实际Controller调用的是没经过代理的原始对象。第五类字符编码问题。表现是前端传中文到后端变成乱码或者从小数据库查出来的中文乱码。这类问题要从三个层面排查前端请求头是否带了Content-Type: application/json; charsetutf-8后端CharacterEncodingFilter是否配置了编码为UTF-8数据库连接URL里是否带了characterEncodingutf8。三处都对了中文才可能不出乱码。前端Vue3工程搭建与核心机制3.1 从Node环境到Vite创建项目的正确姿势前端的准备工作说简单很简单说坑也坑。很多人的Vue3项目起不来第一步就栽在Node版本上。Vite5要求Node 18以上的版本如果你机器上还是Node 14或更低npm create vite虽然能执行但装完依赖启动时直接报错。建议先执行node -v确认版本如果版本太低去Node官网重新装一个18 LTS版本。相关的npm版本也会跟着Node升级一般不用单独处理。创建项目我用的是Vite官方命令行工具npm create vitelatest student-manager-ui -- --template vue cd student-manager-ui npm install npm run dev--template vue生成的是JavaScript版本。如果你对TypeScript比较熟练可以改成vue-ts模板。我建议第一次做全栈项目的同学直接用JavaScript版本就行SSM后端学习已经有不少概念要吸收前端再用TypeScript会增加心智负担。等项目跑通了再回头把TypeScript加上也不迟。生成的项目目录结构本身很简单src下是代码public下放静态资源index.html是入口页面。实际开发时我会在src下自己建更细的目录推荐分这么几类api接口请求、router路由、storesPinia状态管理、views页面级组件、components通用组件、utils工具函数。这样的目录结构对后台管理系统特别友好页面一多也不会乱。3.2 组合式API与响应式机制的实战理解Vue3相比Vue2最核心的变化就是组合式API。用Vue2写代码data、methods、computed、watch是分开的区块一个复杂的业务逻辑会被拆散到各个区块里。而组合式API允许你把某个功能相关的所有状态和方法写在一起比如写一个用户相关的模块就把userInfo、getUserInfo()、updateUserInfo()放在同一段代码块里可读性和可维护性立刻提升。实际开发里最常打交道的是ref和reactive这两个API。简单记忆方法ref用来包装基本类型字符串、数字、布尔值也可以包对象。在template里使用时Vue会自动解包不需要写.value但在script里操作时必须写.value。reactive只能用来包装对象和数组操作时是直接访问属性不需要.value。很多新手困惑两个都能用到底用哪个我的建议是跟踪单个表单项、计数器之类的标量值用ref牵涉一整个表单对象、列表数据这类复杂结构用reactive。当然这只是约定俗成的习惯没有绝对的强制。computed和watch的适用场景也要分清楚。computed是根据已有数据计算新数据计算属性有缓存依赖的数据没变就不会重新计算赛出来性能会好。而watch是数据变化时执行副作用比如搜索框输入内容后触发接口请求这里的发请求不是计算新值就是副作用用watch才贴切。Vue3的响应式底层换成了Proxy相比Vue2的Object.defineProperty它可以直接拦截对象属性的新增和删除操作所以不会再出现新增一个属性页面不更新的老问题。这也是Vue3在diff算法层面的底层优势——Proxy代理天然能监测到更细粒度的变化重渲染时精准定位“是谁变了”效率自然高。3.3 路由、状态管理与Axios封装的完整套路一个全栈项目的前端部分路由和状态管理是躲不开的。Vue Router 4配合Vue3使用基本配置和Vue Router 3差得不大但用法上有几个明显区别。比如createRouter替代了new VueRoutercreateWebHistory替代了mode: history。后台管理系统往往会用动态路由先登录后端返回当前用户角色和可访问的菜单前端再用router.addRoute动态注册。这个机制本身不复杂但新手经常掉进刷新页面后动态路由没了的坑里——因为刷新后Pinia里的用户信息丢失路由自然恢复成初始状态。解法通常是把用户信息持久化到localStorage刷新后再去恢复。状态管理方面Pinia已经是Vue3的默认推荐使用方式比Vuex简单很多。它抛弃了mutations的概念在store里可以直接定义state、getters、actions并异步更新。一个store的写法如下import { defineStore } from pinia export const useUserStore defineStore(user, { state: () ({ token: , userInfo: null }), actions: { setToken(val) { this.token val }, async login(payload) { const res await api.login(payload) this.setToken(res.data.token) } } })Axios的封装是另一个必须做好的点。如果直接在页面组件里axios.get(...)那几十个页面里就会散布几十份重复的代码将来某天要换请求头、加超时时间、弹统一错误提示就要逐个文件去改。我习惯把所有请求集中到一个request.js文件里用axios创建实例配置baseURL、超时时间然后在拦截器里统一做三件事请求拦截从Pinia或localStorage里取出token放到请求头的Authorization字段。响应拦截判断返回状态码如果code ! 200就统一弹出错误消息。登录失效处理如果后端返回401或某个特殊业务码清空本地用户信息并跳转到登录页。这样做的价值在真实项目中很大。有一次带团队做商城后台后端调整了登录失效的返回码我只改了一个文件就让所有页面统一弹登录已过期前后花了不到十分钟。前后端联调与核心功能实现4.1 跨域问题的两种解法与推荐方案前后端分离项目在开发环境遇到的第一个拦路虎就是跨域。SSM后端跑在8080端口Vue3前端跑在5173端口两个端口不同浏览器的同源策略就会拦截前端发出的请求。解决跨域的常用方案有两个。第一种是在后端Controller或者SpringMvcConfig配置类里加CrossOrigin或者实现WebMvcConfigurer的addCorsMappings方法。这种方法简单直接但生产环境如果前端走Nginx代理后端其实就不需要处理跨域了这个配置反而多余。第二种方式是在Vite开发服务器里配置代理。在Vite配置文件vite.config.js中写export default defineConfig({ server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true, rewrite: path path.replace(/^\/api/, ) } } } })这个配置的意思是前端请求/api/student/list时Vite开发服务器会把它转发到http://localhost:8080/student/list。浏览器里看到的请求是发给5173端口的所以不会出现跨域报错。我比较推荐这个方案因为它的代理行为与生产环境的Nginx非常相似将来部署时只需要把/api开头的请求同样代理给后端Tomcat即可前后端代码都不用改。4.2 登录鉴权全流程JWT与路由守卫后台管理系统最核心的通用功能就是登录鉴权。流程梳理一下用户提交用户名密码后端验证通过后签发一个JWT令牌返回给前端前端把token存起来后续每个请求带上token后端通过拦截器校验token合法才放行。后端的JWT集成需要引入jjwt依赖然后写一个JwtUtil工具类包含生成token和解析token两个方法。token里可以放用户id、用户名、有效期等基本信息。SSM拦截器的写法比较经典继承HandlerInterceptorAdapter或实现HandlerInterceptor接口在preHandle里从请求头取token并校验校验失败就返回401给前端。关键在于要排除登录接口本身和静态资源否则会把登录请求也拦下来。前端部分Vue Router 4的全局前置守卫是核心。在router.beforeEach里判断router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.path ! /login !token) { next({ path: /login }) } else { next() } })这层守卫保证了未登录用户无法访问任何业务页面。实际项目中还需要处理路由动态注册的问题也就是后端返回菜单后前端把页面级组件动态挂到路由表上。很多初学者在这个位置写不好导致菜单点进去是空白页通常是路由组件路径写错或者组件没有在import.meta.glob中被正确引入。4.3 学生信息管理系统CRUD全流程实战我拿学生信息管理系统作为贯穿案例因为这是SSM项目里最常见的毕业设计题目——数据库表就一张student表字段有学号、姓名、性别、年龄、班级、入学时间等前后端无非是列表、新增、编辑、删除四个动作却是全栈开发基本功的完整浓缩。后端部分Controller层的接口设计按REST风格来GET /student/list?page1size10name张—— 分页条件查询POST /student—— 新增学生PUT /student/{id}—— 修改学生DELETE /student/{id}—— 删除学生这里有一个细节就是分页插件。SSM项目里通常是配合PageHelper使用只要在Service方法中调用PageHelper.startPage(pageNum, pageSize)紧接着的查询就会自动执行分页SQL返回的数据还要封装成带total总条数的对象。如果不用PageHelper就得自己写LIMIT offset, size还要额外查询一次total代码量大且容易出错。前端部分列表页用el-table展示数据el-pagination做分页搜索区用el-form做条件筛选。新增和编辑可以共用一个弹窗表单组件只是提交时区分是add还是edit。一个常见的坑是编辑时回填数据没处理好——点编辑按钮时要先根据行数据把表单resetFields()否则上一次编辑的数据会残留。另一个坑是删除成功后要判断当前页是否只剩最后一条且不是第一页是的话要往前翻一页再刷新列表这个细节很多教程都不会写但实际体验影响比较大。4.4 异步处理与真实业务场景的补充做了几个SSM项目之后你会慢慢发现CRUD只是热身。真实系统还要考虑文件上传、批量导入、跨表关联、操作日志、权限控制等各种需求。就拿上传头像来说后端如果用的是SpringMVC需要配置CommonsMultipartResolver在Controller里用MultipartFile接收文件然后保存到服务器某个目录并把访问路径存进数据库。这个功能看着简单但在生产环境会遇到很多细节问题文件重名怎么办建议用UUID重命名、上传文件被访问不到怎么办需要配置静态资源映射、上传超时怎么办要调大文件大小和请求时长限制、上传目录在服务器重启后丢失怎么办要配置独立的存储目录不能直接部署在Tomcat临时目录里。前端Vue3里应对这类场景也有常规套路。比如用el-upload组件时带上action属性指向后端接口再通过headers把token带上否则上传接口会被拦截器拦下。上传成功后的回调里拿到文件URL再把它放进表单的cover字段提交表单时一并发送。这一整套逻辑就是真实后台管理系统里最常见的全栈协作模式。常见问题与排查技巧实录5.1 后端常见问题速查表问题现象排查思路解决方案启动报ClassNotFoundException检查Maven依赖是否下载完整是否缺包mvn clean install重新拉取并检查pom是否漏配依赖访问接口404Controller类是否有RestController是否被SpringMvcConfig扫描到检查ComponentScan的包路径确保Controller在扫描范围内Invalid bound statementMapper接口和XML映射文件的namespace或方法id是否对应核对XML里的namespace与接口全限定名一致id与接口方法名一致插入中文乱码数据库连接URL、CharacterEncodingFilter、前端请求编码三处三处都设为UTF-8查询出来的日期差8小时数据库时区与服务端时区不一致URL加serverTimezoneAsia/Shanghai并检查MySQL系统时区事务不生效SpringConfig是否开启EnableTransactionManagement加上注解并确认事务管理器Bean正常注入5.2 前端常见问题与隐蔽坑点前端出错的表现形式比后端更难排查因为浏览器不报错并不代表逻辑正确。我最常遇到的一类问题是数据拿到但页面不渲染。如果用reactive定义了一个空数组然后通过接口拿到数据后直接用res.data赋值页面往往不会更新。正确做法是先push或重新给整个数组赋值保证触发响应式。另外一个更隐蔽的问题是嵌套数据结构的响应性——reactive包裹的对象里如果动态新增属性Vue3不像Vue2那样有$set的限制但如果你用解构把响应式对象的属性拆出来属性会丢失响应性页面自然不更新。所以要从store里拿多个字段时推荐用storeToRefs避免直接解构。再提几个热词里大家关注度高的实战问题。有朋友问若依Vue3 TS版报错的问题我之前也踩过。若依框架升级到Vue3 TypeScript后最常见的报错集中在ts-ignore相关的工具链不兼容以及tsconfig.json里paths别名配置导致找不到模块。解决办法通常是升级依赖版本、按报错提示补全类型或使用as any关键是要先分清是编译报错还是运行时报错不要一上来就改业务代码。还有人问Vue3中嵌套iframe外层div点击事件怎么不触发。这个问题很典型当你用click包裹一个iframe时浏览器会把鼠标事件交给iframe内部文档处理外层div根本接收不到。解决思路有两种一是用z-index叠加一层覆盖在iframe上的透明div事件补刀二是在iframe的load事件后通过contentWindow去监听iframe内部文档的事件再通过postMessage通知外层。具体用哪种看业务场景最直观的还是在iframe上方做覆盖层方案。还有一个细节pxtorem对ECharts图表不生效。很多人做移动端大屏项目时用postcss-pxtorem把px转rem结果ECharts图表里的字体和尺寸还是固定的px导致缩放适配失效。原因是ECharts实例的canvas是动态生成的页面初始化时做的rem转换没有作用到已经实例化的图表上。解决办法是监听窗口尺寸变化调用chart.resize()或者用echarts.init之后基于document.documentElement.clientWidth动态计算字体和间距而不是依赖静态CSS转换。5.3 联调阶段的排查心法与工具链前后端联调出现问题时我有一套固定的排查顺序能节省很多时间第一步先确认接口本身是否正常。不依赖前端页面直接用Postman或Apifox请求后端接口如果返回正常说明问题出在前端如果返回异常问题在后端。第二步打开浏览器开发者工具的Network面板看请求是否发出了、请求URL是否对、请求头和请求体是否符合预期、响应状态码是多少。很多时候真实情况是前端请求发送的路径写错或者请求参数格式不对后端连日志都没打出来。第三步观察控制台的报错信息。如果有一个红色报错不要急着去改代码先仔细读一下错误信息指向哪个文件哪一行。有一半的前端问题通过读报错信息就能解决。这套排查思路虽然朴素但非常管用。很多新人在联调阶段遇到接口问题第一反应是去后端代码里找BUG结果发现是前端没发请求。先用工具确认边界是查问题的基本素养。我可以分享一个我实际带项目时的小技巧给SSM后端添加一个简单的日志切面统一打印每次请求的URL、参数、耗时。这样前端说接口报错时看一眼后端的日志输出就知道请求有没有到达后端、参数被解析成什么了。对比一下请求进入Backend时的原始数据和前端发送的数据往往一眼就能定位是谁的问题省去大量沟通成本。另外SSM项目里调试SQL也有窍门。把MyBatis的日志级别设为DEBUG打印出完整SQL和参数占位符的实际替换值。经常出现参数绑定失败的报错就是因为XML里#{}写成了${}——前者是预编译参数占位符安全且能防SQL注入后者是字符串拼接有注入风险且值含特殊字符时会报错。实际编码时一律用#{}这算是一个铁律。我再补充一个关于接口设计的经验。很多业务系统的前后端经常为字段叫法不一致扯皮比如前端叫userName后端叫username做学生管理系统时前端叫stuName后端叫name。要避免这个问题最好的办法是定一份接口文档前后端按同一个字段名对接或者在后端统一用驼峰命名、前端请求时直接沿用。若依这类成熟框架能做得那么顺很大程度上就是依靠一套统一的字段规范。最后分享一点个人体会。很多人觉得SSM整合是过时的知识但我在实际工作中发现把SSM彻底搞懂的人写Spring Boot时会比直接上手Spring Boot的人少踩很多坑。当你知道了Tomcat、Servlet、DispatcherServlet、MyBatis工厂这些底层组件是如何拼装起来的你就能理解Spring Boot的自动配置到底自动了什么。反过来Vue3也是同样的道理理解了响应式底层原理、路由和状态管理的配合方式今后不管写管理系统还是大屏可视化你都能拿出稳定的架构和工具组合。这篇文章写到这里核心链路已经从后端SSM整合讲到了前端Vue3工程搭建再到登录鉴权和CRUD的真实落地最后是联调排查和扩展方向。如果你手头正好在做一个SSM相关的毕设或企业里的后台系统按这套思路走下来大概率能少走不少弯路。试试看跑通第一个前后端打通的接口时那种成就感是很值得的。
返回列表