简介:基于Java Server Pages(JSP)技术的CIMS课程设计源码,面向高校软件工程、计算机相关专业学生,尤其适合正在完成课程设计或需要传统Java Web开发案例的初学者。项目包含212个文件,压缩包约15.2MB,涵盖JSP视图页面、Java业务逻辑源码、XML配置、JAR依赖库、CSS样式、JavaScript脚本以及SQL数据库脚本等类型,配置与静态资源齐全,可帮助理解从数据库设计到前端展示的完整开发链路。资源按标准Web工程结构组织,清晰展示了控制器、服务层、实体类等分层设计,并包含用户管理、客户管理等典型业务模块。已有103人学习使用,可作为课程设计与毕业设计参考。学习者可借此掌握JSP动态页面生成、Servlet处理请求、JDBC操作数据库及前端交互实现等关键技能,也能为后续开发同类管理信息系统提供可直接借鉴的代码模板与设计思路。
1. 基于 Java Server Pages 技术的 CIMS 课程设计源码:先看清它要你做什么
很多同学拿到“基于 Java Server Pages 技术的 CIMS 课程设计源码”时,第一反应是去搜 CIMS 到底指什么。它全称 Computer Integrated Manufacturing System,直译是计算机集成制造系统,但课程设计一般不会让你去写车间设备控制,而是把制造企业的信息管理流程做成一个可运行的 Web 系统:用户登录、生产计划、物料库存、工单跟踪。真正决定成绩的往往不是功能多新,而是源码分层清楚、关键表之间有外键关系、答辩时每个文件都能说清存在意义。下面内容就围绕这样一份 JSP 课程设计源码展开,适合正在赶 Java Web 课设,或者需要从网上下载 java 课程设计案例源码来改造的读者。
2. 为什么这份 CIMS 源码要用 JSP:模块拆分与三层架构选型
2.1 课程设计里的 CIMS 不是完整制造系统,而是四类业务加四张表
在工业软件里,CIMS 覆盖 ERP、MES、设备控制,做完是一整套大型系统。但 JSP 课程设计通常只要求你实现一个“做得通”的管理信息子系统。我一般会把需求收敛成四类业务:用户管理,负责登录、退出并区分管理员和普通操作员;生产计划管理,负责新增计划和查询计划;物料库存管理,维护物料档案并查看存量;工单跟踪,查看计划下达后的完成状态。对应的表最少只需要四张:t_user、t_plan、t_material和t_work_order。
很多网上的课程设计源码在这一层就出问题:表之间没有外键,生产计划不引用物料,库存扣减写死在前台页面里。课程设计的评分点恰恰是“模块之间有没有数据关系”。比如一次新增计划时,系统要检查物料库存并扣减,而不是把计划表和物料表做成两个孤岛。所以在动手改源码前,先画一遍业务关系:一条生产计划消耗一种物料,物料库存低于最低库存时给出提示。这个关系会决定后续 DAO 方法的数量、Servlet 的跳转方式,以及 JSP 页面要展示什么。
我用一张验收清单来约束课设工作量,也推荐你这么做:
| 功能 | 页面入口 | DAO 方法 | 数据库影响 |
|---|---|---|---|
| 登录 | login.jsp | findByUsernameAndPassword | 查询 t_user |
| 计划列表 | planList.jsp | findAllWithMaterial | 联表查询 t_plan、t_material |
| 新增计划 | planEdit.jsp | insertWithStockCheck | 插入 t_plan,扣减 t_material |
功能宁可少,这条数据链路不能断。只要这三条链路能跑通,答辩时的“系统演示”任务就已经完成了大半。
2.2 为什么 JSP + Servlet + JDBC 比 Spring Boot 更适合这个课设
如果只追求“能跑”,用 Spring Boot 当然也可以,但对你手里这类源码并不友好。市面上的 java 课程设计案例源码大量基于 JSP + Servlet + JavaBean 的老三层结构,直接导入 Tomcat 就能启动,不需要 Maven 解析几十个依赖,也不需要理解启动类上的自动配置。JSP 页面本身是服务端模板,浏览器看到的是渲染后的 HTML,答辩时你可以直接在页面上说“这一块是 JSP 输出的”,比讲一层 Vue 前后端分离省力得多。
另外,题目写明“基于 Java Server Pages 技术”,评分标准里大概率包含 JSP 页面数量、Servlet 跳转、表单处理这些传统 JSP 技术点。用 JSP 是风险最低的选项。我见过不少同学用 Spring Boot 完成课设,老师只看了一眼就说“这不是 JSP 题目”,最后只能临时补页面,得不偿失。JSP 的明显短板是脚本片段一多,页面会变成“面条代码”;所以下面会反复强调分层,把 Java 代码尽量放到 DAO 和 Servlet,JSP 只负责循环和展示。
2.3 Servlet、JavaBean、DAO 的边界:一个请求从浏览器到数据库再返回
CIMS 源码里最需要理解的是请求流转。一次登录请求的路径是这样:浏览器 POST 到/login,Tomcat 按@WebServlet注解找到 LoginServlet;Servlet 读取表单参数,调用 UserDAO;UserDAO 里用 JDBC 执行 SQL;结果封装成 User 这个 JavaBean;Servlet 把 JavaBean 放进 session,再重定向到计划列表页。JSP 不在这个链路的开头,而是在后端数据准备完之后,负责把结果拼成 HTML。
我习惯让三种文件各守边界。JavaBean 只有属性和 getter/setter,不写业务;DAO 只写 SQL 和结果映射;Servlet 只做参数校验、调用 DAO、决定跳转;JSP 里不出现复杂逻辑。这样划分之后,代码量没有减少,但每一层的改动都能被定位:页面样式变了只改 JSP,查询条件变了只改 DAO,流程跳转变了只改 Servlet。答辩时被问“每层会不会写重”,也可以直接拿这个分层回答。
最小 User 实体可以这么写:
package com.cims.bean; public class User { private Integer id; private String username; private String password; private String role; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } }这个类没有任何框架注解,Tomcat 容器不直接认识它,它只是数据载体。课程设计里不引 MyBatis 的情况下,所有表查询结果都要手动“set 到这个 POJO”。很多源码会在 DAO 里直接返回 ResultSet 给 JSP 用,那样会让 JSP 页面出现rs.next(),代码能跑但答辩容易露怯,不建议模仿。
2.4 表单提交地址别写错:相对路径与 JSP 的 contextPath
新手最容易翻车的地方,其实是 JSP 表单里的地址。登录表单的 action 应该写成:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE html> <html> <head><meta charset="UTF-8"><title>CIMS 登录</title></head> <body> <form action="${pageContext.request.contextPath}/login" method="post"> 用户名:<input type="text" name="username" /> 密码:<input type="password" name="password" /> <input type="submit" value="登录" /> </form> </body> </html>${pageContext.request.contextPath}会动态拼上项目部署路径,比如/cims。如果直接写死action="/login",浏览器会往http://localhost:8080/login发,根本到不了你的项目;写死/cims/login又会在项目改名后 404。课程设计里的所有表单、链接、sendRedirect都应该用这个表达式拼前缀。这是 JSP 技术里最实用也最容易被忽略的一个细节。
项目里通常还会配一个web.xml欢迎页:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="3.1"> <display-name>cims-course</display-name> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app>如果登录页放到了WEB-INF目录下,欢迎页就不能直接指向它,必须通过 Servlet 跳转。我的习惯是登录页放根目录,其余受保护页面全部走 Servlet,这样权限控制才不会被绕过。
3. 拆解 CIMS 源码:目录结构、建表脚本与登录链路
3.1 先把源码结构对齐:包名和 jsp 各管什么
一份能让人看懂的 JSP 课程设计源码,目录通常长这样:
cims-course/ ├── src/ │ └── com/cims/ │ ├── bean/ # JavaBean,表数据载体 │ │ ├── User.java │ │ ├── Plan.java │ │ └── Material.java │ ├── dao/ # 数据库访问层 │ │ ├── DBUtil.java │ │ ├── UserDAO.java │ │ └── PlanDAO.java │ └── servlet/ # 请求控制层 │ ├── LoginServlet.java │ └── PlanServlet.java ├── WebContent/ │ ├── WEB-INF/ │ │ ├── web.xml │ │ └── lib/ │ │ └── mysql-connector-java-8.0.x.jar │ ├── login.jsp │ ├── index.jsp │ ├── planList.jsp │ └── planEdit.jsp ├── cims.sql └── readme.txt拿到源码后,不要先从 login.jsp 看起。我看代码的习惯是反着来:先看 cims.sql 弄清有哪些表和字段;再看WEB-INF/lib确认 JDBC 驱动版本;接着看 DBUtil.java 里的连接串和账号密码;最后才看 Servlet 和 JSP。原因简单,课程设计源码最常见的坏毛病是“建表脚本都有语法错误”,先确认数据库层面能落地,比逐行读页面高效。
WEB-INF是 JSP 规范里的受保护目录,放在里面的 JSP 不能被浏览器直接访问。登录页如果放在WEB-INF下,就必须通过 Servlet 跳转来打开。我一般把 login.jsp 放在WebContent根目录,需要登录才能看的页面全放在 Servlet 保护下。如果你看到的源码把 index.jsp 放进了WEB-INF,记得检查欢迎页配置是不是对不上。
3.2 最小建表脚本:用户表、物料表、生产计划表
下面这个脚本足够支撑登录、计划展示和库存扣减,字段命名也方便实体类映射:
CREATE DATABASE IF NOT EXISTS cims DEFAULT CHARACTER SET utf8mb4; USE cims; CREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(64) NOT NULL, role VARCHAR(20) DEFAULT 'operator' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE t_material ( id INT PRIMARY KEY AUTO_INCREMENT, material_code VARCHAR(50) NOT NULL UNIQUE, material_name VARCHAR(100) NOT NULL, stock INT NOT NULL DEFAULT 0, min_stock INT NOT NULL DEFAULT 10 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE t_plan ( id INT PRIMARY KEY AUTO_INCREMENT, plan_no VARCHAR(50) NOT NULL UNIQUE, product_name VARCHAR(100) NOT NULL, quantity INT NOT NULL, material_id INT NOT NULL, status VARCHAR(20) DEFAULT 'pending', create_time DATETIME, CONSTRAINT fk_plan_material FOREIGN KEY (material_id) REFERENCES t_material(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT INTO t_user (username, password, role) VALUES ('admin', '123456', 'admin');设计上有三个关键点。第一,t_plan.material_id必须引用t_material.id,这样计划才能和库存数据产生真实关联,新增计划时才能带出“这个产品消耗什么物料、库存够不够”的信息。第二,status用pending/finished这类短字符串,比数字更直观,答辩时也好解释。第三,字符集统一utf8mb4,既能兜住产品名称里的中文,也避免后面 JDBC 连接串里 characterEncoding 和表字符集对不上。
password字段我写成 64 位,就是提醒你:课程设计里明文密码能跑,但如果想把这套代码放到简历项目,至少把密码改成 MD5 或 BCrypt 的哈希。第 6 章会讲权限和事务,密码这点先立个规矩,不要在课设里留明文密码给老师挑毛病。
3.3 登录链路:从 JSP 表单到 DAO 查询
登录 Servlet 的核心逻辑如下:
package com.cims.servlet; import java.io.IOException; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import com.cims.bean.User; import com.cims.dao.UserDAO; @WebServlet("/login") public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String username = request.getParameter("username"); String password = request.getParameter("password"); UserDAO userDAO = new UserDAO(); User user = null; try { user = userDAO.findByUsernameAndPassword(username, password); } catch (SQLException e) { e.printStackTrace(); request.setAttribute("error", "数据库查询失败,请查看控制台日志"); request.getRequestDispatcher("/login.jsp").forward(request, response); return; } if (user == null) { request.setAttribute("error", "用户名或密码错误"); request.getRequestDispatcher("/login.jsp").forward(request, response); } else { request.getSession().setAttribute("user", user); response.sendRedirect(request.getContextPath() + "/planList"); } } }这里有三个设计点。第一,request.setCharacterEncoding("UTF-8")必须写在读取参数之前,否则中文用户名会乱码。第二,结果被分成“查询异常”“无此用户”“成功”三路:异常和失败路径用forward回登录页,把错误信息塞到 request;成功路径用sendRedirect,让浏览器重新发起 GET 请求到计划列表,避免刷新页面时重复提交登录表单。第三,sendRedirect的地址仍然用request.getContextPath()拼接,不能写死。
DAO 侧的对应实现:
package com.cims.dao; import java.sql.*; import com.cims.bean.User; public class UserDAO { public User findByUsernameAndPassword(String username, String password) throws SQLException { String sql = "SELECT id, username, password, role FROM t_user WHERE username = ? AND password = ?"; try (Connection conn = DBUtil.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, username); ps.setString(2, password); try (ResultSet rs = ps.executeQuery()) { if (rs.next()) { User user = new User(); user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setPassword(rs.getString("password")); user.setRole(rs.getString("role")); return user; } } } return null; } }用PreparedStatement而不是字符串拼接 SQL,是为了避开 SQL 注入。你可以故意在用户名框输入' or '1'='1试试,没做参数化的代码直接就能登录,答辩时这是送命题。try-with-resources会帮你自动关闭连接、语句和结果集,但要注意一点:连接关闭得越早,后面做事务越受限。所以第 6 章写事务时,DAO 里的连接不能自己提前关,必须由调用方统一管理。
4. 把源码跑起来:Eclipse、Tomcat、MySQL 的部署与配置
4.1 导入 Eclipse 并挂到 Tomcat:完整的项目导入三步
老式 JSP 项目在 Eclipse 里的导入路径是固定的。
第一步,File > Import > General > Existing Projects into Workspace,选择源码根目录,如果 Eclipse 能识别出项目,勾选 Copy projects into workspace 后点 Finish。如果导入后项目没有显示成 Java Web 项目,通常是缺少.project和.classpath,我会新建一个 Dynamic Web Project,再把源码和WebContent按目录拷进去。
第二步,右键项目Properties > Targeted Runtimes,勾选你本机的 Tomcat 版本,比如 Tomcat v9.0。不勾选的话,项目在 Eclipse 里可能不报错,但部署到 Tomcat 时找不到javax.servlet相关类。
第三步,在 Servers 面板新建 Server,选择 Apache Tomcat v9.0,指定 Tomcat 安装目录,然后把项目 Add 到 Configured 列表,启动。等控制台出现INFO: Server startup就说明 Tomcat 已经起来了。如果你的源码是 Maven 结构,导入方式会不同,但课程设计极少用 Maven,这里以 Eclipse 传统目录为准。
4.2 JDBC 连接参数:三处必改,改完至少能连上数据库
数据库连接的核心全在 DBUtil.java:
package com.cims.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class DBUtil { private static final String URL = "jdbc:mysql://localhost:3306/cims" + "?useUnicode=true&characterEncoding=utf-8" + "&useSSL=false&serverTimezone=Asia/Shanghai" + "&allowPublicKeyRetrieval=true"; private static final String USER = "root"; private static final String PASSWORD = "你的MySQL密码"; private static final String DRIVER = "com.mysql.cj.jdbc.Driver"; static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } }三个最容易改错的地方。第一,DRIVER字符串。MySQL 8 对应com.mysql.cj.jdbc.Driver,老资料里写com.mysql.jdbc.Driver在 MySQL 8 下有时能跑但会有警告;反过来,驱动 jar 是 5.x,却写了cj,直接抛ClassNotFoundException。第二,serverTimezone。MySQL 8 不带这个参数会报时区错,Asia/Shanghai是面向国内服务器的常规值。第三,allowPublicKeyRetrieval=true。MySQL 8 的 caching_sha2_password 认证在非 SSL 连接下需要这个参数,不加会报Public Key Retrieval is not allowed,这一条在第 5 章还会再展开。
密码直接写在源码里不是好习惯,但课程设计里能用。更稳妥的做法是维护一个config.properties,用类加载器读取,演示时可以不解码源码就换密码。你要是怕答辩问安全性,至少把账号密码从代码里拆出去,这是实际加分点。
4.3 初始化数据库:命令行导入 cims.sql
假设 MySQL 服务已经启动,打开终端导入脚本:
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS cims DEFAULT CHARACTER SET utf8mb4;" mysql -u root -p cims < /path/to/cims.sql第一条命令建库,第二条命令把表结构和初始数据导入 cims 库。Windows 下路径里的反斜杠要改成正斜杠,否则重定向会解析失败。如果 cims.sql 里已经写了USE cims;,第二条命令的cims参数可以省略,但为了明确,我每次都会带库名。
导入后检查一下:
USE cims; SHOW TABLES; SELECT * FROM t_user;能看到三张表和一行 admin 用户,说明数据库 OK。后续改表结构时,建议每次先从备份文件重新导入,不要手删手建。课程设计阶段表结构变动频繁,手动删表容易漏外键约束,留下隐藏故障。
4.4 启动验证与 Tomcat 端口调整
数据库就绪后,访问http://localhost:8080/cims/login.jsp。第一次访问 JSP 会被 Tomcat 编译,首屏可能慢两秒。如果出现目录列表而不是登录页,说明 web.xml 的欢迎页写成了/login.jsp,但文件放在WEB-INF下;把 login.jsp 移到WebContent根目录即可。
如果 8080 被其他程序占用,Tomcat 启动失败,控制台报Port 8080 required by Tomcat ... is already in use。解决办法是改Tomcat/conf/server.xml里的连接端口:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />把 port 改成 8088,重启 Tomcat 后访问http://localhost:8088/cims/login.jsp。改端口是排查手段,不是项目功能,答辩时如果现场端口被占,改一次即可。
5. CIMS 课程设计常见问题排查:五个让现场演示翻车的坑
5.1 MySQL 8 报 Public Key Retrieval is not allowed:换驱动也没用
- 现象:Tomcat 启动正常,页面也能打开,输入 admin 和 123456 点登录后,控制台出现
Public Key Retrieval is not allowed,浏览器停在登录页或直接 500。 - 原因:MySQL 8 默认用户使用 caching_sha2_password 认证。客户端在没有 SSL 加密的情况下要取服务器公钥来加密密码,而 JDBC 驱动默认禁止这种公钥获取行为。换新版驱动不等于解决认证方式,需要在连接参数里显式放开。
- 解决:在 JDBC URL 上追加
allowPublicKeyRetrieval=true,同时确认 mysql 连接 jar 与服务端 MySQL 大版本不要差太多。我通常直接使用 4.2 节里的完整 URL,再把 MySQL 用户的认证插件改成 mysql_native_password 作为后备方案。两个做法在课程设计里都能交差,但前者更接近工程习惯。
5.2 页面中文全部变问号:字符集要四个地方保持一致
- 现象:登录页中文正常,登录后计划列表里的产品名称显示成问号;或者反过来,页面源码是 UTF-8,数据库里却是 latin1。
- 原因:JSP 页面、Servlet 请求、JDBC 连接、MySQL 表字段,四个环节只要有一个字符集不一致,中文就可能被换码。最常见的是只改了 JSP 的 pageEncoding,没改 URL 里的 characterEncoding;或者建表用了 latin1。
- 解决:按清单逐项对齐。JSP 第一行写
contentType="text/html; charset=UTF-8" pageEncoding="UTF-8";Servlet 读取参数前写request.setCharacterEncoding("UTF-8");JDBC URL 加useUnicode=true&characterEncoding=utf-8;建表统一DEFAULT CHARSET=utf8mb4。演示机器上的 MySQL 全局字符集也建议改成 utf8mb4,避免某些表继承了服务端老配置。
5.3 部署后访问一直 404:Context Path 和 Servlet 映射各查一遍
- 现象:Tomcat 启动成功,但访问
http://localhost:8080/cims/planList返回 404;login.jsp 正常,登录后一跳转又 404。 - 原因:Servlet 注解写的是
@WebServlet("/planList"),浏览器地址却漏掉了项目上下文/cims。另一个常见原因是项目被部署成了别的名字,比如 cims-course,Context Path 不再是 cims。 - 解决:先看控制台启动日志确认实际路径,再统一用
${pageContext.request.contextPath}拼页面里的链接和sendRedirect地址,不要在 HTML 和 Java 代码里写死/cims。如果是 Eclipse,右键项目Properties > Web Project Settings能直接改 Context root。
5.4 JSP 编译报错找不到 javax.servlet:项目缺 Tomcat 运行时
- 现象:项目里所有 Servlet 和 JSP 文件都画红叉,提示
The import javax.servlet cannot be resolved,但 Tomcat 控制台没有错误。 - 原因:项目的编译路径没有加入 Tomcat 运行时。Eclipse 里服务器运行时和 JRE 是分开配置的,必须显式把 Tomcat 提供的 servlet-api 加到项目的 Build Path。
- 解决:项目右键
Build Path > Configure Build Path > Libraries > Add Library > Server Runtime,选择本机配置的 Tomcat。直接下载一个javax.servlet-apijar 放到 WEB-INF/lib 也能消除红叉,但用 Server Runtime 更干净,部署时不会把这个 jar 复制到服务器。不要从 Tomcat 安装目录把 servlet-api.jar 复制到项目 lib 里,容易和容器版本冲突。
5.5 表单刷新重复提交数据:POST 后要用重定向而不是转发
- 现象:登录成功后按 F5,浏览器提示重新发送表单;新增计划时连续提交,数据库里出现多条相同记录。
- 原因:Servlet 在写库后使用
request.getRequestDispatcher("/xxx.jsp").forward(...),地址栏不变,浏览器刷新会重放上一次 POST。登录成功、新增计划、修改状态这些写操作最容易踩到。 - 解决:使用 Post/Redirect/Get 模式。登录成功或数据写库后,用
response.sendRedirect(request.getContextPath() + "/planList")让浏览器发新的 GET 请求;只有表单校验失败时才 forward 回原页面并展示错误。还可以在 JSP 里用一次性 token 防双点提交,课设不要求,但能在答辩时显得你考虑过重复提交问题。
6. 让 CIMS 源码在答辩里更像自己写的:权限过滤和事务补偿
6.1 加一个登录过滤器,堵住“绕过登录直接访问”
课设演示时,有人会登录后直接输入planList.jsp的地址访问页面。如果没做权限控制,别人不登录也能看到数据。加一个 Filter 并不难:
package com.cims.filter; import java.io.IOException; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.*; @WebFilter("/plan/*") public class LoginFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; HttpSession session = request.getSession(false); if (session == null || session.getAttribute("user") == null) { response.sendRedirect(request.getContextPath() + "/login.jsp"); return; } chain.doFilter(request, response); } }@WebFilter("/plan/*")只拦以 /plan 开头的路径,这是我有意约定的:计划相关 Servlet 统一放在/plan/xxx下,过滤器就能覆盖。如果你把受保护页面散落在根目录 JSP,Filter 拦不住,因为直接访问 JSP 不经过/plan/*映射。更稳的做法是让受保护页面全部通过 Servlet 转发,JSP 放WEB-INF,外部永远无法直接访问。
6.2 把“创建计划 + 扣库存”放进一个事务
如果 CIMS 只剩下单表 CRUD,答辩会显得没有业务逻辑。一个常见加分业务是:新增生产计划时同时扣减物料库存,任何一个操作失败都不能生效。用 JDBC 手写事务:
Connection conn = null; try { conn = DBUtil.getConnection(); conn.setAutoCommit(false); PlanDAO planDAO = new PlanDAO(conn); MaterialDAO materialDAO = new MaterialDAO(conn); planDAO.insert(plan); materialDAO.decreaseStock(plan.getMaterialId(), plan.getQuantity()); conn.commit(); } catch (SQLException e) { if (conn != null) { conn.rollback(); } throw e; } finally { if (conn != null) { conn.setAutoCommit(true); conn.close(); } }这段代码把 Connection 从 DAO 私有方法提升到调用层,让两个 DAO 共享同一个连接。三个细节值得记:setAutoCommit(false)必须在第一条 SQL 之前;commit放在所有 DAO 调用之后;finally 里要恢复自动提交再关连接。很多参考代码只在 catch 里 rollback,忘记 setAutoCommit(true),连接带着半事务状态回到池里,下一次查询就会卡住。
这几件事做完,源码就不再是“登录加增删改查”。我自己的习惯是答辩前把边界情况全预演一遍:物料不够怎么办?连接中断怎么办?用户直接输入后台 URL 怎么办?把这些场景对应到代码里,比背十张表结构更能说明项目是你自己改的。希望帮到你。
本文还有配套的精品资源,点击获取