尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于SSM+MySQL的网约车用户服务平台设计与实现

基于SSM+MySQL的网约车用户服务平台设计与实现 简介在Java Web开发领域SSMSpringSpring MVCMyBatis是经典的三层架构组合通过依赖注入、请求分发与SQL映射实现业务模块解耦。数据库设计上以MySQL InnoDB引擎保障事务一致性与行级锁支撑订单类系统的状态流转与并发控制。理解这些底层原理对课程设计和毕业设计都有实际价值。以网约车用户服务平台为例项目完整覆盖了框架整合、数据建模、订单状态机、乐观锁防并发等关键工程实践。从用户下单、司机抢单到后台统计SSMMySQL技术栈能高效落地业务闭环。围绕该平台可系统梳理需求分析、数据库脚本、核心功能模块与常见问题排查帮助开发者快速掌握SSM整合技巧和订单系统设计方法并迁移到外卖、预约等同类业务场景。 网约车用户服务平台这种项目几乎每年都会在课程设计和毕业设计里出现一轮。我今天就拿“基于SSMMySQL的网约车用户服务平台”这个项目来拆一遍从需求分析、数据库设计、框架整合到订单状态流转每一条都讲清楚为什么这么做以及你上手的时候会在哪些地方卡住。这个项目包含源码、数据库脚本和设计文档本质上是一个完整的三层架构Java Web应用前端用JSPBootstrap后端用Spring、Spring MVC、MyBatis数据存到MySQL里。适合准备做毕设、想系统过一遍SSM整合流程、或者想看看真实业务项目里订单类需求怎么落地的同学。1. 项目整体设计与思路拆解1.1 这类项目到底要解决什么业务问题网约车平台的核心业务场景很简单乘客有出行需求司机有接单需求平台负责把两者匹配起来并在整个行程过程中维护订单状态的流转。所以在功能拆解上一个用户服务平台基本上可以分成三个端来看。用户端注册、登录、发布行程填起点终点、等待司机接单、查看订单状态、行程结束后的评价。司机端注册与资质认证、上下线、查看附近或派给自己的订单、接单/拒单、开始行程、结束行程。管理后台用户列表、司机审核、订单列表、订单统计、基础数据维护。很多同学一上来就想做“高德地图那种实时轨迹”这其实是给自己挖坑。课程设计级别的项目定位到“用户服务平台”重点在业务闭环——用户能下单、司机能接单、订单状态能正确流转、后台能查到数据这就已经覆盖了SSM框架的所有核心知识点。地图、GPS、实时路径规划这些完全可以做成接口预留用简单的经纬度字段先存下来后续再对接地图API。1.2 为什么SSMMySQL这套组合依然值得选现在Spring Boot确实是大趋势但SSM框架依然大量出现在高校课程和教学项目里这不是因为它过时而是因为它的分层足够明显能把“谁在做什么”这件事讲得很清楚。Spring负责管理对象Service、DAO这些类的创建和依赖注入都由Spring容器统一管理。Spring MVC负责接收请求和返回视图前端发的每个请求先到DispatcherServlet再由Controller分发到具体处理逻辑。MyBatis负责数据库操作把Java接口和SQL映射分开SQL自己写可控性很强。MySQL负责数据持久化事务上用InnoDB引擎订单这种核心表需要支持行级锁和事务回滚InnoDB是唯一选择。这个组合学完之后你再去看Spring Boot会发现它其实就是把Spring、Spring MVC、MyBatis这些组件用自动配置包装了一遍底层思路完全一样。所以花时间把SSM整合明白不亏。1.3 源码、数据库、文档三件套的分工逻辑这个项目标题里带着“源码数据库文档”这个结构其实值得仔细说说。源码解决的是“系统长什么样、代码怎么组织”的问题看的是包结构、层与层之间的调用关系。数据库脚本解决的是“数据从哪来、业务状态怎么落库”的问题建表SQL、初始化数据都在这份文件里。文档解决的是“为什么这么做”的问题包含需求分析、功能设计、数据库设计、核心流程说明。我见过太多同学拿到代码后直奔Controller层看完就懵因为心里没有数据模型的概念。正确的打开方式应该是先跑通数据库脚本把表结构看明白再看核心业务的SQL最后回到Java代码里看Service是怎么调用Mapper的。按这个顺序读代码基本三小时就能理清整个项目。2. 环境准备与框架整合要点2.1 开发环境与基础配置先列一套我实测比较稳的环境组合JDK 1.8Maven 3.6.xTomcat 8.5或9.0MySQL 5.7如果本机是MySQL 8.0需要改驱动和连接串后面详细说IntelliJ IDEA社区版就够用配置Tomcat的时候有一个很关键但容易忽略的地方项目在IDEA里运行时的URL要填http://localhost:8080/项目名/如果项目名里带了版本号或者中文路径后面访问接口的时候非常容易404。建议把Application context直接设成/car这种简短的名字省事。另外IDEA里要检查项目的编译版本。经常出现的情况是JDK配的是1.8但Maven编译器插件默认依赖Java 5语法导致用了Resource等注解时报错。在pom.xml里显式加上maven-compiler-plugin把source和target都设为1.8能避免很多莫名其妙的编译问题。2.2 Maven依赖清单与典型版本组合SSM整合的pom.xml依赖说多不多说少不少版本选不对就是一场灾难。properties spring.version5.2.15.RELEASE/spring.version mybatis.version3.5.6/mybatis.version /properties dependencies !-- Spring核心 -- dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version${spring.version}/version /dependency dependency groupIdorg.springframework/groupId artifactIdspring-webmvc/artifactId version${spring.version}/version /dependency dependency groupIdorg.springframework/groupId artifactIdspring-jdbc/artifactId version${spring.version}/version /dependency !-- MyBatis和MyBatis-Spring桥接包 -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version${mybatis.version}/version /dependency dependency groupIdorg.mybatis/groupId artifactIdmybatis-spring/artifactId version2.0.6/version /dependency !-- MySQL驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version5.1.49/version /dependency !-- 连接池 -- dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.2.6/version /dependency !-- Servlet和JSP相关 -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency dependency groupIdjavax.servlet/groupId artifactIdjstl/artifactId version1.2/version /dependency !-- JSON工具 -- dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId version2.9.8/version /dependency /dependencies这里要特别提醒一个版本坑如果你本机装的是MySQL 8.0mysql-connector-java建议换成8.0.28而且驱动类要写成com.mysql.cj.jdbc.Driver连接串里必须加serverTimezoneAsia/Shanghai否则启动的时候会报时区错误。MySQL 5.7的话继续用com.mysql.jdbc.Driver就没问题。2.3 三个配置文件的核心逻辑SSM整合的核心配置文件有三个理解了这三个文件的职责后面遇到问题就知道去哪找。第一个是spring.xml它管的是容器级别的Bean。关键配置是这样!-- 自动扫描Service、DAO等组件 -- context:component-scan base-packagecom.car.service, com.car.mapper/ !-- 加载数据库配置 -- context:property-placeholder locationclasspath:jdbc.properties/ !-- 数据源 -- bean iddataSource classcom.alibaba.druid.pool.DruidDataSource init-methodinit destroy-methodclose property namedriverClassName value${jdbc.driver}/ property nameurl value${jdbc.url}/ property nameusername value${jdbc.username}/ property namepassword value${jdbc.password}/ /bean !-- 配置SqlSessionFactory -- bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean property namedataSource refdataSource/ property nametypeAliasesPackage valuecom.car.entity/ property namemapperLocations valueclasspath:mapper/*.xml/ /bean !-- 扫描Mapper接口 -- bean classorg.mybatis.spring.mapper.MapperScannerConfigurer property namebasePackage valuecom.car.mapper/ /bean !-- 事务管理器 -- bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager property namedataSource refdataSource/ /bean tx:annotation-driven transaction-managertransactionManager/第二个是springmvc.xml它只扫Controller层并且负责视图解析和静态资源放行。mvc:annotation-driven/ context:component-scan base-packagecom.car.controller/ bean classorg.springframework.web.servlet.view.InternalResourceViewResolver property nameprefix value/WEB-INF/jsp// property namesuffix value.jsp/ /bean mvc:default-servlet-handler/注意那个mvc:default-servlet-handler/少了它CSS、JS、图片资源全部加载不出来。原因很简单DispatcherServlet拦截了所有请求但静态资源请求没有对应的Controller方法只能靠这个配置把它们重新交给容器的默认Servlet处理。第三个是web.xml它是整个应用的入口。servlet servlet-namespringmvc/servlet-name servlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class init-param param-namecontextConfigLocation/param-name param-valueclasspath:springmvc.xml/param-value /init-param load-on-startup1/load-on-startup /servlet servlet-mapping servlet-namespringmvc/servlet-name url-pattern//url-pattern /servlet-mapping这里/的写法很有说法。如果配成/*所有请求包括JSP页面都会走DispatcherServlet结果就是Controller返回的视图没法正常渲染页面直接变成乱码或者源码。正确做法是配成/让JSP请求直接交由Servlet容器处理。3. 数据库设计网约车平台的关键在订单表3.1 核心表结构与字段设计解读网约车平台的表结构不算复杂核心围绕“人”和“订单”展开。我做这类项目时最常用的核心表就是下面这些t_user乘客用户表字段包括id、username、password、phone、nickname、create_time。t_driver司机表字段包括id、user_id关联用户表、name、phone、license_no、car_no、car_model、status0待审核 1通过 2禁用。t_order订单表这是整个系统的核心字段要专门说明。t_evaluation评价表关联订单和司机。订单表是整个系统里字段最多的表我这里列一份核心脚本CREATE TABLE t_order ( id bigint(20) NOT NULL AUTO_INCREMENT, order_no varchar(32) NOT NULL COMMENT 订单编号, user_id bigint(20) NOT NULL COMMENT 下单用户ID, driver_id bigint(20) DEFAULT NULL COMMENT 接单司机ID, start_address varchar(100) NOT NULL COMMENT 起点, end_address varchar(100) NOT NULL COMMENT 终点, start_lng decimal(10,6) DEFAULT NULL COMMENT 起点经度, start_lat decimal(10,6) DEFAULT NULL COMMENT 起点纬度, end_lng decimal(10,6) DEFAULT NULL COMMENT 终点经度, end_lat decimal(10,6) DEFAULT NULL COMMENT 终点纬度, status tinyint(4) NOT NULL DEFAULT 0 COMMENT 0待接单 1已接单 2行驶中 3已完成 4已取消, amount decimal(10,2) DEFAULT NULL COMMENT 订单金额, distance decimal(10,2) DEFAULT NULL COMMENT 预估距离(公里), create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 下单时间, accept_time datetime DEFAULT NULL COMMENT 接单时间, finish_time datetime DEFAULT NULL COMMENT 完成时间, KEY idx_user_id (user_id), KEY idx_driver_id (driver_id), KEY idx_status (status) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT订单表;这里有几个设计上的考量。status用tinyint而不是varchar存中文是为了查询速度快、避免脏数据。在Java代码里定义一个枚举或者常量类来映射例如0表示待接单、1表示已接单、2表示行驶中、3表示已完成、4表示已取消。order_no必须有而且要在代码里生成不能依赖数据库自增。原因是订单号会暴露给用户自增ID容易被遍历而且业务上经常需要按订单号查询加个唯一索引很合理。生成方式可以用System.currentTimeMillis()加随机数或者用yyyyMMddHHmmss userId后四位。三个时间字段分别记录下单、接单、完成时间这不仅是业务需要也方便将来对账、统计时长。取消订单的情况只记录取消时间可以加一个cancel_reason字段这个在真实项目里必须有否则客诉的时候查无实据。3.2 订单状态机与流转约束订单状态是整个项目的业务命脉。状态流转必须遵循固定的顺序不能让用户从“已取消”直接跳到“已完成”。设计状态机时可以用一张流转表来约束当前状态可执行动作目标状态待接单用户取消已取消待接单司机接单已接单已接单司机开始行程行驶中已接单司机取消已取消行驶中司机结束行程已完成已完成用户评价状态不变在代码实现时不能只用update ... set status 新状态一定要带上前置条件UPDATE t_order SET status #{newStatus}, accept_time NOW(), driver_id #{driverId} WHERE id #{orderId} AND status #{expectedOldStatus}这样写的好处是如果这条订单在并发操作下已经被别人改成了别的状态那这次更新影响的行数是0代码里根据这个结果就知道操作失败了可以提示“订单状态已变化请刷新”。3.3 司机接单的并发处理网约车场景里最常见的并发问题是“多个司机同时抢同一单”。如果不做控制很可能两个司机都看到订单状态是“待接单”然后各自执行一次更新最后谁成功谁失败完全看运气。解决思路就是上面那条带状态条件的UPDATE语句。在MySQL的InnoDB引擎下这条UPDATE会先锁定满足条件的行再执行更新所以同一时刻只有一个事务能修改成功。执行影响的记录行数如果是1表示抢单成功如果是0说明订单已经被别人抢走。这就是典型的乐观锁思路——不用在应用层面加锁利用数据库的行锁和条件更新保证数据一致性。我在Service层实现抢单的时候是这样处理的Transactional(rollbackFor Exception.class) public boolean acceptOrder(Long orderId, Long driverId) { Order order orderMapper.selectById(orderId); if (order null || order.getStatus() ! 0) { return false; } int rows orderMapper.updateStatusAndDriver(orderId, driverId, 1, 0); return rows 0; }注意先查一遍是为了能给出更友好的提示信息真正保证并发安全的是后面那条带条件的UPDATE加上Transactional确保事务原子性。3.4 派单逻辑的简化实现与扩展预留真实网约车平台的派单算法会考虑距离、司机评分、实时路况、潮汐区域等因素但课程项目一般不需要做这么重。一个可行的简化方案是用户下单后系统从在线司机中找几个附近没在跑单的司机按距离排序把最近的司机ID写入订单的candidate_driver_id字段然后通知实际是前端轮询该司机查看订单。司机点“接单”后走上面说的抢单逻辑。如果司机拒绝或者超时不接系统就把这个候选司机标记为“已推送”再选下一个。为了实现这个逻辑在司机表或者单独建一张t_driver_location表存司机实时位置很重要。至少需要有driver_id、lng、lat、update_time四个字段。查询附近的司机用经纬度范围匹配就行SELECT * FROM t_driver_location WHERE lng BETWEEN #{minLng} AND #{maxLng} AND lat BETWEEN #{minLat} AND #{maxLat} AND driver_id IN (SELECT id FROM t_driver WHERE status 1 AND online 1)minLng、maxLng这些值可以在Java代码里根据用户起点经纬度算一个矩形范围。虽然严格来说应该用球面距离计算但课程项目用这种矩形过滤已经够用了接口命名上留好nearbyDrivers()以后要接地图API也有位置。4. 核心功能模块实现与实操记录4.1 用户端从注册到下单的完整链路用户端最核心的功能是注册登录和下单。注册逻辑里密码一定不能明文存储用MD5加盐或者BCrypt。MD5虽然不算特别安全但在课程项目里比明文强太多了而且实现简单public String encodePassword(String password, String salt) { return DigestUtils.md5DigestAsHex((password salt).getBytes()); }注册时把用户名、手机号作为唯一校验字段插入前先查重。手机号可以做脱敏显示138****1234这种小细节写进开发文档里很加分。下单的Controller层接收用户提交的起点终点、经纬度Service层先生成订单号再计算预估距离和费用最后插入订单表。费用计算可以写得很简单基础费用 8 元 每公里 2.5 元。规则可以用常量抽出来后续调整价格只改一个地方public BigDecimal calculateAmount(BigDecimal distance) { BigDecimal basePrice new BigDecimal(8.00); BigDecimal perKmPrice new BigDecimal(2.50); return basePrice.add(distance.multiply(perKmPrice)); }下单成功之后前端页面在订单详情页用setInterval定时请求订单状态接口轮询到状态变成“已接单”时就在页面显示司机信息和联系方式。这种轮询方案简单可靠缺点是实时性一般但对课程项目来说完全够用。4.2 司机端接单与订单状态维护司机端的核心功能是上下线、接单、开始行程、结束行程。接单功能的实现我在前面抢单部分已经讲了这里补充一个前端细节司机端订单列表页面应该用定时刷新来拉取“待接单”订单而不是每次都整页刷新。用jQuery的$.getJSON配合setInterval就够了不需要引入复杂的前端框架。每过5秒向服务端请求一次最新订单列表如果发现有新订单就播放一个提示音提醒司机注意。这个交互方式在真实业务里也常见只是真实场景会有WebSocket做实时推送。开始行程和结束行程的接口本质上也是改订单状态Transactional public boolean startTrip(Long orderId, Long driverId) { int rows orderMapper.updateStatus(orderId, 2, 1, driverId); if (rows 0) { throw new BusinessException(只能操作自己接的订单); } return true; }这里必须把driverId也带进SQL条件防止司机A去操作司机B的订单这是一个很容易被忽略的越权漏洞。订单完成后系统要计算实际费用。我习惯在结束行程时由后端重新算一次金额用实际里程覆盖预估金额并写入finish_time。这样用户端看到的就是最终支付金额。4.3 管理后台审核、统计与权限设计管理后台是很多学生项目最容易偷懒的部分其实这里最能体现工程化能力。司机审核是后台最典型的流程管理员在“待审核司机”列表里看到司机的姓名、驾驶证号、车牌号点通过或者驳回。审核操作在代码里对应更新t_driver.status字段。这个功能不需要锁但要记录操作人和操作时间所以司机表里可以加audit_user和audit_time两个字段。订单统计页面可以用ECharts画一个简单柱状图统计最近7天的订单量。后端提供一个接口返回按日期分组的订单数量SELECT DATE(create_time) AS day, COUNT(*) AS cnt FROM t_order WHERE create_time #{startTime} GROUP BY DATE(create_time) ORDER BY day控制层返回JSON数组前端用ECharts加载数据。图表能正常显示在答辩演示时非常直观。权限设计方面后台所有请求都放在/admin/**路径下写一个AdminInterceptor拦截/admin/*检查Session里有没有管理员标识。如果没有就重定向到登录页。这个方案简单但实用而且能在文档里写清楚“基于拦截器的粗粒度权限控制”。4.4 前端交互页面、AJAX与数据格式约定JSP页面搭配Bootstrap是这类项目的标配。页面布局一般包括顶部导航栏、侧边栏、内容区三个部分用JSP的include指令复用公共片段比如header.jsp和footer.jsp。前后端交互统一用JSONController方法上加ResponseBody返回给前端的数据格式要统一。我建议定义一个简单的Result对象public class Result { private int code; // 200成功 500失败 private String msg; // 提示信息 private Object data; // 业务数据 }前端拿到的永远是{code:200, msg:success, data:{...}}这种结构回调里先判断code再做后续处理。这样整个项目的Ajax代码可以写得非常统一不会出现十个接口十种返回格式的灾难。需要注意一个Jackson序列化的大坑如果实体类里用了LocalDateTime而Spring MVC版本较老默认的Jackson不支持Java 8时间类型序列化会直接报错。最省事的办法是数据库的datetime对应Java里的java.util.Date或者给LocalDateTime字段加JsonFormat(pattern yyyy-MM-dd HH:mm:ss)。如果实在是排不出来干脆在SQL查询时用DATE_FORMAT(create_time, %Y-%m-%d %H:%i:%s)转成字符串返回最直接。5. 常见问题与排查技巧实录5.1 数据库连接与版本不匹配问题这类项目里最频繁的报错就是数据库连不上而且错误信息千奇百怪。如果报ClassNotFoundException: com.mysql.jdbc.Driver多半是本地MySQL是8.0驱动却还是5.x或者根本没引入驱动包。改成com.mysql.cj.jdbc.Driver并依赖8.x版本驱动即可。如果报The server time zone value Öйú±ê׼ʱ¼ä is unrecognized这是MySQL 8.0的时区问题连接串加?serverTimezoneAsia/ShanghaiuseSSLfalse就行了。如果报Access denied for user rootlocalhost先检查用户名密码再检查是不是权限问题。很多人会在root密码里带这种特殊符号结果在properties文件里没做转义解析就乱了。建议开发环境把数据库密码设得简单一点比如直接用root123456。如果报Public Key Retrieval is not allowedMySQL 8.0需要在连接串加allowPublicKeyRetrievaltrue。我把常见数据库问题整理成一张速查表报错信息常见原因解决方案ClassNotFoundException驱动版本不对统一使用兼容版本的mysql-connector-javaServer time zone ...MySQL 8.0时区设置URL加serverTimezoneAsia/ShanghaiAccess denied账号或密码错误重置密码或在配置中去掉特殊字符Public Key RetrievalMySQL 8.0安全机制URL加allowPublicKeyRetrievaltrueUnknown database库没创建先执行建库语句再执行建表脚本5.2 请求404与静态资源无法加载404问题在SSM项目里太常出现了。我总结下来主要是三类原因。第一类访问路径和Controller上的RequestMapping不一致。排查时先看Controller类上有没有class级别的路径前缀比如类上写了RequestMapping(/order)方法上写RequestMapping(/list)那完整路径就是/order/list。第二类DispatcherServlet拦截路径配置错了。web.xml里如果配成url-pattern/*/url-pattern会导致JSP请求也被DispatcherServlet拦截页面直接以源码形式显示。改成/就没问题。第三类静态资源CSS、JS、图片加载不出来。排查思路是在浏览器开发者工具里看资源请求的状态码如果是404检查springmvc.xml里有没有加mvc:default-servlet-handler/如果是500多半是资源文件本身路径引用错了JSP页面里写/css/style.css这种绝对路径时要确保项目根的上下文路径是正确的。5.3 中文乱码问题乱码问题的排查思路只有一个全链路字符集必须统一。数据库连接串加characterEncodingutf8。建库建表时显式指定字符集DEFAULT CHARSETutf8mb4。JSP页面顶部写% page contentTypetext/html;charsetUTF-8 languagejava %。Tomcat的server.xml里给Connector加URIEncodingUTF-8解决GET请求参数乱码。Controller返回JSON时在springmvc.xml里配置一个StringHttpMessageConverter强制使用UTF-8编码。其中server.xml那个坑我在初学SSM时踩得很深。页面提交表单是POST请求修改了Request装配过滤器就能解决中文但如果是GET请求或者打开带中文参数的URLTomcat默认会用ISO-8859-1去解密URL参数中文就乱了。在server.xml的Connector节点加上URIEncodingUTF-8后重启Tomcat才能根治。5.4 状态更新丢失与并发问题我在带人看项目时经常遇到有人抱怨“两个司机同时点了接单两个页面都显示接单成功了但数据库里只有一个司机”这个就是典型的并发状态更新问题。解决办法在前面已经给出来了更新时必须带旧状态条件。如果更新的影响行数为0就说明当前状态不匹配需要重新查询并提示用户。很多人写Mapper更新语句时图省事直接按id更新完全不考虑status这在订单这类需要状态流转的业务里一定会出问题。另外一个隐藏问题是Transactional没有生效。Spring的声明式事务默认只在RuntimeException下回滚如果Service方法里throws Exception比如Exception e事务不会回滚。规范做法是Transactional(rollbackFor Exception.class)并且在Controller层捕获业务异常后统一返回错误信息。这是我要求学生写的第一个规范避免“打开订单但司机没被占用”这种脏数据。5.5 部署打包时的高频坑当项目做完打包部署到Tomcat时有几个非常典型的坑。第一JDK版本不一致。开发环境用的JDK 8服务器如果用的是JDK 11有些依赖的行为会变化。稳妥做法是本地和服务器都装相同大版本JDK并且pom.xml里配置maven-compiler-plugin让编译目标固定为1.8。第二数据库连接配置。properties文件里的jdbc.url如果写的是localhost部署到服务器后要改成服务器的实际IPusername、password也要检查不要把本地测试账号带到正式环境。第三war包名称。用Maven执行mvn clean package打包产生的war包名默认是artifactID-version.war这个名称就是部署后的访问路径。如果期望访问/car要么把war包重命名为car.war要么在pom.xml中配置finalNamecar/finalName。还有一个我印象很深的坑项目的lib目录里有多个版本的jar包比如同时存在不同版本的mysql驱动Tomcat加载时可能因为类加载顺序导致运行时用的是旧版本驱动结果本地一切正常部署后一启动就报驱动方法不存在。排查时直接在部署环境里看实际生效的jar版本或者在maven依赖树里检查是否引入了重复依赖用mvn dependency:tree可以一键查出来。整套做下来你会发现这种SSM项目最大的价值不是代码本身而是把业务变成数据结构、把状态流转变成事务规则的过程。拿到任何一份源码先看它的数据库脚本再顺着订单状态走一遍代码基本就能把整个项目吃透。下次遇到类似的项目比如外卖平台、定票系统你也会发现它们的内核几乎都是同一套只是业务对象换了名字而已。本文还有配套的精品资源点击获取
返回列表