简介:这是一套基于JSP+Servlet+Tomcat+MySQL实现的完整人事管理系统源码,面向计算机、数学、电子信息等专业的本科生及初学者,适用于课程设计、期末大作业与毕业设计参考。系统涵盖员工信息管理、部门维护、考勤统计、权限控制等核心模块,采用经典B/S架构与MVC分层思想,便于理解Web开发全流程与数据库交互逻辑。压缩包共2000个文件,主体为49个Java后端类、42个JSP页面、1294个JS脚本及404个CSS样式文件,辅以SQL建表语句、配置文件与说明文档,整体73.74MB,结构清晰、注释较全,适合作为Java Web入门到进阶的实践范例。目前已有205人学习下载,资源提供开箱即用的可运行环境(含adminLTE前端框架),并附带详细部署说明与常见问题提示,有助于快速掌握项目搭建、代码调试与功能扩展方法。
1. 这不是“老古董”,而是能跑通、能调试、能交差的 JavaWeb 实战基线:一个完整人事管理系统源码包,为什么值得你花 20 分钟解压、配环境、跑起来?
你可能刚在头歌实训里卡在HttpServlet的doGet和doPost区分上,也可能正被毕设选题折磨——导师说“别用 Spring Boot,得体现 Servlet 基础”,而你搜到的所谓“JSP 项目”点开全是空文件夹或报错 404。这个基于jsp+servlet+tomcat+mysql的人事管理系统源码.zip不是教学幻灯片,也不是阉割版 demo,它是一套真实可运行、结构清晰、有登录鉴权、有增删改查、有前端 AdminLTE 界面、有 MySQL 表结构脚本、有 Tomcat 部署路径约定的完整工程。它解决的不是“怎么写 HelloWorld.jsp”,而是“如何把用户登录、部门管理、员工档案录入、离职状态更新、权限跳转这些业务逻辑,用原生 JSP+Servlet 串成一条不崩的链路”。适合计算机/软工专业大三学生做课程设计,也适合想补全 JavaWeb 底层链路(从请求进 Filter 到 Servlet 处理再到 JSP 渲染)的转岗者。它不炫技,但每一步都踩在 JavaWeb 开发的真实断点上:比如web.xml里 servlet-mapping 的/emp/*路径匹配规则、context.xml中 JNDI 数据源配置、WEB-INF/web.xml与META-INF/MANIFEST.MF的协同作用——这些不是考点,是部署时真正会卡住你的地方。
2. 从解压到首页渲染:五步走通整个部署链路,每一步都对应一个真实环境变量
2.1 解压后先看目录结构:识别核心模块与“非装饰性”文件
解压后你会看到类似这样的层级(实际以 ZIP 内容为准,但典型结构如下):
hrms/ ├── src/ # Java 源码根目录 │ ├── main/ │ │ ├── java/ # Servlet 类、DAO、Service 层 │ │ │ └── com/hrms/ # 包名前缀,含 LoginServlet.java, EmpServlet.java 等 │ │ └── resources/ # db.properties 或 jdbc.properties(关键!) │ └── webapp/ # Web 资源根目录(等同于传统 WebContent) │ ├── WEB-INF/ │ │ ├── web.xml # 核心配置:servlet 定义、filter、welcome-file-list │ │ └── lib/ # jar 包:mysql-connector-java-x.x.jar 必须存在 │ ├── static/ # CSS/JS 静态资源(注意:adminlte.css 在此目录下) │ └── jsp/ # 所有 .jsp 页面:login.jsp, index.jsp, emp_list.jsp 等 ├── sql/ # 数据库脚本:hrms.sql 或 init.sql(建库建表+初始数据) └── README.md # (如有)说明数据库用户名密码、默认账号提示:
adminlte.css等文件出现在static/下而非WEB-INF/,是因为WEB-INF是受保护目录,外部无法直接访问。所有 CSS/JS 必须放在webapp/static/或webapp/根下才能被浏览器加载。这是新手第一次启动页面空白的最常见原因。
2.2 数据库初始化:执行 SQL 脚本前必须确认三件事
不要直接双击.sql文件用 Navicat 执行——很多脚本依赖CREATE DATABASE IF NOT EXISTS hrms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;这类语句,而 Navicat 默认不启用“执行多条语句”选项。
正确做法(命令行优先,避免 GUI 陷阱):
# 1. 登录 MySQL(假设 root 密码为 123456) mysql -u root -p123456 # 2. 手动创建数据库(确保字符集) CREATE DATABASE hrms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 3. 退出后执行脚本(关键:-e 参数让 mysql 客户端执行完即退出) mysql -u root -p123456 hrms < /path/to/hrms/sql/hrms.sql参数说明:
utf8mb4:支持 emoji 和四字节 UTF-8 字符,避免中文乱码(尤其姓名字段含生僻字时);-e:避免交互式等待,适合自动化部署;hrms.sql中应包含USE hrms;和完整的CREATE TABLE语句,若无USE,需在脚本开头手动加。
2.3 Tomcat 配置:context.xml与web.xml的双重绑定
该系统大概率使用 JNDI 数据源(比硬编码 URL 更安全),因此src/main/webapp/META-INF/context.xml是必查文件:
<!-- META-INF/context.xml --> <?xml version="1.0" encoding="UTF-8"?> <Context> <Resource name="jdbc/hrms" auth="Container" type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/hrms?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai" username="root" password="123456" maxActive="20" minIdle="5" maxWait="10000"/> </Context>关键点解析:
name="jdbc/hrms":JNDI 名称,必须与web.xml中<resource-ref>的res-ref-name一致;url中serverTimezone=Asia/Shanghai:MySQL 8.0+ 强制要求,否则报The server time zone value '...' is unrecognized;&:XML 中&必须转义,写成&,否则 Tomcat 启动失败。
同时检查WEB-INF/web.xml是否声明了该资源:
<!-- WEB-INF/web.xml --> <resource-ref> <description>HRMS Database Connection</description> <res-ref-name>jdbc/hrms</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>2.4 IDE 配置:IntelliJ IDEA 中让 JSP 正确编译的三个隐藏开关
即使你已配置好 Tomcat Server,JSP 仍可能报java.lang.ClassNotFoundException: org.apache.jsp.index_jsp——这不是类路径问题,而是 IDEA 未启用 JSP 编译器。
必须操作:
File → Project Structure → Modules → [你的模块] → Sources:确认src/main/webapp已标记为Web Resources Root;File → Settings → Build → Compiler → Java Compiler:勾选"Use compiler: javac in-process"(避免 JDK 版本冲突);File → Settings → Build → Compiler → Compiler → Java Compiler:设置Target bytecode version = 8(JSP 编译依赖 Java 8 兼容性);- 最关键一步:
File → Settings → Build → Compiler → Annotation Processors→ 勾选"Enable annotation processing",并设置Processor path为tomcat/lib/jasper.jar(路径需指向你本地 Tomcat 的lib目录)。
血泪经验:很多教程漏掉第 4 步,导致 JSP 页面始终 500 错误,日志只显示
org.apache.jasper.JasperException: Unable to compile class for JSP,根本原因就是jasper.jar未参与编译过程。
2.5 启动验证:用 curl 命令绕过浏览器,直击 Tomcat 响应头
不要一上来就打开http://localhost:8080/hrms/login.jsp——先用命令行确认服务是否真正响应:
# 发送 GET 请求,只看 HTTP 状态码和 Content-Type curl -I http://localhost:8080/hrms/login.jsp # 预期返回(关键看 200 OK 和 text/html) HTTP/1.1 200 OK Content-Type: text/html;charset=UTF-8 Content-Length: 2345 Date: Mon, 15 Apr 2024 08:22:17 GMT如果返回HTTP/1.1 404 Not Found:
- 检查 WAR 包是否部署成功(
$TOMCAT_HOME/webapps/下是否有hrms/目录); - 检查
web.xml中<welcome-file-list>是否包含login.jsp; - 检查
login.jsp是否真在webapp/jsp/下(而非webapp/根目录)。
如果返回HTTP/1.1 500 Internal Server Error:
- 查
catalina.out日志末尾,定位Caused by:行; - 最常见是
ClassNotFoundException: com.mysql.cj.jdbc.Driver(jar 包没放对位置)或SQLException: Access denied for user 'root'@'localhost'(数据库密码错误)。
3. Servlet 生命周期与请求流转:从 login.jsp 提交到 LoginServlet 的七层调用链
3.1 表单提交路径:action属性如何触发正确的 Servlet 映射
login.jsp中的表单通常长这样:
<form action="login" method="post"> <input type="text" name="username" /> <input type="password" name="password" /> <button type="submit">登录</button> </form>注意action="login"是相对路径,它会被浏览器解析为http://localhost:8080/hrms/login。而web.xml中必须有对应映射:
<servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>com.hrms.servlet.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login</url-pattern> <!-- 关键:必须与 action 值完全一致 --> </servlet-mapping>玄学细节:/login是精确匹配;/login/*是路径前缀匹配;*.do是扩展名匹配。本项目用前者,意味着只有POST /login才会进入LoginServlet,GET /login会 405 错误(除非doGet()也实现)。
3.2 LoginServlet 的标准处理流程:request.getParameter() 到 request.getRequestDispatcher() 的闭环
典型LoginServlet.java代码片段:
public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 获取表单参数(注意:name 属性值必须与 getParameter() 一致) String username = request.getParameter("username"); // 来自 <input name="username"> String password = request.getParameter("password"); // 2. 调用 Service 层验证(此处简化为硬编码校验) if ("admin".equals(username) && "123456".equals(password)) { // 3. 设置 session 属性(登录态) request.getSession().setAttribute("user", username); // 4. 转发到主页(注意:/index.jsp 是相对于 webapp 的路径) request.getRequestDispatcher("/jsp/index.jsp").forward(request, response); } else { // 5. 转发回登录页,并带错误信息 request.setAttribute("error", "用户名或密码错误"); request.getRequestDispatcher("/jsp/login.jsp").forward(request, response); } } }参数说明:
request.getRequestDispatcher():服务器端内部跳转,URL 地址栏不变,request对象可传递属性;response.sendRedirect():客户端重定向,URL 变化,request属性丢失(本项目登录成功后用forward,避免刷新重复提交);request.getSession().setAttribute():将用户信息存入 Session,后续所有 Servlet 可通过request.getSession().getAttribute("user")获取。
3.3 Filter 拦截器:如何实现未登录用户访问员工列表自动跳转
web.xml中定义的LoginFilter是权限控制核心:
<filter> <filter-name>LoginFilter</filter-name> <filter-class>com.hrms.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>LoginFilter</filter-name> <url-pattern>/jsp/emp_list.jsp</url-pattern> <!-- 拦截具体 JSP 页面 --> <url-pattern>/servlet/EmpServlet</url-pattern> <!-- 拦截 Servlet --> </filter-mapping>LoginFilter.java关键逻辑:
public class LoginFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; // 1. 检查 session 中是否存在 user 属性 Object user = request.getSession().getAttribute("user"); if (user == null) { // 2. 未登录,重定向到登录页(注意:sendRedirect 用绝对路径) response.sendRedirect(request.getContextPath() + "/jsp/login.jsp"); return; // 阻断后续执行 } // 3. 已登录,放行 chain.doFilter(req, resp); } }注意:request.getContextPath()返回应用上下文路径(如/hrms),确保重定向地址为http://localhost:8080/hrms/jsp/login.jsp,而非硬编码/jsp/login.jsp(否则部署到 ROOT 上下文会失效)。
3.4 EmpServlet 的 CRUD 实现:URL 路径设计决定功能分支
EmpServlet通常通过?action=add或/emp/delete?id=123区分操作类型:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String action = request.getParameter("action"); switch (action) { case "list": showEmpList(request, response); // 查询全部员工 break; case "toAdd": request.getRequestDispatcher("/jsp/emp_add.jsp").forward(request, response); break; case "delete": deleteEmp(request, response); // 删除 break; default: response.sendError(HttpServletResponse.SC_BAD_REQUEST); } } private void deleteEmp(HttpServletRequest request, HttpServletResponse response) throws IOException { String idStr = request.getParameter("id"); int id = Integer.parseInt(idStr); // 注意:生产环境需 try-catch EmpService.delete(id); // 调用 DAO 执行 DELETE FROM emp WHERE id=? response.sendRedirect(request.getContextPath() + "/servlet/EmpServlet?action=list"); }边界坑:Integer.parseInt()在id为空或非数字时抛NumberFormatException,必须包裹 try-catch 并返回友好提示,否则 500 错误。
4. 前端 AdminLTE 集成:CSS 文件加载失败的四个真实原因与修复方案
4.1 路径引用必须遵循 WAR 包结构:/static/adminlte.cssvs../static/adminlte.css
index.jsp中引入 CSS 的典型写法:
<!-- 错误:相对路径,依赖当前 JSP 所在目录层级 --> <link rel="stylesheet" href="../static/adminlte.css"> <!-- 正确:绝对路径,从上下文根开始 --> <link rel="stylesheet" href="${pageContext.request.contextPath}/static/adminlte.css">为什么必须用${pageContext.request.contextPath}?
因为应用可能部署在/hrms或/ROOT下。硬编码/static/在 ROOT 上下文下有效,但在/hrms下会请求http://localhost:8080/static/adminlte.css(404);而${pageContext.request.contextPath}动态输出/hrms或/,保证路径正确。
4.2 AdminLTE 版本兼容性:adminlte.core.css与 jQuery 的版本锁死关系
该 ZIP 包中出现adminlte.core.css和adminlte.core.min.css,表明使用的是 AdminLTE v3+(v2 无 core 文件)。v3 要求 jQuery ≥ 3.4.1,而 Tomcat 默认的jsp-api.jar仅提供 JSP 规范,不包含 jQuery。
检查步骤:
- 打开
webapp/static/js/,确认存在jquery.min.js(版本号需 ≥ 3.4.1); - 在
index.jsp中<head>里,jQuery 必须在 AdminLTE JS 之前加载:
<script src="${pageContext.request.contextPath}/static/js/jquery.min.js"></script> <script src="${pageContext.request.contextPath}/static/js/bootstrap.bundle.min.js"></script> <script src="${pageContext.request.contextPath}/static/js/adminlte.min.js"></script>翻车现场:若bootstrap.bundle.min.js在jquery.min.js之前加载,浏览器控制台报Uncaught ReferenceError: $ is not defined,AdminLTE 的侧边栏、折叠菜单全部失效。
4.3 中文乱码终极排查:从 MySQL 到 JSP 的四层字符集校验
即使页面<meta charset="UTF-8">正确,仍可能显示??,必须逐层验证:
| 层级 | 检查项 | 验证命令/方法 | 期望值 |
|---|---|---|---|
| MySQL 服务端 | 服务器默认字符集 | mysql -u root -p -e "SHOW VARIABLES LIKE 'character_set%';" | character_set_server = utf8mb4 |
| MySQL 数据库 | hrms库字符集 | SHOW CREATE DATABASE hrms; | DEFAULT CHARACTER SET = utf8mb4 |
| MySQL 表 | emp表字符集 | SHOW CREATE TABLE emp; | DEFAULT CHARSET=utf8mb4 |
| JSP 页面 | 页面编码声明 | 查login.jsp第一行:<%@ page contentType="text/html;charset=UTF-8" %> | 必须存在且为UTF-8 |
漏掉任何一层,中文都会变问号。尤其注意db.properties中 JDBC URL 必须含?useUnicode=true&characterEncoding=utf8。
4.4 Tomcat 乱码:catalina.sh中 JVM 参数的隐形杀手
Linux 下启动 Tomcat 后,日志中System.out.println("张三")显示为å¼ ä¸,根源是 JVM 默认编码非 UTF-8。
修复方法(永久生效):
编辑$TOMCAT_HOME/bin/catalina.sh,在JAVA_OPTS定义处添加:
# 在 catalina.sh 中找到 JAVA_OPTS 行,追加: JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"Windows 用户:修改catalina.bat,在set JAVA_OPTS=行后添加set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8。
后悔药:若已部署,可临时在
web.xml中添加filter强制请求编码:
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>5. 避坑指南:五个高频翻车点与对应诊断命令(附真实日志片段)
5.1 现象:启动 Tomcat 后访问http://localhost:8080/hrms/login.jsp返回 404
原因:WAR 包未正确部署,或web.xml中welcome-file-list未包含login.jsp
解决:
- 检查
$TOMCAT_HOME/webapps/下是否存在hrms/目录(而非hrms.war); - 查
web.xml是否有:
<welcome-file-list> <welcome-file>jsp/login.jsp</welcome-file> <!-- 注意路径:jsp/ 开头 --> </welcome-file-list>若
welcome-file写成login.jsp(无jsp/前缀),Tomcat 会在webapp/根下找,但实际文件在webapp/jsp/下,必然 404。
5.2 现象:登录时控制台报java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver
原因:mysql-connector-java-8.0.33.jar未放入WEB-INF/lib/,或版本与 MySQL 不匹配
解决:
- 确认
src/main/webapp/WEB-INF/lib/下有mysql-connector-java-x.x.jar(x.x ≥ 8.0); - 若用 MySQL 5.7,需降级到
mysql-connector-java-5.1.49.jar; - 验证命令:
jar -tf target/hrms/WEB-INF/lib/mysql-connector-java-8.0.33.jar | grep Driver应输出com/mysql/cj/jdbc/Driver.class。
5.3 现象:点击“员工列表”按钮后页面空白,浏览器控制台报Uncaught TypeError: $ is not a function
原因:jQuery 未加载成功,或加载顺序错误
解决:
- 打开浏览器开发者工具 → Network 标签 → 刷新页面 → 查看
jquery.min.js请求状态码是否为 200; - 若为 404,检查
href路径是否漏写${pageContext.request.contextPath}; - 若为 200 但控制台仍有报错,查看 Elements 中
<script>标签顺序,确保 jQuery 在所有依赖它的 JS 之前。
5.4 现象:新增员工后数据库无记录,但页面跳转到emp_list.jsp
原因:EmpServlet中add方法未 commit 事务,或 DAO 层 SQL 语法错误
解决:
- 查
EmpDao.java中insert方法,确认是否调用conn.commit()(若用 JNDI 数据源,通常已配置自动 commit); - 在
EmpDao.insert()中添加日志:System.out.println("SQL: " + sql + ", params: " + Arrays.toString(params));; - 将打印出的 SQL 粘贴到 MySQL 命令行执行,观察是否报错(如字段名拼写错误、NOT NULL 字段未赋值)。
5.5 现象:Tomcat 启动后立即闪退,catalina.out末尾显示SEVERE: Failed to initialize connector [Connector[HTTP/1.1-8080]]
原因:8080 端口被占用(常见于 Skype、其他 Tomcat 实例)
解决:
- Linux:
netstat -tuln | grep :8080→kill -9 <PID>; - Windows:
netstat -ano | findstr :8080→taskkill /PID <PID> /F; - 或修改
$TOMCAT_HOME/conf/server.xml中<Connector port="8080"为8081。
6. 进阶技巧:用 Maven 重构原始项目,实现一键打包与跨环境部署
6.1 为什么必须重构?原始 ZIP 的三大维护痛点
你拿到的 ZIP 是纯手工目录结构,没有pom.xml,这意味着:
- 无法用
mvn clean package一键构建 WAR; - 添加新 jar 包(如 Apache Commons Lang)需手动复制到
WEB-INF/lib/; - 开发环境(localhost)、测试环境(192.168.1.100)、生产环境(prod-db)的数据库配置无法隔离。
重构目标:将src/main/java、src/main/webapp等目录按 Maven 标准布局,用profiles管理不同环境配置。
6.2pom.xml核心配置:定义 Java 版本、Tomcat 插件与依赖范围
<project xmlns="http://maven.apache.org/POM/4.0.0"> <modelVersion>4.0.0</modelVersion> <groupId>com.hrms</groupId> <artifactId>hrms</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- Servlet API:provided 范围,由 Tomcat 提供,不打入 WAR --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <!-- MySQL 驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> </dependencies> <build> <plugins> <!-- Tomcat 插件:mvn tomcat7:run 直接启动 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <path>/hrms</path> <uriEncoding>UTF-8</uriEncoding> </configuration> </plugin> </plugins> </build> </project>关键点:
<scope>provided</scope>:告诉 Maven 此依赖由容器提供,打包时不包含,避免与 Tomcat 自带的servlet-api.jar冲突;tomcat7-maven-plugin:虽名 tomcat7,实则支持 Tomcat 8/9/10,mvn tomcat7:run启动内嵌 Tomcat,无需单独安装。
6.3 多环境配置:用profiles实现 dev/test/prod 数据库无缝切换
在pom.xml中添加 profiles:
<profiles> <profile> <id>dev</id> <properties> <jdbc.url>jdbc:mysql://localhost:3306/hrms?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai</jdbc.url> <jdbc.username>root</jdbc.username> <jdbc.password>123456</jdbc.password> </properties> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> <profile> <id>prod</id> <properties> <jdbc.url>jdbc:mysql://prod-db:3306/hrms?...</jdbc.url> <jdbc.username>hrms_prod</jdbc.username> <jdbc.password>${env.PROD_DB_PASSWORD}</jdbc.password> </properties> </profile> </profiles>配合src/main/resources/db.properties使用:
jdbc.url=${jdbc.url} jdbc.username=${jdbc.username} jdbc.password=${jdbc.password}打包命令:
- 开发环境:
mvn clean package(默认激活 dev); - 生产环境:
mvn clean package -Pprod -Denv.PROD_DB_PASSWORD=real_password。
6.4 自动化部署脚本:Linux 下一键重启 Tomcat 并发布新 WAR
编写deploy.sh(需赋予执行权限chmod +x deploy.sh):
#!/bin/bash # 1. 停止 Tomcat $TOMCAT_HOME/bin/shutdown.sh sleep 5 # 2. 删除旧应用 rm -rf $TOMCAT_HOME/webapps/hrms* rm -rf $TOMCAT_HOME/work/Catalina/localhost/hrms* # 3. 复制新 WAR(假设 mvn package 后生成 target/hrms-1.0-SNAPSHOT.war) cp target/hrms-1.0-SNAPSHOT.war $TOMCAT_HOME/webapps/hrms.war # 4. 启动 Tomcat $TOMCAT_HOME/bin/startup.sh # 5. 检查启动日志(tail -f 会持续输出,Ctrl+C 退出) echo "Deploy complete. Checking logs..." tail -n 20 $TOMCAT_HOME/logs/catalina.out为什么这比手动复制更可靠?
- 强制删除
work/目录:清除 Jasper 编译缓存,避免旧 JSP class 未更新; sleep 5:确保 Tomcat 进程完全退出,防止端口占用;tail -n 20:快速确认最后一屏日志无 ERROR,比打开完整日志高效。
从那以后我每次交付课程设计,都强制走一遍mvn clean package→sh deploy.sh→curl -I http://localhost:8080/hrms/login.jsp三连,哪怕只是本地测试。因为真正的“跑通”,不是浏览器看到登录框,而是curl返回200 OK且Content-Type正确——这背后是数据库连接、Servlet 映射、JSP 编译、静态资源路径、字符集、Session 管理全部链条的咬合。希望帮到你。
本文还有配套的精品资源,点击获取