拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于JSP+Servlet+JDBC的学生请假系统课设拆解指南

简介基于 jspservletjdbc 实现的学生请假信息管理系统课程设计面向高校学生完成 Java Web 课设或毕业设计定位清晰。系统围绕学生、辅导员、宿管员三类角色展开包含个人信息查看、晚归记录、请假单填写与审核、班级与课程基础信息管理等功能前后端层次清晰可直接体验完整业务流转宿管员模块也保留了扩展空间。资源共117个文件压缩包约2.25MB主体为78个jsp页面、5个java源码及其对应class文件、2个sql数据库脚本另有jar依赖、css/js与项目配置文件导入数据库并部署即可运行便于二次修改。压缩包内置三组测试账号分别对应学生、辅导员、宿管员可快速登录验证不同权限的操作流程。已有2404人学习下载适合需要快速搭建课设原型、理解ServletJDBCJSP分层开发的初学者或中级开发者。1. 基于 jspservletjdbc 的学生请假系统课设怎么拆才省事java 课程设计要交差很多人会盯上 jspservletjdbc 学生请假信息管理系统这类选题。这包里的东西也确实是课设标配三个登录角色、请假审核流程、晚归记录导出按理说写完就能答辩。但真打开源码包你会发现里面除了 jsp 页面还有一堆编译好的 class 文件、pintuer.css 这种第三方 UI以及一个要自己导入的数据库。第一次接触的人很容易卡在“这到底怎么跑起来”这一关。这套系统其实是个标准的前后端不分离项目servlet 处理请求jdbc 连 MySQLjsp 负责渲染前端套的是经典蓝色后台模板。它适合想快速交差或者想完整练一遍 JavaWeb 基础链路的同学。本文我按实际拆包顺序讲透登录角色、请假审核链、以及几个必踩的坑。2. 登录与角色路由从数据库账号到三个面板的权限分配2.1 登录验证与 session 记角色先看登录这块。系统里三个账号学生 1/1辅导员 2/2宿管员 3/3。密码默认和用户名一样这种设计在课设里大量存在因为老师重点看的是功能链路不是安全强度。登录的核心逻辑是用户提交用户名密码servlet 从请求里拿参数查 user 表比对通过后把用户实体和角色 type 存进 session。因为 jsp 页面要反复判断当前登录的是谁session 里存一个 role 字段最省事。// LoginServlet 核心逻辑常见实现示意 String username request.getParameter(username); String password request.getParameter(password); UserDao dao new UserDao(); User user dao.findByUsernameAndPassword(username, password); if (user ! null) { HttpSession session request.getSession(); session.setAttribute(loginUser, user); session.setAttribute(role, user.getRole()); response.sendRedirect(index.jsp); // 登录成功统一跳入口页 } else { request.setAttribute(msg, 用户名或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); }这里有个关键点findByUsernameAndPassword返回的 User 对象里role字段来自数据库的 user 表。response.sendRedirect是重定向这样地址栏会变成 index.jsp刷新页面时不会重复提交登录表单用 forward 虽然能带 request 里的 msg但刷新会重复登录。课设里两种写法都有建议登录成功后一律重定向。再说密码存储。源码包里有CodeUtil.class和CheckCode.class说明登录页其实还带验证码功能。CheckCode 负责生成图片CodeUtil 处理验证码字符串和 session 比对。如果你嫌麻烦可以在登录表单里删掉验证码这一项但不建议因为答辩老师很可能会问“验证码是怎么防刷的”。2.2 三个角色的菜单与 jsp 个人信息展示页面登录后 index.jsp 根据 session 里的 role 显示不同菜单。这个可以用 jsp 的 if 判断实现也可以用权限拦截 servlet。课设项目为了好改通常是在左侧导航菜单里用 jstl 判断。c:if test${sessionScope.role 1} lia hrefStudentInfoServlet?actionmyinfo查看个人信息/a/li lia hrefLeaveServlet?actionmyLeave填写请假单/a/li lia hrefLateRecordServlet?actionmyLate个人晚归记录/a/li /c:if c:if test${sessionScope.role 2} lia hrefLeaveServlet?actionauditList审核请假单/a/li lia hrefLateRecordServlet?actionexport导出晚归记录/a/li lia hrefBaseManageServlet?actionstudent学生信息管理/a/li /c:if c:if test${sessionScope.role 3} lia hrefBaseManageServlet?actionroom基础信息管理/a/li /c:if注意${sessionScope.role 1}这里的 1 代表学生2 是辅导员3 是宿管员。这些数字必须和数据库 role 字段一致。我见过有人把 role 存成字符串 student然后 jsp 里判断 1页面直接白屏——就是类型不匹配的典型。学生端“查看个人信息”这个菜单点进去就是一张信息展示页这是 jsp 个人信息展示页面的经典写法servlet 从 session 或数据库查出对象request setAttribute 后转发到 user_info.jsp页面用 EL 表达式直接取字段。前端样式靠的是 pintuer.css 和 admin.css 组合这套蓝色 UI 换肤很简单改一个classtable table-bordered就能适配表格。跳转路径建议全部走 servlet不要用 jsp 直接访问 jsp因为 servlet 里可以做权限拦截比如学生直接访问auditList.jsp看不到数据答辩时被问到 MVC 模式你也能解释得更清楚。源码包里的PageBean.class说明列表页做过封装这应该是辅导员审核列表或者晚归记录列表用的分页组件。2.3 数据库表与账号初始化源码包通常会附带一个 sql 文件如果没有就需要自己建。这套系统的核心表大概有四张user用户表、student学生信息、leave_info请假单、late_record晚归记录。role 字段直接放 user 表里这样登录和业务表分离改起来方便。CREATE TABLE user ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(20) NOT NULL, password varchar(50) NOT NULL, role int(1) DEFAULT 1, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8; INSERT INTO user VALUES (1, 1, 1, 1); INSERT INTO user VALUES (2, 2, 2, 2); INSERT INTO user VALUES (3, 3, 3, 3);关于字符集建表时一定要指定CHARSETutf8否则插入中文会乱码别问我怎么知道的。如果你用的是 MySQL 8.x连接驱动和 URL 都要跟着变驱动用com.mysql.cj.jdbc.DriverURL 里要加serverTimezoneAsia/Shanghai。这一点在 4.3 节还会细讲。role 用 int 有个好处扩展角色数字就行但注意如果以后要加“管理员”角色最好用 0 或 4别把已有数字挤掉。这套系统的宿管员标记为 3而且功能“有待完善”说明是半成品课设你如果答辩要展示建议先把自己角色的功能点列清楚别被老师问住。3. 请假单审核链路jsp 表单到 servlet 再到 jdbc 的完整落库这是系统的核心功能。学生填请假单辅导员审核审核结果要能反馈给学生。整个链路涉及前端校验、servlet 接收、jdbc 写入、状态流转、列表导出。我按数据流向拆解。3.1 请假表单与前端校验学生端“填写请假单”页面通常是一个 form提交到LeaveServlet?actionadd。字段无外乎请假类型事假/病假、开始时间、结束时间、请假天数、请假原因。表单在 jsp 里写但提交前必须做基本校验。form actionLeaveServlet?actionadd methodpost onsubmitreturn checkForm() 请假类型select nameleaveType option value事假事假/option option value病假病假/option option value其他其他/option /selectbr/ 开始时间input typedate namestartDate idstartDate/br/ 结束时间input typedate nameendDate idendDate/br/ 请假天数input typenumber namedays min1 max30 value1/br/ 请假原因textarea namereason rows3 cols30/textareabr/ input typesubmit value提交请假/ /form script function checkForm() { var start document.getElementById(startDate).value; var end document.getElementById(endDate).value; if (start || end ) { alert(开始和结束时间不能为空); return false; } if (start end) { alert(结束时间不能早于开始时间); return false; } return true; } /scriptcheckForm 里比较日期字符串是因为 HTML5 的 date 输入框返回的是YYYY-MM-DD格式字符串比较就能反映日期先后。这里有个坑如果用的是input typetext手动填日期格式可能是2024-01-01也可能是2024/01/01字符串比较就失效了。后端的 servlet 里一定要再用 SimpleDateFormat 解析一遍只信前端校验等于没校验。这个话题顺便提一句jsp 页面让加载完后刷新一次的诉求偶尔会有比如你希望列表页每次进入都从服务器重新拉数据。最简单的办法是给 jsp 的 body 加onloadwindow.location.reload()但这样做会死循环正确做法是通过 servlet 转发过来时加Cache-Control: no-cache头或者用一个隐藏的 iframe 触发。课设里别乱加。3.2 Servlet 接收参数与业务判断前端提交后请求到LeaveServlet。这个 servlet 会根据action参数分发到不同方法。最写意但最常见的写法是一个大 if/else这也是课设源码里最常看到的。如果你愿意可以改成用 switch 或者建立 action 映射但课设注重能跑通我建议至少保持清晰的分发入口。// LeaveServlet 的 doPost 部分 String action request.getParameter(action); if (add.equals(action)) { // 处理新增请假 String leaveType request.getParameter(leaveType); String startDate request.getParameter(startDate); String endDate request.getParameter(endDate); String reason request.getParameter(reason); int days Integer.parseInt(request.getParameter(days)); // 从 session 拿当前学生 id User loginUser (User) request.getSession().getAttribute(loginUser); LeaveInfo leave new LeaveInfo(); leave.setStudentId(loginUser.getId()); leave.setLeaveType(leaveType); leave.setStartDate(java.sql.Date.valueOf(startDate)); leave.setEndDate(java.sql.Date.valueOf(endDate)); leave.setDays(days); leave.setReason(reason); leave.setStatus(0); // 0 待审核1 通过2 驳回 boolean ok new LeaveDao().addLeave(leave); if (ok) { response.sendRedirect(LeaveServlet?actionmyLeave); } else { request.setAttribute(msg, 提交失败); request.getRequestDispatcher(leave_add.jsp).forward(request, response); } }java.sql.Date.valueOf能把2024-01-01字符串直接转成 sql 日期比自己写 SimpleDateFormat 省事但前提是字符串格式必须严格符合yyyy-MM-dd。studentId从 session 的 loginUser 里拿而不是从表单里传这是防止学生伪造 studentId。课设里有人直接前端 hidden input 传 studentId这是绝对不行的数据库的归属信息必须由服务端决定。status字段用 0/1/2 比用字符串好排序和统计都方便。待审核状态为 0导出晚归记录时不会把请假未通过的数据算进去。3.3 JDBC 写入与审核状态流转JDBC 这块最基础也最容易敲错。课程设计里一般会封装一个BaseDao或者DBUtil工具类提供获取 Connection 和关闭资源的方法。注意连接信息千万别写死在每个 dao 里改一次累死。public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/leave_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai; private static final String USER root; private static final String PASSWORD 123456; static { try { Class.forName(com.mysql.jdbc.Driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } }如果你用的是 MySQL 5.x驱动是com.mysql.jdbc.DriverMySQL 8.x 要用com.mysql.cj.jdbc.Driver并且 URL 里必须有serverTimezone。源码包里通常是 class 文件你改配置文件是不起作用的必须改 java 源文件重新编译这一点后面避坑章详细讲。审核状态的更新本质是一个 update 语句带 where 条件。安全起见审核时要把状态字段作为条件防止重复审核覆盖。public boolean audit(int leaveId, int auditStatus) { String sql update leave_info set status? where id? and status0; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, auditStatus); ps.setInt(2, leaveId); return ps.executeUpdate() 1; } catch (SQLException e) { e.printStackTrace(); return false; } }这条 SQL 加上了status0意思是只能对待审核的请假单进行操作。如果这条语句返回 0 行说明该单已经被审核过了页面就提示“已被处理”。这种乐观锁的思路在课设里非常加分老师问“并发情况下怎么防止重复审核”你就能答上来。晚归记录导出通常用Excel.class。源码包里已经编译好的Excel.class应该是个导出工具类把 list 数据填充到 HSSFWorkbook 再输出下载。你需要确认它能处理中文表头如果导出后乱码多半是 ContentType 或流编码问题见 4.4。4. 避坑清单课设里最容易翻车的五个环节这一章我把拆包和复现过程中最常见的坑按“现象、原因、解决”列出来。几乎每个做这个系统的人都会遇到。4.1 Eclipse 编译版本与 class 文件不匹配现象把源码导入 Eclipse 后运行 Tomcat启动报错ClassNotFoundException: org.apache.jsp.index_jsp或者页面能开但某些 servlet 找不到类。原因源码包里已经有编译后的 .class 文件它们是用某个 JDK 版本编的。你本机 Eclipse 的编译器版本如果不一致或者没有 clean 项目旧 class 会和新源码混在一起。解决项目导入后第一时间Project - Clean全部重新编译。如果你拿到的包只给 .class 不给 .java那只能反编译或者换对应 JDK 版本的运行环境。最稳妥的是用 Eclipse 新建 Dynamic Web Project把 java 文件拷到 src把 jsp 拷到 WebContent重新用你本机环境编译一遍不要直接拿 .class 去顶。4.2 请求参数中文乱码现象提交请假原因辅导员审核列表显示“鍟嗗暐”或者一堆问号。原因Tomcat 8 以前 POST 请求默认 ISO-8859-1而 jsp 页面是 UTF-8参数传到 servlet 解码错了。另外数据库连接 URL 没加characterEncodingutf8存进库就是乱码。解决在 servlet 的 doPost 里加request.setCharacterEncoding(UTF-8)而且必须在读取任何参数之前调用。数据库连接 URL 改成我上面写的带useUnicodetruecharacterEncodingutf8的写法。如果还乱检查 jsp 页面开头有没有% page contentTypetext/html;charsetUTF-8 %。这一个链条三处全查一遍。4.3 MySQL 8.x 驱动与时区问题现象启动 Tomcat 后访问任意 servlet 报java.sql.SQLException: The server time zone value ???ú±ê×??±?? is unrecognized。原因MySQL 8.0 以后连接器要求指定时区而课设源码里都是老的 5.x 驱动写法。解决换成com.mysql.cj.jdbc.DriverURL 里加serverTimezoneAsia/Shanghai。如果你用的是本地 MySQL 5.5 老库那可以继续用com.mysql.jdbc.Driver但注意新版驱动包已经把旧类移除了。一个更省事的办法是直接把连接串写进一个 properties 文件这样换环境不用重新编译 java。但源码包里已知是 class 文件你没法改编译好的 DBUtil只能改你自己重新编译后的源文件。4.4 jsp 页面刷新后重复提交表单现象学生提交请假单后按 F5出现两条重复记录。原因表单提交是 POST刷新时浏览器会重新发送上次请求。servlet 里没有用重定向跳转而是 forward 到列表页或者提交成功后没有sendRedirect。解决凡是对数据库有写操作的请求处理成功一律使用response.sendRedirect(列表页)不要用 forward。列表页是 GET 请求刷新就不会重复提交了。如果你实在想在列表页看到提示信息可以用 session 传一次性的 alert推荐用request.getSession().setAttribute(msg,提交成功)列表页显示后立即移除。4.5 数据库文件导不进去或找不到 sql现象老师发的包里有数据库目录但没.sql文件或者有.sql但导入时报错Unknown database。原因sql 文件开头可能含有CREATE DATABASE leave_system如果手动打开执行时没先建库或者字符集不对就会失败有的包是只给.frm文件需要把整个目录拷到 MySQL 的 data 目录下权限不对就启动不了。解决先看 sql 头部。如果有CREATE DATABASE就在 MySQL 命令行直接source d:/leave.sql它会自动建库如果没有就手动建库再导入。要是只有.frm的物理文件建议别折腾直接新建库然后按 2.3 节里的建表语句重新建再用工具手动补几条测试数据比修复物理文件快得多。这也是我每次做课设的习惯不指望别人给的库文件自己建一份带测试数据的。5. 换一套编译环境后如何快速验证半小时跑通业务闭环最后一章给一个落地技巧怎么用最少时间确认这套课设能跑通并拿到答辩分。这个技巧就是从导入源码到验证功能最多不超过半小时。先准备环境。装 JDK 8不要用 17老 servlet 项目容易踩模块化问题、Tomcat 8.5 或 9、MySQL 5.7 或 8.0、Eclipse EE 或 IDEA。然后用 4.1 的方式新建一个项目把 jsp 和 java 源码按目录放好。注意确认项目构建路径里有没有 Tomcat 的 servlet-api.jar没有的话 servlet 类全部编译不通过。接着按顺序做三件事验证。第一件是让登录页能出验证码。源码里 CheckCode.class 是在线的如果验证码图片不出来先看 servlet 映射有没有配置在 web.xml再看 response 的 content type 是不是image/jpeg。验证码通了说明你的 servlet 环境没问题。第二件是登录。用 1/1 登录学生端能看个人信息和填写请假单说明 jdbc 连接通了。第三件是提交一张请假单再到辅导员账号 2/2 登录审核。如果状态从待审核变成通过说明整个业务闭环通了。如果时间充裕把PageBean.class对应的分页逻辑排查一下。很多课设分页只有上一页下一页点的时候currentPage没有从 session 里恢复回列表就第一页。我一般会把currentPage放在 URL 参数里page.jsp?currentPage2这样刷新也不丢。这个方法非常简单但是能防止答辩时被问“为什么点下一页之后再回详情返回列表又变第一页”。最后说个习惯。每次我拿到这类课设源码第一件事不是跑而是把所有.java文件里System.out.println和硬编码的root/123456全部搜一遍改成日志输出和配置文件。这么做不是为了好看而是排查问题时你能看到 SQL 参数到底传了什么。如果你正打算下载这套源码复现导入前把第四章的清单过一遍能少走两小时弯路。从那以后我每次跑别人的 jsp 老项目都强制走一遍“先 clean再统一字符集最后测一条完整业务流”的流程再没在答辩台上翻过车。希望这份拆解能帮到你让你的课设少走两步冤枉路。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门