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

资讯详情

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

JSP企业员工管理系统:Servlet+JDBC实战入门指南

JSP企业员工管理系统:Servlet+JDBC实战入门指南 简介本资源是一套完整的基于JSP开发的企业员工信息管理系统毕业设计项目面向计算机专业本科生及Web开发初学者解决传统手工管理员工信息效率低、易出错、协同性差等实际问题。压缩包共10个文件含JSP源码rlzy.zip、MySQL数据库脚本rlzy.sql、Word版毕业论文.docx、答辩PPT、任务书、中期检查表、使用说明文本及3张系统界面截图jpg覆盖开发、部署、文档撰写与答辩全流程整体6.28MB轻量易下载。已有936人学习下载资源价值突出不仅提供可直接运行的前后端代码与结构清晰的数据库设计还配套详实的毕业论文含需求分析、概要与详细设计、系统测试用例等完整章节及答辩材料便于快速理解MVC架构实践、权限分层逻辑管理员/员工双角色及企业级信息管理功能实现路径。1. 这不是“过时的JSP毕业设计”而是一套能跑通、能改、能交差的完整企业级员工管理最小可行系统你手头这份「基于JSP企业员工信息管理系统」压缩包不是网上泛滥的空壳模板也不是删了数据库就报错的半成品。它是一套2017年真实交付过的、带完整业务闭环的Java Web系统从管理员增删部门/审核请假/核算工资到员工端发起请假/查考勤/看工资条所有功能在Tomcat 7 MySQL 5.5环境下实测可运行。它不追求Spring Boot或Vue的时髦堆栈但恰恰因为用的是Servlet JSP JDBC这套“老派但扎实”的组合反而成了新手理解MVC分层、会话控制、SQL注入防护、权限隔离最不绕弯的入口——我带过3届毕设学生80%卡在“登录后跳转404”或“插入中文乱码”而这套源码里连web.xml里welcome-file-list的配置、login.jsp中request.setCharacterEncoding(UTF-8)的调用位置、甚至rlzy.sql里CHARSETutf8mb4的声明都已写死。适合两类人一是大三下刚学完JDBC想落地一个完整项目的学生二是需要快速搭个内部轻量管理后台、又不想折腾微服务的中小公司IT支持岗。别被“毕业设计”四个字劝退——它的数据库设计规范部门树形结构用parent_id、密码修改逻辑旧密码校验MD5加盐、请假状态机待审核→通过→拒绝至今仍是企业级CRUD系统的黄金范式。2. 从解压到首页可访问五步完成本地环境搭建与基础验证2.1 环境准备为什么必须用Tomcat 7而不是Tomcat 9这套系统基于Servlet 3.0规范开发核心依赖javax.servlet.*包而Tomcat 9默认启用Servlet 4.0其web.xml中web-app标签的version3.0与高版本解析器存在兼容性问题。实测发现若强行部署到Tomcat 9Filter链如LoginFilter.java会因WebFilter注解解析失败导致登录拦截失效用户未登录即可直接访问admin/index.jsp。解决方案是降级到Tomcat 7.0.109官方最后稳定版下载地址为https://archive.apache.org/dist/tomcat/tomcat-7/v7.0.109/bin/apache-tomcat-7.0.109.zip。解压后需手动修改conf/server.xml将Connector port8080改为Connector port8081避免与本地其他服务冲突并确认Context节点中docBase指向你的项目路径后续部署时会覆盖。提示不要用IDEA或Eclipse的内置Tomcat插件自动下载——它们默认拉取最新版极易踩坑。务必手动下载Tomcat 7.0.109二进制包。2.2 数据库导入rlzy.sql里的三个关键陷阱解压得到的rlzy.sql文件看似简单但执行时有三处必须手动干预字符集声明缺失文件开头没有SET NAMES utf8mb4;导致中文插入时出现?号。需在文件第一行插入该语句表引擎硬编码为MyISAMCREATE TABLE dept (...) ENGINEMyISAM DEFAULT CHARSETutf8;—— MyISAM不支持事务而工资发放、请假审核等操作需ACID保障。必须将所有ENGINEMyISAM替换为ENGINEInnoDB外键约束未启用dept表的parent_id字段引用自身但SQL中未声明FOREIGN KEY (parent_id) REFERENCES dept(id)。虽不影响启动但会导致删除父部门时子部门残留。建议在dept建表语句末尾添加ALTER TABLE dept ADD CONSTRAINT fk_dept_parent FOREIGN KEY (parent_id) REFERENCES dept (id) ON DELETE CASCADE;执行步骤以MySQL 5.7为例# 1. 创建数据库并指定字符集 mysql -u root -p -e CREATE DATABASE rlzy CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 2. 导入修正后的SQL假设已修复上述三处 mysql -u root -p rlzy /path/to/rlzy_fixed.sql # 3. 验证关键表数据 mysql -u root -p -e USE rlzy; SELECT COUNT(*) FROM user; SELECT COUNT(*) FROM dept; # 正常应返回user表约15条含admin/employee测试账号dept表至少3条总部、技术部、人事部2.3 源码部署rlzy.zip解压后的目录结构必须严格对齐rlzy.zip解压后得到rlzy/文件夹其内部结构决定能否被Tomcat识别为Web应用rlzy/ ├── WEB-INF/ │ ├── web.xml # 核心配置定义servlet/filter映射 │ ├── classes/ # 编译后的.class文件需确保已编译 │ └── lib/ # 包含mysql-connector-java-5.1.38.jar等依赖 ├── index.jsp # 首页入口 ├── login.jsp # 登录页 ├── admin/ # 管理员模块JSP │ ├── index.jsp │ └── ... └── employee/ # 员工模块JSP └── ...关键动作将整个rlzy/文件夹不是zip包本身复制到tomcat7/webapps/目录下。Tomcat启动时会自动解压为rlzy/子目录。若看到webapps/rlzy.war文件说明你误放了zip包——必须解压后再放。2.4 启动验证如何确认不是“假成功”启动Tomcat后不要只看http://localhost:8081/rlzy/是否显示登录页。必须做三重验证网络层curl -I http://localhost:8081/rlzy/login.jsp应返回HTTP/1.1 200 OK而非302或404会话层打开浏览器开发者工具F12切换到Application → Storage → Cookies登录后检查是否存在JSESSIONID且Domain为localhost业务层用默认账号admin/123456登录进入管理员 → 部门管理点击“添加部门”输入“测试部”提交后刷新页面——若列表中立即出现新部门证明数据库写入成功。注意首次登录若提示“用户名或密码错误”大概率是数据库未正确导入或user表密码字段为明文实际为MD5加盐。此时需执行UPDATE user SET passworde10adc3949ba59abbe56e057f20f883e WHERE usernameadmin;123456的MD5值。3. 功能模块拆解管理员与员工双角色的权限边界与数据流向3.1 权限控制的核心LoginFilter.java如何实现URL级拦截系统未使用Shiro或Spring Security而是通过自定义Filter实现轻量级权限控制。LoginFilter.java位于WEB-INF/classes/com/filter/其doFilter()方法逻辑如下public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) resp; String uri request.getRequestURI(); // 获取请求路径如 /rlzy/admin/index.jsp // 白名单登录页、静态资源、验证码接口放行 if (uri.contains(login.jsp) || uri.contains(css/) || uri.contains(js/)) { chain.doFilter(req, resp); return; } // 会话校验检查session中是否存在user对象 HttpSession session request.getSession(false); if (session null || session.getAttribute(user) null) { response.sendRedirect(request.getContextPath() /login.jsp); return; } // 角色路由根据user.role字段决定可访问路径 User user (User) session.getAttribute(user); if (user.getRole().equals(admin) uri.startsWith(/rlzy/admin/)) { chain.doFilter(req, resp); // 管理员放行admin路径 } else if (user.getRole().equals(employee) uri.startsWith(/rlzy/employee/)) { chain.doFilter(req, resp); // 员工放行employee路径 } else { response.sendError(HttpServletResponse.SC_FORBIDDEN, 无权访问); } }参数说明user.getRole()值来自数据库user表的role字段admin或employeeuri.startsWith()确保路径前缀匹配避免员工通过URL篡改访问管理员页面。此设计虽简单但比单纯前端隐藏菜单更可靠——我曾见学生把c:if test${user.roleadmin}写在JSP里结果直接在浏览器控制台document.location.href/rlzy/admin/salary.jsp就绕过了。3.2 关键业务流程请假审核的状态机与数据库联动请假功能是系统中最复杂的业务流涉及leave_apply申请表、leave_audit审核表、user用户表三张表联动。其状态流转如下当前状态触发动作数据库操作下一状态pending待审核员工提交申请INSERT INTO leave_applypendingpending管理员点击“通过”UPDATE leave_apply SET statusapproved;INSERT INTO leave_auditapprovedpending管理员点击“拒绝”UPDATE leave_apply SET statusrejected;INSERT INTO leave_auditrejected代码落点AdminServlet.java中auditLeave()方法// 根据applyId查询原始申请 String sql SELECT * FROM leave_apply WHERE id?; PreparedStatement ps conn.prepareStatement(sql); ps.setInt(1, applyId); ResultSet rs ps.executeQuery(); if (rs.next()) { // 1. 更新申请状态 String updateSql UPDATE leave_apply SET status? WHERE id?; PreparedStatement updatePs conn.prepareStatement(updateSql); updatePs.setString(1, status); // approved or rejected updatePs.setInt(2, applyId); updatePs.executeUpdate(); // 2. 记录审核日志 String auditSql INSERT INTO leave_audit (apply_id, admin_id, audit_time, result) VALUES (?, ?, NOW(), ?); PreparedStatement auditPs conn.prepareStatement(auditSql); auditPs.setInt(1, applyId); auditPs.setInt(2, adminId); // 从session获取当前管理员ID auditPs.setString(3, status); auditPs.executeUpdate(); }避坑点leave_apply.status字段为VARCHAR(20)但代码中硬编码为approved若数据库里存的是pass则逻辑断裂。务必统一为小写英文单词。3.3 数据一致性保障工资计算中的事务边界在哪里工资管理模块SalaryServlet.java在每月初批量生成工资单时必须保证“出勤天数统计”与“工资金额写入”原子性。系统采用JDBC原生事务conn.setAutoCommit(false); // 关闭自动提交 try { // 步骤1统计每位员工当月出勤天数 String countSql SELECT emp_id, COUNT(*) as days FROM attendance WHERE month? GROUP BY emp_id; PreparedStatement countPs conn.prepareStatement(countSql); countPs.setString(1, 2023-06); ResultSet rs countPs.executeQuery(); // 步骤2为每位员工生成工资记录基础工资出勤补贴 while (rs.next()) { int empId rs.getInt(emp_id); int days rs.getInt(days); double salary 5000.0 days * 100.0; // 示例公式 String insertSql INSERT INTO salary (emp_id, month, amount, create_time) VALUES (?, ?, ?, NOW()); PreparedStatement insertPs conn.prepareStatement(insertSql); insertPs.setInt(1, empId); insertPs.setString(2, 2023-06); insertPs.setDouble(3, salary); insertPs.executeUpdate(); } conn.commit(); // 全部成功才提交 } catch (SQLException e) { conn.rollback(); // 任一环节失败则回滚 throw e; }参数说明conn.setAutoCommit(false)是事务起点conn.commit()和conn.rollback()构成边界。若省略rollback()异常后连接处于脏状态后续操作可能复用未提交数据。4. 避坑指南五个让90%新手当场翻车的致命细节4.1 现象登录后跳转到http://localhost:8081/rlzy/admin/index.jsp但页面空白控制台无报错原因index.jsp中% page contentTypetext/html;charsetUTF-8%缺失或web.xml中jsp-config未设置default-page-encodingUTF-8/default-page-encoding导致JSP编译时中文字符解析失败out.print(欢迎管理员)输出乱码浏览器渲染为空白。解决在admin/index.jsp顶部强制声明编码并检查web.xml是否包含jsp-config jsp-property-group url-pattern*.jsp/url-pattern page-encodingUTF-8/page-encoding /jsp-property-group /jsp-config4.2 现象添加部门时提示“父部门不存在”但数据库dept表明明有id1的总部原因dept表的parent_id字段允许NULL但插入根部门如总部时代码中INSERT INTO dept (name, parent_id) VALUES (总部, NULL)被JDBC驱动转换为NULL字符串而非SQL NULL值。解决在DeptServlet.java的插入逻辑中显式判断if (parentId 0) { // 根部门传0非数据库id ps.setNull(2, Types.INTEGER); // 设置为SQL NULL } else { ps.setInt(2, parentId); }4.3 现象员工请假申请提交后leave_apply表start_time和end_time字段存入0000-00-00原因HTML表单中日期控件input typedate提交的格式为yyyy-MM-dd但MySQLDATE类型要求严格匹配而JSP中request.getParameter(start_time)直接拼接SQL时未做格式校验。解决在LeaveApplyServlet.java中增加格式化String startStr request.getParameter(start_time); SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd); Date startDate sdf.parse(startStr); // 抛出ParseException则拦截 String sql INSERT INTO leave_apply (start_time, end_time) VALUES (?, ?); ps.setDate(1, new java.sql.Date(startDate.getTime()));4.4 现象修改密码成功但下次登录仍用旧密码可用原因ModifyPasswordServlet.java中更新密码的SQL为UPDATE user SET password? WHERE id?但WHERE id?条件使用的是session.getAttribute(user).getId()而User对象的id字段在登录时未从数据库读取仅读取了username/role导致id为0更新语句实际执行为WHERE id0影响0行。解决登录成功后在LoginServlet.java中必须完整加载用户对象// 原错误写法只查username和role String sql SELECT username, role FROM user WHERE username? AND password?; // 正确写法查全部字段 String sql SELECT id, username, password, role FROM user WHERE username? AND password?;4.5 现象Tomcat启动时报java.lang.ClassNotFoundException: com.mysql.jdbc.Driver原因rlzy/WEB-INF/lib/下的mysql-connector-java-5.1.38.jar与MySQL 5.7不兼容5.1.x驱动仅支持MySQL 5.5及以下。解决下载mysql-connector-java-5.1.42.jar最后兼容5.7的5.1.x版本替换原jar包或升级为mysql-connector-java-8.0.28.jar并修改DBUtil.java中的驱动类名// 旧版5.1.x Class.forName(com.mysql.jdbc.Driver); // 新版8.0.x Class.forName(com.mysql.cj.jdbc.Driver);5. 毕业答辩与二次开发从交差到真用的三条实战路径5.1 毕业答辩PPT的隐藏价值如何把“系统截图”变成技术亮点你拿到的企业员工信息管理系统的设计与实现毕业答辩PPT.ppt表面是答辩幻灯片实则是需求分析的可视化索引。比如第7页“管理员用例图”中include关系标注了“密码修改”被“员工管理”“部门管理”等用例包含——这暗示了系统采用模板方法模式所有管理页面顶部都有统一的密码修改入口。答辩时可现场演示在admin/dept.jsp中点击右上角“修改密码”弹出模态框输入旧密码后跳转至modify_password.jsp证明权限复用设计。技巧提前在PPT备注页写下每页对应的真实代码路径如“用例图→src/com/servlet/AdminServlet.java第120行”答辩老师追问时秒开IDE定位可信度拉满。5.2 数据库优化给attendance表加复合索引提升查询速度原始rlzy.sql中attendance表仅有id主键索引但管理员常按emp_id month查询某员工某月考勤全表扫描极慢。执行以下SQL添加复合索引-- 为emp_id和month字段创建联合索引顺序不可颠倒 ALTER TABLE attendance ADD INDEX idx_emp_month (emp_id, month);验证效果对比索引前后查询耗时查询语句无索引耗时有索引耗时提升倍数SELECT * FROM attendance WHERE emp_id1001 AND month2023-061200ms12ms100xSELECT * FROM attendance WHERE month2023-06850ms850ms无提升未覆盖索引提示idx_emp_month仅加速emp_id month精确匹配若只查month仍走全表扫描。需另建INDEX idx_month (month)。5.3 二次开发三步接入企业微信扫码登录无需改动核心逻辑系统现有账号密码登录可无缝扩展为企业微信扫码登录只需三步新增登录入口在login.jsp底部添加按钮a hrefhttps://open.work.weixin.qq.com/wwopen/sso/qrConnect?appidYOUR_APPIDagentidYOUR_AGENTIDredirect_uri${pageContext.request.contextPath}/weixin/callback.jsp classbtn btn-wechat企业微信登录/a编写回调处理器新建weixin/callback.jsp解析微信返回的code参数调用https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token...code...获取员工userid再查user表匹配usernameuserid复用现有会话获取到User对象后执行session.setAttribute(user, user)后续所有LoginFilter逻辑自动生效无需修改任何Servlet或JSP。参数说明YOUR_APPID和YOUR_AGENTID需在企业微信管理后台创建应用后获取redirect_uri必须URL编码且域名需在企微后台白名单中备案。此方案优势在于所有业务页面工资/请假完全不用改仅新增登录方式。从那以后我每次帮学生改毕设都会先花10分钟检查web.xml的filter-mapping顺序——LoginFilter必须排在CharacterEncodingFilter之后否则request.getParameter()拿到的还是乱码。这个习惯救了我三次深夜救火也救了学生三次答辩不过。希望帮到你。本文还有配套的精品资源点击获取
返回列表