JSP企业人事管理系统源码解析:环境配置、核心代码与二次开发指南
简介一套基于JSP的企业人事管理系统源码包内含完整Java Web项目与数据库文件适合计算机专业学生用于毕业设计也适合开发者个人学习Java Web分层开发、Struts配置与人事业务流程或小公司改造为内部管理后台。压缩包共包含229个文件大小5.8MB主要构成有88个JSP页面、18个Java类与18个class文件、28个tld标签库描述、16个jar依赖库、32个jpg及11个gif图片资源另附数据库备份mdf/ldf/db、Struts元数据与项目工程配置文件。已有175人浏览学习。项目按Java Web经典分层组织涉及人事管理系统常见的登录鉴权、员工档案、考勤、工资、部门岗位等业务模块配套数据库文件与说明文档便于直接导入数据库并在Tomcat下运行调试。读者可借此掌握JSPServletStruts整合思路、理解企业应用从页面到持久层的完整调用链并参考其目录结构完成课程设计或快速搭建可用原型。1. JSP企业人事管理系统这份JAVA源码包能帮你解决什么问题如果你最近在准备JavaWeb课设或者在补传统项目经验JSP企业人事管理系统是个绕不开的样本。它不是Spring Boot那一套全家桶而是用JSPServletJDBC写成的经典三层结构能直接看到浏览器发请求、Servlet接参数、JDBC查库、JSP回显数据这条完整链路。这份打包下载的zip资源里常见的是完整源码、数据库脚本和配套说明适合两类人一类是刚学完Java基础想找一个能照葫芦画瓢的jsp入门项目另一类是需要在短时间内交一个功能齐全的人事管理课设又不想从零开写的从业者。它解决的问题很实在把你从“看懂语法”推到“能跑通一个完整系统”。2. 项目拆解JSPServletJDBC的人事管理系统里都有什么2.1 系统功能模块与角色权限人事管理系统在JavaWeb课设里一直是常青树因为它功能边界清晰员工、部门、考勤、工资每一块都能独立成功能页又都能共用同一套登录鉴权流程。我拆过的这种源码包模块划分基本一致。最外层通常是登录页面登录后根据角色跳转到不同主界面管理员能看到员工管理、部门管理、用户管理、考勤管理的全部入口普通员工则只能查看自己的信息和考勤记录。权限控制一般写在Servlet的doGet/doPost开头通过Session里保存的user对象判断role字段。比如登录成功后用管理员账号进系统能看到“删除员工”按钮普通账号登录就看不到。这种判断方式在JSP页面里往往是一段% if (admin.equals(session.getAttribute(role))) { %的Java小脚本。不复杂但足够展示JSP里的状态保持是怎么回事。对新手来说这比倒回去读Spring Security的Filter链要友好得多。功能模块通常用一个简洁表格就能说清楚部门管理负责维护部门层级员工管理包含新增、编辑、删除、按姓名/部门/学历筛选考勤管理按月记录出勤天数工资管理根据考勤数据计算薪资系统用户管理则用来分配登录账号。每个模块对应一个Servlet加一组JSP命名一般是UserServlet、DeptServlet、EmployeeServlet、AttendanceServlet、SalaryServlet。设计上的好处是如果你想验证jsp个人信息展示页面怎么做可以直接看员工列表页面的Java片段里怎么把查询结果set到request再遍历出来。如果你想拿一份java课程设计案例源码做参考这个项目的表结构和页面交互能直接复用甚至可以把部门管理改成班级管理员工管理改成学生管理课设题目就换了。2.2 源码包目录结构和数据表关系解压zip之后第一件事不是急着配环境而是先把目录结构看明白。常见打包方式有两种一种是Eclipse/MyEclipse导出时的web项目结构直接包含src、WebRoot、.project和.classpath另一种是IDEA项目的结构根目录有src、web或webapp还有.idea文件夹。无论哪种关键目录都是src和WebRoot或webapp。src下通常有com.example.dao、com.example.entity、com.example.servlet、com.example.util几个包。entity放表和页面之间的临时对象dao封装数据库操作servlet接收请求、调dao、转发JSPutil负责数据库连接、字符编码过滤器等工具类。WebRoot下则是静态资源登录页login.jsp、主框架index.jsp、员工模块下的list.jsp/add.jsp/edit.jsp以及WEB-INF/web.xml。web.xml里配置Servlet映射和欢迎文件老项目还可能有EncodingFilter的配置。一个典型的Servlet映射片段长这样servlet servlet-nameloginServlet/servlet-name servlet-classcom.example.servlet.LoginServlet/servlet-class /servlet servlet-mapping servlet-nameloginServlet/servlet-name url-pattern/login/url-pattern /servlet-mapping这段配置的意思是浏览器访问/login时Tomcat会把请求交给com.example.servlet.LoginServlet处理。url-pattern里的斜杠不能少少了就报404servlet-class必须是类的全限定名如果类所在包变了这里也要跟着改否则启动时会报ClassNotFoundException。数据库脚本一般单独放在sql或database文件夹名为hr.sql或personnel.sql。导入时如果用Navicat直接执行整个文件就行如果用命令行需要先建库再导入。数据表关系是这个项目的灵魂。小体量人事系统通常有这五张表用户表t_user、部门表t_dept、员工表t_employee、考勤表t_attendance、工资表t_salary。员工表和部门表用dept_id关联考勤表和工资表用employee_id关联主键都是自增id。这里给出一个常见表结构对照表名核心字段与其它表的关系t_userid, username, password, rolerole决定页面权限t_deptid, dept_name, dept_manager员工表的所属部门t_employeeid, emp_no, name, gender, dept_id, position, phonedept_id关联t_deptt_attendanceid, employee_id, work_date, status, overtime_hoursemployee_id关联t_employeet_salaryid, employee_id, base_salary, bonus, deduction, net_salary按月计算时以employee_id聚合这段关系理清了后面读EmployeeDao里的SQL就容易了。很多新手卡在“为什么改了一个员工信息工资表没有变”——因为工资表只存计算后结果员工表存最新状态两者通过employee_id连接不是同一份数据。理解这点二次开发才能下手。3. 本地跑起来JDK/Tomcat/MySQL/IDEA的版本搭配与导入步骤3.1 运行环境选择为什么要卡在JDK 8和Tomcat 8.5老JSP项目对环境特别挑剔翻车大都是版本问题。我的建议是把环境钉在一套稳定组合上JDK 8、Tomcat 8.5、MySQL 5.7开发工具用IDEA 2020以上即可。IDE影响不大真正决定成败的是编译器版本和Servlet容器版本。JDK尽量选择1.8因为大部分JSPServletJDBC项目编译时用了泛型、自动资源管理这些Java 7/8特性高版本JDK反而会因为模块化或强封装导致老库兼容问题。Tomcat推荐8.5它依然完整支持JSP模型和javax.servlet包不需要额外引依赖如果用了Tomcat 10会发现Servlet包变成了jakarta.servlet老项目的import全报错。MySQL 5.7和项目自带的mysql-connector-java 5.x驱动配合很顺MySQL 8.0也能连但要把驱动换成8.0.x并调整认证方式这一步单独拿出来说。Java环境变量配置是零基础最常见的一个卡点。帮别人排错时十有八九是JAVA_HOME指到了jre目录而不是jdk目录。正确做法是配置三个系统变量JAVA_HOME指向JDK安装根目录比如C:\Program Files\Java\jdk1.8.0_202Path里加%JAVA_HOME%\bin再建CLASSPATH配成.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar。配完在cmd执行java -version验证。注意不是装完JDK就能编译没有JAVA_HOMETomcat启动脚本根本找不到Java这是环境问题里排名第一的坑。版本组合看起来保守但这类项目的价值就在“稳定复现”而非追赶新版本。等你把请求流程跑通再考虑迁移到Spring Boot也不迟。3.2 从zip源码到能跑导入项目、替换连接配置、导入SQL脚本第一步是解压zip。如果你用的是Windows自带解压资源管理器右键“压缩为zip”可能给文件加上安全标记导致IDEA里面某些文件变成只读建议用7-Zip解压到无中文路径的目录比如D:\hrsys。目录里有中文或者空格Tomcat部署时可能取项目名异常后面访问路径对不上。第二步是IDEA导入。如果解压出来是Eclipse项目结构IDEA里直接选File - New Project - Existing Sources选择根目录下的.project文件如果是IDEA项目结构选Open直接打开pom.xml如果有或根目录文件夹。导入后检查src文件夹是否被标成蓝的Source RootWebRoot是否被标成Web Resources Directory。这一步没做对启动Tomcat后永远404。IDEA新建jsp项目时它会自动帮你标好但导入老工程没有自动标记得手动Set as Properties。第三步是改数据库连接配置。老项目一般把连接参数写在src下的jdbc.properties或db.properties里代码如下jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/hr_db?useUnicodetruecharacterEncodingUTF-8 jdbc.usernameroot jdbc.password123456这段配置里driver是MySQL 5.x老驱动类名url里的hr_db是你导入数据库时建的库名characterEncodingUTF-8决定中文能不能正常查出来。如果你的MySQL是8.0driver要改成com.mysql.cj.jdbc.Driverurl里还要加serverTimezoneAsia/Shanghai否则时间字段会报错。password改成你自己数据库的密码别直接用文档里的。第四步导入SQL脚本。用Navicat或mysql命令行执行脚本命令行常见写法是mysql -u root -p hr_db sql/hr.sql执行前先执行create database hr_db default character set utf8否则表结构里的中文注释会变成乱码。这个库名需要和jdbc.url里的hr_db保持一致。配置完成后把Tomcat集成到IDEA里。在Run/Debug Configurations里新增Tomcat Server - LocalDeployment加当前项目的Artifact改一改Application Context应用名比如/hrserver然后启动。启动日志里看到server startup in [xxx] ms就说明环境成了。3.3 启动后先验证这三件事不要看到登录页就以为项目跑通了HR系统最怕的是登录进得去、列表加载不出来。首先打开浏览器访问http://localhost:8080/hrserver/应该能看到登录界面然后输入管理员账号admin密码通常是admin或123456如果登录后能看到员工列表数据说明数据库连接和查询都正常最后随便点一个模块看看Session会话是否会跳到登录页这是权限控制生效的标志。我自己常用curl先探一遍HTTP状态不用点开浏览器curl -I http://localhost:8080/hrserver/login.jsp返回200是正常返回404就检查Web资源目录和Artifact是否部署成功。这个命令在Windows、Linux都能用排查节奏快很多。4. 避坑指南跑这个JSP项目最常见的五个翻车点4.1 环境配置和Tomcat启动的坑现象一双击Tomcat目录startup.bat后窗口一闪而过日志里提示Neither JAVA_HOME nor JRE_HOME is defined。原因是Tomcat启动脚本找不到JDK只装了JRE但没有JAVA_HOME或者JAVA_HOME指向的是jre目录。解决办法是重新配置环境变量JAVA_HOME指向JDK根目录然后重启cmd窗口再试不要在旧终端里验证配置完用java -version确认当前生效的是JDK而不是其他版本。那之后我再也没在旧终端里配过环境变量每次都开新窗口。现象二IDEA里启动Tomcat时端口8080被占用报Port 8080 was already in use。常见原因是之前启动过残留的java进程或者本机装了其他Web服务器。解决方式是杀掉占用进程Windows下执行netstat -ano | findstr 8080拿到PID再用taskkill /PID /F结束也可以改Tomcat配置文件server.xml里的Connector端口但注意改完访问URL的数字对不上不推荐新手这么干。排查时可以顺便确认一下是否本地MySQL也占了3306两边冲突的情况我也见过不少。4.2 数据库和字符集的坑现象三登录时后台报java.sql.SQLException: Access denied for user rootlocalhost。原因是jdbc.properties里username或password和本地MySQL不一致或者MySQL里用户的host限制不是localhost。解决方式很简单先把properties里的密码改成MySQL真实密码注意不要在这个文件末尾留空格如果是MySQL 8.0还需要先创建用户或执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 密码否则驱动握手会失败。这类权限问题排查起来最费时间因为看起来像是密码错误实际是认证插件不匹配。现象四登录成功后员工姓名、部门名全部显示成问号。原因有两个层叠根源数据库表用了latin1编码或者连接串没带characterEncoding参数。解决顺序是先把jdbc.url加上useUnicodetruecharacterEncodingUTF-8再确认建库语句是default character set utf8。如果数据已经导完且出现乱码只改连接串救不回已经存成二进制乱码的数据必须删库重导。所以从拿到zip的那一刻起我习惯先看SQL脚本开头有没有charsetutf8没有就先加上再执行省得后面来回折腾。4.3 页面和资源访问的坑现象五访问http://localhost:8080/项目名/出现404但login.jsp单独访问能打开。原因是Servlet路径映射和欢迎文件配置两处冲突。常见做法是检查web.xml里的welcome-file-list把index.jsp或login.jsp加进去否则Tomcat会按默认顺序找index.html、index.jsp找不到就404。另一个隐蔽点是IDEA部署时Application Context如果设成了/那么URL末尾就不再需要项目名直接localhost:8080/访问就对了。访问路径要和部署配置对齐别死记网上的写法资源里自带的说明文档如果有端口信息优先按文档来文档里的项目名可能和你的不一致。5. 读懂核心代码从登录到员工管理二次开发怎么下手5.1 登录验证与Session控制登录模块是整个项目里代码最完整、也最适合入门拆解的一块。它的流程是login.jsp提交表单到LoginServletLoginServlet调UserDao.findByUsernameAndPassword查库查到就把user对象放进Session并重定向到index.jsp查不到就返回登录页并带一个error参数。典型代码如下protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username request.getParameter(username); String password request.getParameter(password); User user new UserDao().findByUsernameAndPassword(username, password); if (user ! null) { HttpSession session request.getSession(); session.setAttribute(user, user); response.sendRedirect(index.jsp); } else { request.setAttribute(error, 用户名或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); } }这段代码里request.getParameter拿的是表单input里name字段的值username和password必须和login.jsp里input标签的name属性一致很多新手改了字段名忘了改这里结果一直登录失败。session.setAttribute(user, user)是把用户信息挂到会话上后续JSP页面通过session里的user对象读取当前登录人。sendRedirect和forward的区别在于前者让浏览器发起一次新请求地址栏会变后者是服务端内部转发地址栏不变request里的error属性还能拿到所以登录失败用forward登录成功用sendRedirect这是最常见也最稳妥的分工。学完这里基本就能看懂jsp面试题里常问的get/post区别、转发和重定向区别在真实项目里的应用场景。如果你想做jsp个人信息展示页面直接把index.jsp里满屏的Java片段拆出来就能看到session.getAttribute(user)的取值方式。5.2 员工列表与分页查询员工列表是HR系统里另一个高频模块通过EmployeeServlet接收pageNo参数、调EmployeeDao查询当前页数据、最后set到request转发给employee_list.jsp。分页逻辑基本一致核心SQL是limit ? offset ?。为了让新手直接抄我简化后的代码如下public ListEmployee findPage(int pageNo, int pageSize) { ListEmployee list new ArrayList(); String sql SELECT e.id, e.emp_no, e.name, e.gender, d.dept_name, e.position FROM t_employee e LEFT JOIN t_dept d ON e.dept_id d.id ORDER BY e.id LIMIT ?, ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, (pageNo - 1) * pageSize); ps.setInt(2, pageSize); ResultSet rs ps.executeQuery(); while (rs.next()) { Employee emp new Employee(); emp.setId(rs.getInt(id)); emp.setEmpNo(rs.getString(emp_no)); emp.setName(rs.getString(name)); emp.setDeptName(rs.getString(dept_name)); list.add(emp); } } catch (SQLException e) { e.printStackTrace(); } return list; }LIMIT ?, ?里的第一个参数是偏移量计算方式是(pageNo-1)*pageSize这是分页最容易写错的地方。第二个参数是每页条数。LEFT JOIN是为了把员工表里的dept_id翻译成部门名称如果只用内连接没有部门的员工会被过滤掉列表显示不完整。PreparedStatement参数占位符从1开始setInt(1, offset)对应第一个问号setInt(2, pageSize)对应第二个问号。代码里try-with-resources会在执行完自动关闭Connection和PreparedStatement老项目如果不用这个写法一定要记得在finally里关连接否则连接数一多MySQL会报too many connections。Servlet里接收pageNo的代码int pageNo 1; String pageNoStr request.getParameter(pageNo); if (pageNoStr ! null !pageNoStr.equals()) { pageNo Integer.parseInt(pageNoStr); } request.setAttribute(empList, empDao.findPage(pageNo, PAGE_SIZE)); request.setAttribute(pageNo, pageNo); request.getRequestDispatcher(employee_list.jsp).forward(request, response);parseInt没做异常保护用户手动输一个?pageNoabc就会抛NumberFormatException真正的生产系统应该用正则或try/catch兜底。这一点在二次开发时最好补上同时还能放到简历里当亮点你给老项目补了参数校验这就是实打实的改进记录。5.3 从增删改查看老项目改写方向如果你已经跑通了登录和查询接下来可以动手做一个小改动来验证理解给员工列表加一个删除按钮并在Servlet里做权限判断。做法是找到EmployeeServlet里的doPost或doGet增加一个action参数比如actiondelete和id参数。删除的SQL要带上参数限制防止意外全表清空SQL写成DELETE FROM t_employee WHERE id ?。因为t_attendance和t_salary表外键关联了employee_id删除员工时如果直接删主表可能因为外键约束报错需要先删子表或把外键设为ON DELETE CASCADE。这是一个非常现实的坑很多老项目设计表时外键约束不那么严格反而不会报错但一旦把数据库迁到严格模式就会翻车。二次开发还有一条更明显、也更推荐的路把JDBC连接工具类DBUtil换成连接池实现比如阿里的Druid或HikariCP。好处是频繁创建connection的损耗变小而且可以在配置里监控慢SQL。替换起来不复杂引入一个jar包把DriverManager.getConnection换成从DataSource对象拿连接然后配置文件里加上initialSize、maxActive这些连接池参数。做完这一步项目的行为从“每次请求建连”变成“复用连接池里的连接”对理解后续Spring Boot整合MyBatis的数据源概念特别有用。6. 进阶把传统JSP项目打成WAR包换台机器也能跑这节聊聊一个很实在的收尾操作把项目打成WAR包部署到另一个Tomcat。IDEA里依次打开File - Project Structure - Artifacts - - Web Application: Archive - For 项目名: war exploded然后Build - Build Artifacts就能在out/artifacts下看到xxx.war。把这个war复制到另一台Tomcat的webapps目录下启动Tomcat访问http://localhost:8080/xxx/就省掉整个IDE配置过程。打包过程中容易踩一个和IDEA配置有关的坑Artifact里必须包含web.xml和所有lib依赖如果你在Project Structure里漏了Dependent Files部署后会出现ClassNotFoundException。我的习惯是每次打包前先Build - Clean然后重新构建避免上一轮残留class文件污染输出。除了部署这个项目还能当java基础面试题的实战素材。面试官问“讲一下JSP请求流程”时你可以直接拿这个系统举例从浏览器发起login.jsp开始说到Servlet在web.xml中的映射、doPost执行、Session保存、JSP渲染比背八股文要可信得多。从那以后我每次接手老项目都会先建一个环境核对清单把JDK版本、Tomcat版本、数据库连接、字符集和部署路径五项放在最前面确认无误再启动。这个习惯从JSP项目延续到Spring Boot项目帮我少走了无数弯路。希望这份JSP企业人事管理系统源码包也能让你少踩几个坑。本文还有配套的精品资源点击获取