
简介本资源为Java Web应用开发技术课程设计配套的车辆管理系统项目源码包面向计算机相关专业正在做毕设或课程设计的学生以及需要项目实战练手的Java学习者。项目基于IDEA开发环境采用JSPServletMySQLMaven搭建围绕车辆信息管理场景实现增删改查等核心功能数据库需建立car_data库与fixed_car表字段涵盖车牌号、颜色、车主、品牌、状态及进出时间等贴近真实业务需求。压缩包共70个文件约5.67MB包含24个xml配置文件、12个jsp页面、4个java源文件、8个class编译文件及6个jar依赖包另附项目说明文档结构完整便于快速导入运行。目前已有381人学习下载读者可借此掌握Servlet请求处理、JSP页面渲染、Maven依赖管理与MySQL数据表设计等关键技能并参考其目录组织与配置方式完成自己的课程设计或毕设项目。1. 从一份课程设计源码说起JSPServlet 的车辆管理系统到底能跑出什么如果你正在做 Java Web 课程设计或者刚学完 Servlet 想找一个能跑通、能改、能写进报告里的完整项目这份基于 JSPServletMySQLMaven 的车辆管理系统源码值得拆开看。它不是 Spring Boot 那种开箱即用的脚手架而是用最原始的 Servlet 做控制器、JSP 做视图、JDBC 直连数据库的经典三层结构整个项目用 Maven 管理依赖导入 IDEA 配好 Tomcat 就能跑。车辆管理系统这个选题在课程设计里出现频率极高因为它业务简单、表结构清晰、增删改查逻辑完整非常适合用来演示 MVC 模式。这份源码包含完整的项目说明文档、数据库建表语句和示例数据车辆信息表里预置了一条鲁A09836的临时车辆记录字段覆盖车牌、颜色、车主、品牌、状态、进出时间等。适合谁正在做 Web 应用开发技术课程设计的学生、需要交毕设初稿的计算机专业同学以及想通过一个真实项目理解 JSPServlet 请求流转的 Java 学习者。下面我从环境搭建、数据库配置、核心代码结构到常见报错把这份资源完整拆一遍。2. 环境搭建与数据库初始化从零把项目跑起来2.1 开发环境选型与依赖确认这份源码用的是 IDEA MySQL Maven Tomcat 的组合这是目前 Java Web 课程设计最主流的配置。为什么不用 Eclipse因为 IDEA 对 Maven 项目的支持更顺滑pom.xml 改完自动刷新依赖Tomcat 配置也更直观。你需要提前装好 JDK 8 或 11源码的 target 目录显示编译版本是 1.8、MySQL 5.7 或 8.0、Maven 3.6 以上、Tomcat 8.5 或 9.0。注意 Tomcat 10 会有问题因为 Servlet 包名从 javax.servlet 变成了 jakarta.servlet这份源码用的是 javax所以别用 Tomcat 10。pom.xml 里核心依赖是 servlet-api、jsp-api、mysql-connector-java 和 jstl。servlet 和 jsp 的依赖 scope 是 provided因为 Tomcat 自带这些包打包时不需要重复引入。mysql 驱动版本建议用 8.0.x对应驱动类 com.mysql.cj.jdbc.Driver如果是 5.x 版本则用 com.mysql.jdbc.Driver这个在写 JDBC 工具类时要注意区分。!-- pom.xml 核心依赖片段 -- dependencies !-- Servlet APIscope 为 providedTomcat 已自带 -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency !-- JSP API同样由 Tomcat 提供 -- dependency groupIdjavax.servlet.jsp/groupId artifactIdjavax.servlet.jsp-api/artifactId version2.3.3/version scopeprovided/scope /dependency !-- MySQL 驱动8.0 版本对应 cj 驱动类 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency !-- JSTL 标签库JSP 页面里用 c:forEach 遍历数据 -- dependency groupIdjavax.servlet/groupId artifactIdjstl/artifactId version1.2/version /dependency /dependencies这段配置里最容易被忽略的是 scope 标签。servlet-api 和 jsp-api 如果不加 provided打包成 war 后会和 Tomcat 自带的包冲突启动时报 ClassCastException 或者 NoSuchMethodError。mysql 驱动 8.0 以上必须用 com.mysql.cj.jdbc.Driver连接 URL 还要加时区参数 serverTimezoneAsia/Shanghai否则会报时区错误。2.2 数据库建库建表与示例数据导入项目说明里写得很清楚数据库叫 car_data核心表是 fixed_car。建表语句需要覆盖车辆管理的完整字段car_id 作为主键car_color、car_owner、car_brand 是基本信息status 表示车辆状态临时/固定/月租等intime 和 outtime 记录进出时间statusint 是一个整型状态标记。示例数据里那条鲁A09836的记录status 是“临时”intime 和 outtime 相差 18 秒statusint 为 1这条数据可以用来测试查询和修改功能。-- 创建数据库字符集用 utf8mb4 避免中文乱码 CREATE DATABASE car_data DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE car_data; -- 车辆信息表字段类型和项目说明保持一致 CREATE TABLE fixed_car ( car_id VARCHAR(20) NOT NULL COMMENT 车牌号, car_color VARCHAR(10) DEFAULT NULL COMMENT 车辆颜色, car_owner VARCHAR(50) DEFAULT NULL COMMENT 车主姓名, car_brand VARCHAR(50) DEFAULT NULL COMMENT 车辆品牌, status VARCHAR(10) DEFAULT NULL COMMENT 车辆状态临时/固定, intime DATETIME DEFAULT NULL COMMENT 入场时间, outtime DATETIME DEFAULT NULL COMMENT 出场时间, statusint INT DEFAULT 0 COMMENT 状态标记, PRIMARY KEY (car_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 插入示例数据方便启动后直接看到效果 INSERT INTO fixed_car (car_id, car_color, car_owner, car_brand, status, intime, outtime, statusint) VALUES (鲁A09836, 灰色, 杜姆杜姆, 标志, 临时, 2022-12-10 16:45:11, 2022-12-10 16:45:29, 1);建表时注意 car_id 用 VARCHAR 而不是 INT因为车牌号包含汉字和字母。intime 和 outtime 用 DATETIME 类型Java 端用 java.sql.Timestamp 接收。statusint 这个字段在源码里可能用于逻辑判断比如 1 表示已出场、0 表示在场内具体要看 Servlet 里的业务逻辑。导入数据后可以用 SELECT * FROM fixed_car 验证确保中文没有变成问号如果有乱码检查数据库和表的字符集是否都是 utf8mb4。2.3 IDEA 导入项目与 Tomcat 配置把 zip 解压后用 IDEA 的 Open 功能选择项目根目录IDEA 会自动识别 pom.xml 并提示导入 Maven 项目。等依赖下载完成后检查 Project Structure 里的 SDK 是否指向 JDK 8Language level 设为 8。接下来配置 TomcatRun → Edit Configurations → 加号 → Tomcat Server → Local在 Deployment 标签页点加号选 Artifact把 demo2:war exploded 加进去Application context 设为 /car 或者留空。这里有个血泪经验如果 Artifact 列表是空的说明 Maven 还没刷新或者 web 目录没被识别。去 File → Project Structure → Facets 确认 Web 模块的 Web Resource Directory 指向 src/main/webappSource Roots 勾上 src/main/java。配置好后启动 Tomcat浏览器访问 http://localhost:8080/car/ 应该能看到登录页或者车辆列表页。如果 404检查 web.xml 里的 welcome-file 和 Servlet 映射路径是否匹配。提示Tomcat 启动时如果报端口占用改 conf/server.xml 里的 8080 为 8081如果报数据库连接失败先确认 MySQL 服务已启动、car_data 库已建好、用户名密码和 JDBC 工具类里写的一致。3. 核心代码结构拆解Servlet 控制器与 JSP 视图怎么配合3.1 项目目录结构与 MVC 分层逻辑解压后的目录结构是典型的 Maven Web 项目布局src/main/java 放 Java 源码src/main/webapp 放 JSP 页面和 WEB-INFsrc/main/resources 放配置文件target 是编译输出目录。项目说明里提到的 demo2.iml 和 .idea 目录是 IDEA 的工程文件不影响代码逻辑。webContexts.xml 和 artifacts 目录是 IDEA 的部署描述换到 Eclipse 需要重新配置。Java 源码按包名分层常见的是 controller、dao、entity、util 四个包。entity 里放 Car 实体类字段和 fixed_car 表一一对应dao 里放 CarDao 类封装 JDBC 增删改查controller 里放 CarServlet继承 HttpServlet 重写 doGet 和 doPostutil 里放 DBUtil负责获取数据库连接。JSP 页面放在 webapp 下比如 carList.jsp、addCar.jsp、editCar.jsp通过 JSTL 标签遍历 Servlet 传过来的 List 数据。这种分层的好处是职责清晰Servlet 只负责接收请求和转发DAO 只负责数据库操作JSP 只负责展示。课程设计答辩时老师通常会问“你的 MVC 体现在哪里”这套结构就是标准答案。缺点是代码量比 Spring Boot 多每个功能都要写 Servlet 映射和 JDBC 代码但正好用来展示你对基础 API 的掌握。3.2 Servlet 接收请求与 JDBC 操作数据库以车辆列表查询为例CarServlet 的 doGet 方法里先调用 CarDao 的 findAll 方法拿到 List 然后 request.setAttribute(carList, list)最后 request.getRequestDispatcher(/carList.jsp).forward(request, response)。JSP 页面用 c:forEach items${carList} varcar 遍历输出表格。新增车辆时表单 POST 到 CarServletdoPost 里用 request.getParameter 逐个取字段封装成 Car 对象调用 CarDao 的 insert 方法完成后重定向回列表页。// CarServlet 中处理新增车辆的核心逻辑 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置编码防止中文参数乱码 request.setCharacterEncoding(UTF-8); response.setContentType(text/html;charsetUTF-8); // 从表单获取参数字段名要和 JSP 里的 name 属性一致 String carId request.getParameter(carId); String carColor request.getParameter(carColor); String carOwner request.getParameter(carOwner); String carBrand request.getParameter(carBrand); String status request.getParameter(status); // 封装成实体对象 Car car new Car(); car.setCarId(carId); car.setCarColor(carColor); car.setCarOwner(carOwner); car.setCarBrand(carBrand); car.setStatus(status); car.setIntime(new Timestamp(System.currentTimeMillis())); car.setStatusint(0); // 调用 DAO 插入数据库 CarDao dao new CarDao(); boolean success dao.insert(car); if (success) { // 插入成功重定向到列表页避免刷新重复提交 response.sendRedirect(request.getContextPath() /carList); } else { request.setAttribute(msg, 新增失败请检查车牌号是否重复); request.getRequestDispatcher(/addCar.jsp).forward(request, response); } }这段代码的关键点有三个第一request.setCharacterEncoding(UTF-8) 必须放在 getParameter 之前否则中文车主名会乱码第二插入成功后用 sendRedirect 而不是 forward这是 PRG 模式防止用户刷新页面导致重复插入第三car_id 是主键如果插入重复车牌会抛 SQLIntegrityConstraintViolationExceptionDAO 里要 try-catch 并返回 false。DAO 层的 JDBC 代码通常写成这样先从 DBUtil 拿 Connection然后 PreparedStatement 设置参数执行 executeUpdate最后在 finally 块里关闭资源。PreparedStatement 用 ? 占位符能防止 SQL 注入这也是课程设计答辩的加分点。查询操作把 ResultSet 遍历封装成 List注意 Timestamp 转成字符串时格式要统一JSP 里可以用 fmt:formatDate 标签格式化。3.3 JSP 页面数据渲染与表单提交JSP 页面承担视图职责列表页用 JSTL 的 c:forEach 遍历表单页用 form 标签提交到 Servlet。注意表单的 action 要写对路径比如 action${pageContext.request.contextPath}/carServlet?methodaddmethod 参数用来区分是新增还是修改。JSP 顶部要加 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % 引入标签库否则 c:forEach 不生效。!-- carList.jsp 车辆列表渲染片段 -- table border1 cellpadding8 tr th车牌号/thth颜色/thth车主/thth品牌/thth状态/thth操作/th /tr c:forEach items${carList} varcar tr td${car.carId}/td td${car.carColor}/td td${car.carOwner}/td td${car.carBrand}/td td${car.status}/td td a hrefcarServlet?methodeditcarId${car.carId}编辑/a a hrefcarServlet?methoddeletecarId${car.carId} onclickreturn confirm(确认删除)删除/a /td /tr /c:forEach /table这段 JSP 里 ${car.carId} 是 EL 表达式会自动调用 Car 类的 getCarId 方法。删除链接加了 onclick 确认框防止误操作。编辑链接把 carId 作为参数传给 ServletServlet 根据 methodedit 调用 DAO 的 findById 方法把查到的 Car 对象放到 request 域forward 到 editCar.jsp 回显数据。整个流程走下来就是一个完整的增删改查闭环。注意JSP 页面里不要写太多 Java 代码% % 脚本片段越少越好用 JSTL 和 EL 表达式替代。如果 c:forEach 不生效检查 jstl 依赖是否引入、taglib 指令是否写对、web.xml 的版本是否支持 JSTL。4. 避坑与常见问题排查那些让你卡半天的报错4.1 数据库连接失败与中文乱码现象Tomcat 启动后访问页面报 500控制台堆栈显示 CommunicationsException 或 Access denied for user。原因通常是三种MySQL 服务没启动、car_data 库没建、JDBC 工具类里的用户名密码和实际不一致。解决方法是先用命令行 mysql -u root -p 登录确认 car_data 存在且 fixed_car 表有数据然后检查 DBUtil 里的 URL 是不是 jdbc:mysql://localhost:3306/car_data?useSSLfalseserverTimezoneAsia/Shanghai用户名密码改成自己的。中文乱码分两种场景数据库里存的中文变成问号或者页面显示的中文变成乱码。前者检查建库建表时字符集是否 utf8mb4后者检查 Servlet 里有没有 request.setCharacterEncoding(UTF-8) 和 response.setContentType(text/html;charsetUTF-8)。JSP 页面顶部加 % page contentTypetext/html;charsetUTF-8 languagejava %。三个地方都设了基本就不会乱码。4.2 Tomcat 启动报错与 404 问题现象Tomcat 启动时控制台报 ClassNotFoundException: com.mysql.cj.jdbc.Driver或者启动成功但访问页面 404。原因一是 mysql 驱动没打进 WEB-INF/libIDEA 里检查 Project Structure → Artifacts → 右侧 WEB-INF/lib 里有没有 mysql-connector-java 的 jar原因二是 Servlet 映射路径写错web.xml 里 url-pattern 是 /carServlet浏览器访问就要带这个路径。404 还有一个常见原因是 Application context 配错了。IDEA 的 Tomcat 配置里 Deployment 标签页有个 Application context如果设成 /car访问地址就是 http://localhost:8080/car/如果留空就是 http://localhost:8080/。很多人改了 context 但浏览器还用旧地址自然 404。另外检查 web.xml 的 welcome-file-list 里有没有 index.jsp没有的话访问根路径不会自动跳转。4.3 JSTL 标签不解析与 EL 表达式失效现象JSP 页面直接把 c:forEach 原样输出到浏览器或者 ${car.carId} 显示成字符串而不是具体值。原因是 jstl 依赖没引入或者 taglib 指令写错。检查 pom.xml 里有没有 jstl 1.2 的依赖JSP 顶部有没有 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %。如果用的是 Tomcat 10javax 包名要换成 jakarta但这份源码是 javax 体系所以 Tomcat 版本别超过 9。EL 表达式失效还有一种可能是 web.xml 的版本太低。如果 web.xml 声明的是 2.3 版本EL 默认不启用要在 page 指令里加 isELIgnoredfalse。建议直接把 web.xml 改成 4.0 版本头信息用 xmlnshttp://xmlns.jcp.org/xml/ns/javaee这样 Servlet 4.0 和 EL 3.0 都默认支持。4.4 表单提交后数据不入库或重复插入现象点了新增按钮页面跳转了但数据库里没数据或者刷新页面后同一条数据插入了两次。原因一是表单字段的 name 属性和 Servlet 里 getParameter 的参数名不一致比如表单写 car_id 但 Servlet 取 carId取到 null 自然插不进去原因二是插入成功后用了 forward 而不是 sendRedirect用户刷新页面会重复提交上一次请求。解决方法是逐个核对表单 name 和 getParameter 的字符串大小写敏感。插入成功后统一用 response.sendRedirect(request.getContextPath() /carList) 重定向到列表页。如果数据库有唯一索引重复插入会抛异常DAO 里 catch 住返回 falseServlet 里给用户提示“车牌号已存在”。4.5 修改和删除功能点不动或报主键冲突现象点编辑链接没反应或者点删除后报 SQLIntegrityConstraintViolationException。原因一是编辑链接的参数名写错比如 href 里写 carId 但 Servlet 里取 id原因二是删除时没有先删关联表数据如果 fixed_car 被其他表外键引用直接删会报约束冲突。这份源码只有一张表所以主键冲突通常出现在新增重复车牌时。排查时先在浏览器地址栏看点击链接后的 URL 参数对不对然后在 Servlet 里加 System.out.println 打印接收到的参数值。删除操作建议先查再删确认 carId 存在再执行 delete避免误删。如果用了外键先删子表再删主表或者设置级联删除。5. 进阶技巧把课程设计改成能写进简历的项目5.1 从 JDBC 直连升级到 MyBatis-Plus这份源码用的是原生 JDBC代码里到处是 try-catch-finally 和手动封装 ResultSet。如果你想让它看起来更像企业项目可以把 DAO 层换成 MyBatis-Plus。MyBatis-Plus 的 BaseMapper 自带 insert、deleteById、updateById、selectList 方法实体类加 TableName(fixed_car) 和 TableId 注解就能自动映射连 SQL 都不用写。升级后代码量减少一半答辩时还能讲“我用了 ORM 框架提升开发效率”。// MyBatis-Plus 版本的 CarMapper替代原来的 CarDao Mapper public interface CarMapper extends BaseMapperCar { // 继承 BaseMapper 后自动拥有 CRUD 方法 // 复杂查询可以在这里写自定义 SQL } // 实体类加注解映射表名和主键 TableName(fixed_car) public class Car { TableId(value car_id, type IdType.INPUT) private String carId; TableField(car_color) private String carColor; // 其他字段省略 getter/setter }升级步骤是pom.xml 加 mybatis-plus-boot-starter 依赖application.yml 配数据源启动类加 MapperScan 注解然后把 CarDao 里的方法替换成 CarMapper 的调用。注意 MyBatis-Plus 默认把驼峰字段转下划线carId 自动映射 car_id如果字段名不一致用 TableField 指定。这样改完项目就从“课程设计”变成了“Spring Boot MyBatis-Plus”的技术栈简历上能多写一行。5.2 增加分页查询和条件搜索原来的列表页是全量查询数据一多页面就卡。可以加分页功能前端传 pageNum 和 pageSize后端用 LIMIT 语句查询。MyBatis-Plus 有 Page 对象传进去自动分页。条件搜索按车牌号模糊查SQL 用 LIKE CONCAT(%, ?, %)Servlet 里判断参数不为空才拼条件。// 分页查询示例pageNum 当前页pageSize 每页条数 public PageCar findByPage(int pageNum, int pageSize, String keyword) { PageCar page new Page(pageNum, pageSize); QueryWrapperCar wrapper new QueryWrapper(); if (keyword ! null !keyword.isEmpty()) { wrapper.like(car_id, keyword); } return carMapper.selectPage(page, wrapper); }分页后 JSP 页面要加翻页按钮显示总页数和当前页。搜索框提交到 Servlet 时带上 keyword 参数Servlet 把 keyword 和分页结果一起放到 request 域JSP 回显搜索关键词。这样改完项目就有了“分页 搜索”的实用功能比单纯的增删改查更有说服力。5.3 用 Postman 验证接口和写测试用例课程设计通常不要求写测试但如果你想让项目更完整可以用 Postman 测 Servlet 接口。把 Tomcat 启动后用 Postman 发 GET 请求到 http://localhost:8080/car/carServlet?methodlist看返回的 JSON 或 HTML 是否正确。新增接口用 POST 请求Body 里填表单参数。测试通过后再写 JUnit 测试用例测 DAO 层的 insert 和 findById 方法用 Before 初始化数据库连接After 关闭资源。// JUnit 测试 CarDao 的插入和查询 public class CarDaoTest { private CarDao dao; Before public void setUp() { dao new CarDao(); } Test public void testInsertAndFind() { Car car new Car(); car.setCarId(京B12345); car.setCarColor(白色); car.setCarOwner(测试车主); car.setCarBrand(比亚迪); car.setStatus(临时); car.setIntime(new Timestamp(System.currentTimeMillis())); car.setStatusint(0); boolean success dao.insert(car); assertTrue(success); Car found dao.findById(京B12345); assertNotNull(found); assertEquals(测试车主, found.getCarOwner()); } }写测试的好处是改代码时能快速验证有没有改坏答辩时老师看到测试用例也会加分。注意测试用的数据库和正式库分开避免污染数据。测试完记得删掉测试数据或者用 Transactional 注解让事务回滚。5.4 打包部署与常见部署问题项目开发完后要打包成 war 部署到 Tomcat。IDEA 里用 Maven 的 package 命令target 目录下会生成 demo2-1.0-SNAPSHOT.war把这个文件复制到 Tomcat 的 webapps 目录启动 Tomcat 会自动解压部署。访问地址是 http://localhost:8080/demo2-1.0-SNAPSHOT/。如果报 404检查 war 包名和访问路径是否一致。部署到服务器时注意数据库连接地址要改成服务器的 IP不能用 localhost。如果服务器上 MySQL 端口不是 3306JDBC URL 里要改。另外 war 包里的 WEB-INF/lib 要包含 mysql 驱动Maven 打包时 scope 为 provided 的依赖不会打进去所以 servlet-api 和 jsp-api 不会在 lib 里这是正常的Tomcat 自带。mysql 驱动的 scope 是 compile会正常打包。从那以后我每次交课程设计前都会先在本地 Tomcat 跑一遍完整流程建库建表、导入数据、启动项目、走一遍增删改查、再打包部署到另一个 Tomcat 验证。这套流程走通基本不会在答辩现场翻车。希望帮到你。本文还有配套的精品资源点击获取