ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

JSP企业人事管理系统全解析:环境搭建到部署调试

JSP企业人事管理系统全解析:环境搭建到部署调试 之前有个读者私信我说课程设计选了个“JSP企业人事管理系统7jl6b”源码也下了、环境也装了结果一跑就报错来回折腾两天愣是没看到登录页面。这种场景我太熟悉了。JSP作为JavaWeb入门阶段的经典技术栈本身不复杂问题几乎都出在“环境匹配”和“部署细节”上。这篇博客就以这个项目为蓝本从技术选型、设计思路、数据库建模到环境搭建、源码解读、部署调试完整过一遍。内容覆盖程序、源码、数据库、调试部署、开发环境这几个板块适合正在做JavaWeb课程设计、毕业设计或者想系统过一遍JSPServletJDBC这套经典组合的读者。1. 项目整体设计与技术选型1.1 为什么这类管理系统还在用JSP很多人会问现在后端都是SpringBoot的天下怎么课程设计还在用JSP这个问题的答案其实很实在。JSP这类管理系统是JavaWeb教学体系里承上启下的关键一环它帮你把HTTP请求、Servlet生命周期、Session会话管理、JDBC数据库操作这些Web开发的地基全部过了一遍。用JSP写一遍人事管理系统你才知道一个请求从浏览器到服务器再到数据库中间经历了什么。跳过了直接上SpringBoot很多概念就成了黑盒后面排查问题反而更吃力。这套JSP企业人事管理系统7jl6b就是典型的JavaWeb三层结构浏览器发起请求Servlet接收并处理JSP负责展示页面JDBC操作MySQL数据库。它没有Spring那种复杂的容器管理和代理机制所有代码都摆在明面上逻辑清晰特别适合用来理解Web应用的本质。1.2 系统模块与功能清单人事管理系统听起来大核心模块其实就那么几个。这套系统一般包含以下功能块功能模块核心功能点涉及的角色登录与注册账号密码校验、验证码、会话管理所有用户员工管理员工信息的增删改查、条件检索管理员、人事专员部门管理部门列表维护、部门人数统计管理员考勤管理打卡记录查询、出勤统计所有用户薪资管理薪资录入、按月份查询管理员、财务个人中心查看修改个人信息、修改密码所有用户模块划分遵循了“高内聚、低耦合”的思路。每个模块对应一个Servlet或一组ServletJSP页面按模块放在WebContent目录的子文件夹下这种组织方式在项目交付时尤其重要。评审老师打开源码一眼就能看出来作者的工程素养。1.3 数据库设计思路数据库是这套系统能不能跑起来的关键。人事管理系统的实体关系并不复杂员工属于某个部门部门包含多个员工员工有着一条或多条考勤记录薪资记录按月份与员工关联。核心表结构大概是这样的employees表员工基本信息主键是员工编号emp_id外键关联部门编号dept_id包含姓名、性别、手机号、邮箱、入职时间、职位、基本工资等字段。departments表部门表主键dept_id包含部门名称、部门负责人、部门描述、创建时间。attendance表考勤表主键id外键emp_id关联员工记录打卡日期、上班时间、下班时间、考勤状态。salary表薪资表主键id外键emp_id关联员工记录薪资月份、基本工资、奖金、扣款、实发工资。users表系统用户表存储登录账号、密码、真实姓名、角色类型。管理员和普通员工走同一张表通过role字段区分。设计时要注意一个细节员工表和用户表要做区分。员工表存的是企业人事数据用户表存的是系统登录账号。虽然很多时候两者是一对一的关系但逻辑上必须分开这样人事数据变更不影响登录认证系统扩展性也好很多。1.4 源码目录结构的标准写法这套系统的源码目录采用的是JavaWeb标准结构我强烈建议你拿到源码后先花十分钟捋一遍目录不要急着跑JSPEnterprisePersonnelManagementSystem ├── src │ ├── com.xxx.dao // 数据访问层JDBC操作 │ ├── com.xxx.entity // 实体Bean对应数据库表 │ ├── com.xxx.filter // 过滤器处理编码、登录验证 │ ├── com.xxx.servlet // Servlet控制层 │ └── com.xxx.util // 工具类数据库连接、字符串处理 ├── WebContent │ ├── css/ // 层叠样式表 │ ├── images/ // 页面图片 │ ├── js/ // JavaScript脚本 │ └── WEB-INF │ ├── lib/ // 项目依赖的jar包 │ └── web.xml // Web应用部署描述文件 └── sql └── personnel_management.sql // 数据库建库建表脚本如果你的源码包结构比这个多或比这个少问题都不大关键是“实体类-数据访问层-控制层-视图层”这条链路要清晰。实体类对应数据表字段DAO层封装SQL操作Servlet接收请求调用DAO并把结果塞进request或session最后转发给JSP渲染展示。理解了这条链路这套源码就算吃透了一半。2. 开发环境搭建的关键版本匹配2.1 JDK版本和Tomcat版本不能乱配JSP项目跑不起来概率最高的原因就是JDK、Tomcat、IDEA三者版本匹配出了问题。我见过太多人拿JDK 17去跑老项目报错报得莫名其妙。这套JSP人事管理系统技术栈产生的年代对应的是JDK 8兼容性最好的是Tomcat 8.5或Tomcat 9.0。为什么不能直接用JDK 17因为JDK 9开始模块化之后很多老库的反射调用受到限制最典型的就是JSP编译时找不到javax.servlet的类。而且Tomcat 10之后把javax.servlet包名改成了jakarta.servlet老代码直接迁移要改大量import语句别给自己找麻烦。推荐的组合是JDK 8或者OpenJDK 1.8Tomcat 8.5.xx 或 Tomcat 9.0.xxIDEA 2019到2023的任意版本MySQL 5.7 或 MySQL 8.0这套组合经过了无数课设项目验证稳定得不行。你打开项目前先确认本机JDK版本命令行输入java -version一看便知。2.2 IDEA中JSP不高亮和无法识别问题有朋友提到一个很具体的问题“IntelliJ IDEA中Color Scheme里没有JSP”。这个现象一般出现在IDEA社区版上因为社区版不带JavaWeb插件。你打开一个.jsp文件发现整个文件灰蒙蒙的没有任何语法高亮甚至右键没有运行选项。原因就是IDEA没有把JSP识别为Web文件类型。解决办法是先看IDEA版本。如果是社区版而JSP文件确实打不开高亮那么最省事的方案是换用IntelliJ IDEA Ultimate旗舰版学生可以申请免费教育授权。如果暂时换不了旗舰版也可以尝试在Settings - Editor - File Types里手动把*.jsp关联到HTML文件类型但这样只解决高亮问题解决不了内置Tomcat集成问题。做JavaWeb项目我还是建议直接上旗舰版省心太多。还有一个容易忽略的点IDEA打开已有项目时如果没识别成Web项目结构JSP文件里的代码提示也会失效。你可以右键项目根目录选择Add Framework Support勾选Web Application把Web模块补上。这样IDEA才会把WebContent或web目录当作Web资源根目录。2.3 MySQL驱动jar包的匹配陷阱数据库连接是这套系统最容易翻车的地方。你要注意MySQL驱动jar包的版本这是老生常谈但每次都有人踩坑。如果你用的是MySQL 5.7驱动jar包用mysql-connector-java-5.1.49.jar没有毛病。如果用MySQL 8.0还拿5.1的驱动去连它会直接报Communications link failure或者Public Key Retrieval is not allowed。解决方法是换成mysql-connector-java-8.0.30.jar或者更新一点的8.x驱动。驱动版本之外JDBC连接URL也有讲究。MySQL 8.0的连接串最好写成String url jdbc:mysql://localhost:3306/personnel_management?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai;其中serverTimezoneAsia/Shanghai必须加不加就会报时区错误。useSSLfalse是为了避免SSL握手警告。characterEncodingutf8是为了保证中文不乱码。这三个参数缺一个都可能出问题。2.4 在IDEA中配置Tomcat的步骤环境搭建的最后一步是在IDEA里配置Tomcat。有些新手直接双击Tomcat的startup.bat然后在浏览器里访问8080端口页面显示了Tomcat默认首页就算成功。但这跟IDEA集成是两回事你在IDEA里开发的项目不会自动部署到那个Tomcat里。正确做法是点击Run - Edit Configurations左上角加号选择Tomcat Server - Local。在Application Server处点击Configure选择本地Tomcat安装目录。切换到Deployment选项卡点加号选Artifact找到项目名的war exploded。Application Context设置成/personnel或者直接/。点Apply后运行IDEA会自动启动Tomcat并将项目部署到容器上。这里有个关键区别需要搞清楚war包和war exploded包。war是压缩包war exploded是解压目录。开发调试时选war exploded因为IDEA支持热部署改完代码按CtrlF10就能立刻生效。打成正式交付包时再用Maven或IDEA打包成war归档文件。3. 数据库脚本与核心源码走读3.1 建库建表脚本的使用方法每个JSP课设项目里都会带一个sql目录里面是数据库脚本。不要小看这个文件很多项目跑不起来就是卡在数据库导入这一步。使用脚本时要注意两个操作规范。第一新建数据库时要选择正确的字符集。我用Navicat和命令行都试过最稳的方式是先在MySQL里创建一个指定utf8mb4的数据库CREATE DATABASE personnel_management DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;创建完数据库之后再用source命令或者Navicat导入sql文件。直接用导入工具而不管字符集很容易出现中文乱码。第二如果脚本里包含建库语句那你在本机导入时就要注意库名冲突问题。多个课设项目共用一套MySQL时库名很容易撞车导入前先把原来同名的库备份或者删除。以这套系统为例核心建表语句风格大致如下CREATE TABLE departments ( dept_id INT NOT NULL AUTO_INCREMENT, dept_name VARCHAR(50) NOT NULL COMMENT 部门名称, dept_manager VARCHAR(20) DEFAULT NULL COMMENT 负责人, dept_desc VARCHAR(200) DEFAULT NULL COMMENT 部门描述, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (dept_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;建表时统一用InnoDB引擎支持事务和外键约束。虽然课设项目未必用到复杂事务但作为一个规范化的管理系统InnoDB是基本素养。每张表都要有主键自增字段作为逻辑主键业务编号作为唯一索引这是数据库设计的通用规范。3.2 从JDBC到DAO封装的数据访问层这套系统的数据访问层是最值得花时间精读的部分。原始的JDBC写法大家都见过Class.forName注册驱动、DriverManager获取连接、Statement执行SQL、ResultSet遍历结果代码重复度极高。好的课设项目会在util包下封装一个DBUtil工具类把获取连接和关闭资源的逻辑收敛起来。一个标准的JDBC连接工具类核心代码长这样public class DBUtil { private static final String DRIVER com.mysql.cj.jdbc.Driver; private static final String URL jdbc:mysql://localhost:3306/personnel_management?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai; private static final String USER root; private static final String PASSWORD 123456; static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } public static void close(ResultSet rs, PreparedStatement ps, Connection conn) { // 反序关闭资源先ResultSet再PreparedStatement最后Connection } }看到com.mysql.cj.jdbc.Driver这个类名了吗这是MySQL 8.0驱动的新类名。如果你用的是8.0驱动但代码里还写着com.mysql.jdbc.Driver也能跑但会提示你Driver已过时。如果是5.x驱动反过来com.mysql.cj.jdbc.Driver会直接报ClassNotFoundException。这就是驱动版本和代码类的匹配问题。在DAO层这套系统应该使用PreparedStatement而不是Statement。PreparedStatement的好处有两个预编译SQL提升执行效率参数化查询防止SQL注入。员工登录时用户名密码拼接SQL的做法是极为危险的像 or 11这种万能密码可以直接绕过去。用PreparedStatement的setString方法绑定参数从根本上杜绝这个漏洞。这是体现一个Java开发基础素养的细节。3.3 登录模块与会话控制实现登录功能是整个系统的门面也是评审老师必看的核心模块。完整的登录逻辑是这样的用户提交用户名密码后LoginServlet从request中取出参数调用UserDao的findUserByUsernameAndPassword方法把用户信息封装成User对象。如果查到了说明认证通过就把user对象放进session作用域并重定向到系统主页如果没查到转发回登录页并附带错误提示。这里有一个容易被新手忽略的点登录成功后不能使用request.setAttribute存放用户信息然后转发到主页而是必须用session。因为转发是一次请求内部的跳转浏览器地址栏不会变化刷新页面会重复提交表单。重定向是两次请求第一次请求在认证通过后结束第二次请求由浏览器重新发起。重定向配合session存储登录用户才能保证刷新页面不会产生重复提交问题。为了防止未登录用户通过URL直接访问系统页面这个项目里应该有一个LoginFilter。web.xml中配置filter映射到需要保护的路径下核心逻辑如下public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { HttpServletRequest req (HttpServletRequest) request; HttpServletResponse resp (HttpServletResponse) response; HttpSession session req.getSession(false); if (session ! null session.getAttribute(loginUser) ! null) { chain.doFilter(request, response); } else { resp.sendRedirect(login.jsp); } }这段代码解决的是访问控制问题。filter里写session.getSession(false)而不是getSession(true)是因为如果session不存在没必要创建一个新的。这个细节写进课设报告里会很加分。3.4 员工列表的分页查询与模糊检索人事管理系统的员工列表页数据量通常不会太大但分页功能必须具备。合理的设计是把分页参数封装好SQL层面用LIMIT控制查询范围。假设每页显示10条记录当前页码是pageNum查询第pageNum页数据的SQL是SELECT * FROM employees LIMIT ?, ?;第一个参数是偏移量offset计算方式是(pageNum - 1) * pageSize第二个参数是pageSize。为什么偏移量要用pageNum减1再乘页大小因为第一页的offset是0第二页是10第三页是20。这是数据库分页的基本功很多人就在这里翻车。模糊检索也类似员工姓名或部门搜索条件动态拼接进SQL。注意使用PreparedStatement时LIKE语句的参数要手动拼接百分号String sql SELECT * FROM employees WHERE emp_name LIKE ? LIMIT ?, ?; preparedStatement.setString(1, % keyword %); preparedStatement.setInt(2, offset); preparedStatement.setInt(3, pageSize);关键词不能直接放到SQL模板里要作为绑定参数传入。同时注意百分号是拼在参数里的不是拼在SQL模板里的。这个细节我亲自见过几个学生搭错导致搜索永远查不出结果。4. 调试部署与问题排查实录4.1 混淆的启动方式不少新人对“启动项目”这件事存在理解偏差。有人直接双击Tomcat的startup.bat然后访问项目地址发现404有人在IDEA里不配置Tomcat直接右键JSP页面Run结果浏览器打开了一堆JSP源码。这两种方式都不对。JSP文件本质上是一个Servlet必须运行在Servlet容器里。右键JSP直接Run用的是文件系统静态解析不会经过Tomcat的JSP引擎编译所以页面上的JSTL标签、EL表达式全部原样显示在页面上或者直接报错。而双击startup.bat只是单独启动了Tomcat没有完成项目部署所以访问不到应用的ContextPath。正确的做法只有一个在IDEA里配置好Tomcat Server把项目作为Artifact部署进去然后通过IDEA的Run按钮启动。IDEA启动过程中会自动调起Tomcat把项目的war exploded目录部署到webapps下面整个过程在控制台里能看到日志输出。4.2 三个最常见的启动失败原因第一是端口占用。Tomcat默认8080端口如果你之前开过其他服务占用了8080启动日志里会报Port 8080 was already in use。解决方式有两种杀掉占用进程或者在IDEA配置里把Tomcat端口改掉。改端口记住把HTTP Port和JMX Port都改了不然改了个寂寞。第二种是404错误。项目成功启动但访问地址返回404。这个基本是Application Context和实际访问路径不匹配。如果你在Deployment里配置的Application Context是/personnel那么访问地址必须是http://localhost:8080/personnel/。第三种是数据库连接失败。启动时页面能打开一旦操作登录或查询就报Cannot create PoolableConnectionFactory或Access denied for user。这就是数据库驱动、URL、账号密码三者至少有一个出问题了。这个排查顺序要记牢先看MySQL服务是否启动再看账号密码是否正确再看驱动版本和URL参数最后看库名是否存在。4.3 数据库连接失败定位方法数据库连接不上很多人一上来就改代码其实最快定位问题的方法是先绕过项目用命令行直接测试连接。打开终端执行mysql -uroot -p能进来说明MySQL服务正常。如果报ERROR 2003说明MySQL服务没启动。Windows下到服务管理里启动MySQL服务Linux下用systemctl启动。如果报ERROR 1045说明密码错误。这里要注意如果你用的是MySQL 8.0root用户的加密方式是caching_sha2_password而老版本JDBC驱动不支持这种加密方式就会报Public Key Retrieval错误。这也就是为什么前面强调要用8.x驱动。另外通过show databases;检查数据库是否存在表名是否和代码里匹配。JSP报错日志淡化了具体SQL错误这时要去看IDEA控制台的完整堆栈。4.4 开发部署问题速查表我把这套JSP系统调试过程中最常见的几类问题汇总成一张表按问题现场和解决办法检索即可问题现场可能原因解决办法启动Tomcat报端口被占用8080端口已被其他进程使用netstat -ano命令查PID任务管理器结束进程或修改Tomcat端口浏览器访问显示源码或下载文件Tomcat未配置JSP引擎或IDE未识别Web项目检查是否通过IDEA集成部署而不是直接打开JSP文件启动成功但访问404ContextPath配置错误或未部署Artifact检查Deployment中Artifact和Application Context设置中文乱码页面编码、请求编码、数据库连接编码不一致JSP页面设置UTF-8配置CharacterEncodingFilter数据库连接串加characterEncodingutf8数据库访问拒绝用户权限或密码错误检查DBUtil中的账号密码MySQL8注意加密方式找不到驱动类jar未放入WEB-INF/lib或版本不对确认mysql-connector-java版本刷新ArtifactIDEA中JSP不高亮社区版缺少Web插件或文件未关联安装插件、使用旗舰版、File Types手动关联页面样式失效ContextPath变化导致CSS引用路径错误使用%request.getContextPath()%拼接资源路径4.5 我踩过最深的坑IDEA社区版做JSP项目讲个真实经历。我刚开始带课设那会儿有个学生用的IntelliJ IDEA Community Edition把源码导入后JSP文件全部白茫茫一片代码提示也没有。他以为是源码有问题反复重新导入了很多遍结果都一样。后来帮他远程看才发现IDEA社区版根本不含JavaEE插件JSP、Servlet、Tomcat集成这些功能社区版天生就不支持。不是代码的问题是工具选错了。解决方式是直接换Ultimate版本从官网下载30天试用或者用学生邮箱申请一年免费授权课设做完绰绰有余。所以拿到这套JSP人事管理系统源码第一件事就是确认自己的IDEA版本和JDK版本别急着改代码。5. 数据库脚本导入与数据同步实操5.1 用Navicat导入SQL脚本的正确姿势这套系统交付时带有sql脚本下面说的导入步骤适合绝大多数JSP项目。如果拿到的是.sql文件不要直接双击打开复制粘贴容易编码错乱。正确操作是先在Navicat左侧连接到本机MySQL右键连接选择新建数据库数据库名建议与项目数据库配置类中URL里的库名保持一致字符集选utf8mb4排序规则选utf8mb4_general_ci。数据库建好之后右键这个库选择“运行SQL文件”选中脚本文件然后开始执行。执行完成后刷新下数据表如果全部出现在列表里导入就成功了。这时候可以用SELECT * FROM departments;验证一下中文是否正常显示。5.2 从开发库到演示库的数据迁移项目交付前通常需要准备一套带初始数据的演示库。有些同学在本机跑通后把项目拷给老师或同学但没带数据库脚本或者带了脚本但忘了带数据。最好的做法是用mysqldump工具导出一个完整的数据脚本包含建表语句和INSERT语句。命令如下mysqldump -uroot -p personnel_management personnel_management.sql执行完会生成一个包含建库建表和数据插入的完整脚本。注意默认情况下mysqldump不会包含CREATE DATABASE语句要加--databases参数才会mysqldump -uroot -p --databases personnel_management personnel_management.sql这样对方拿到脚本后直接source导入数据库就整个复原了不用手动建库。5.3 项目代码中的数据库配置统一修改很多初学者改数据库配置只知道改DBUtil类但有些项目会通过properties文件读取配置如果漏改会导致“数据库连不上但代码看起来没问题”。拿到这套系统源码时建议全局搜索jdbc:mysql://或者password关键字把数据库连接相关的配置全部揪出来统一改成自己本机的MySQL账号密码和库名。这里有一个保守建议项目里如果出现了明文密码是root/123456之类的组合在自己本机跑通常没问题。但是如果要交付给别人运行对方MySQL的root密码可能不一样最简单的办法是教对方把MySQL的root密码改成123456或者统一修改源码里的配置文件。自行取舍。6. 这套JSP人事系统还能怎么扩展源码拿到手不只是为了跑通提交上去你可以基于它做一些扩展提升项目完成度这个在答辩时非常加分。比如增加图片上传功能用SmartUpload组件员工头像上传到服务器目录数据库里存图片路径这样就多了文件IO的考察点。再比如增加数据导出到Excel的功能用Apache POI把员工表数据生成.xls文件下载到本地等于拓展到第三方库的使用。还可以增加操作日志表记录每次增删改操作的操作人、操作时间和操作内容这是在真实企业系统里很常见的设计。这些扩展不需要改动系统整体架构只需要在现有链路里插入新的Servlet和JSP页面。以POI导出为例就是在EmployeeServlet里加了一个export方法查询全部员工列表构建Workbook对象设置响应头让浏览器以附件形式下载。代码量不大但其含金量比单纯跑通一个基础功能要高很多。从学习角度看这套系统的源码足够支撑你弄懂JavaWeb的核心链路从数据库建模到DAO层封装从Servlet请求处理到JSP页面展示每一环都能找到对应的代码。跑通只是第一步真正花时间把代码读完改完你的收获会远超一个课设分数。我个人在实际操作中的体会是这种系统拿到手第一件事不是急着配环境而是先花十五分钟把项目结构梳理清楚把数据库脚本导入进去把每个Servlet和JSP的对应对照关系画出来。如果你能不看文档把系统的登录流程和数据流向讲明白这个项目就真正变成你自己的了。当年我做过一个类似的员工管理系统后来在SpringBoot项目里遇到请求过滤器和拦截器的问题时第一时间想到的就是当年在JSP项目里写的那个LoginFilter底层逻辑一脉相承那些踩过的坑反而成了最值钱的经验。
返回列表