简介:这是一套基于Java Web主流技术栈开发的学生信息管理系统完整源码,面向计算机专业本科生及Java初学者,适用于课程设计、期末大作业与Web开发入门实践。系统采用Servlet处理业务逻辑、JSP实现页面展示、Bootstrap优化前端交互、MySQL存储数据,结构清晰、功能完整,涵盖学生/教师双角色登录、信息增删改查、密码找回等核心模块,代码已通过本地编译验证,评审得分98分,难度适中且经助教审定,具备教学示范性与工程参考价值。资源包共82个文件,含20个Java源文件、21个Class编译类、15个JSP页面、6个CSS样式文件及SQL建库脚本等,总大小12.03MB,目录组织规范,便于理解MVC分层结构与项目部署流程。目前已有162人学习下载,配套详细使用说明与README文档,开箱即用,可直接导入IDE运行调试,是巩固Servlet/JSP基础、掌握前后端协同开发的优质实践素材。
1. 这不是“过时技术堆砌”,而是一套能跑通、能交付、能面试讲清楚的 Java Web 全栈最小闭环
你搜“Java+Servlet+JSP+Bootstrap+MySQL 学生信息管理系统”,大概率正卡在三个现实节点上:课程设计 deadline 剩 72 小时、毕设开题被导师质疑“技术栈太老”,或者面试官盯着你简历上那行“熟悉 Java Web 基础”问:“那你手写一个 Servlet 处理增删改查,不许用 Spring Boot,怎么保证 URL 路由不冲突?”——这项目标题里没写 Spring、没提 Maven、没带 Tomcat 版本号,但它恰恰是检验你是否真懂 Java Web 底层脉络的“压力测试仪”。它用最朴素的技术组合(Servlet 控制流程、JSP 渲染视图、Bootstrap 快速美化、MySQL 持久化),逼你亲手串起请求生命周期、会话管理、SQL 注入防护、表单验证、前后端数据流转这些被框架封装掉的“黑匣子”。我带过 37 个学生做这个系统,90% 的翻车点不在代码语法,而在“以为 JSP 就是 HTML 写 Java 代码”“以为 Bootstrap 引入 CSS 就完事”“把 MySQL root 密码硬编码进 JDBC URL”。这篇笔记不讲理论推导,只拆解:从零建工程、让第一个 JSP 页面在浏览器弹出“欢迎,张三”,到点击“新增学生”按钮真正写入数据库并跳转回列表页——每一步命令、每个配置文件字段、每个容易被 IDE 自动忽略的路径陷阱。适合正在赶课设/毕设、想补全 Java Web 底层认知、或需要向面试官证明“我能脱离框架造轮子”的人。
2. 用 IntelliJ IDEA 新建标准 Java Web 项目:绕过 Maven 依赖幻觉,直击 classpath 和部署结构
传统 JSP 项目不是靠mvn clean install一键打包就能跑起来的黑盒。它的生命线系在两个地方:一是 IDE 如何识别WEB-INF/web.xml和lib目录为 Web 根目录,二是 Tomcat 启动时如何加载classes下的 Servlet 类和lib中的 JDBC 驱动。很多新手在 IDEA 里新建项目后直接写 JSP,结果浏览器报 404,根本原因是 IDEA 默认创建的是普通 Java Module,而非 Web Application Module。下面步骤基于 IntelliJ IDEA 2023.3(社区版/Ultimate 均适用),全程手动配置,不依赖任何插件模板。
2.1 创建 Web Application Module 并校验目录结构
打开 IDEA → New Project → 左侧选Java→ 右侧勾选Web Application(注意:不是 “Maven” 或 “Gradle”)→ Next → Project name 填student-mgmt→ Finish。IDEA 会自动生成标准目录:
student-mgmt/ ├── src/ # Java 源码(Servlet、DAO、Bean) │ └── main/ # 注意:这里没有 /main,而是直接 src/ │ └── java/ # Servlet 类放这里 ├── web/ # Web 根目录(等同于 Tomcat 的 webapps/ROOT) │ ├── WEB-INF/ │ │ ├── web.xml # 核心配置文件,必须存在 │ │ └── lib/ # 放 mysql-connector-java-x.x.x.jar │ ├── index.jsp # 首页 │ └── css/ # Bootstrap CSS 文件放这里 └── pom.xml # 如果你误选了 Maven,这个文件会存在;但本项目手动管理依赖,可删提示:若你看到
src/main/java结构,说明你创建的是 Maven 项目,需右键student-mgmt→Add Framework Support→ 勾选Web Application→ 点击 OK,IDEA 会自动补全web/目录和WEB-INF/web.xml。
2.2 配置 Tomcat Server 并设置 Artifact
这是最容易被跳过的致命步骤。IDEA 不会自动把你的web/目录映射到 Tomcat 的webapps。
Step 1:File → Project Structure → Artifacts → + → Web Application: Exploded → From modules → 选中student-mgmt→ OK。此时右侧会出现student-mgmt:war exploded,展开它,确认 Output directory 指向out/artifacts/student_mgmt_war_exploded,且web目录下的所有内容(含WEB-INF)已包含在内。
Step 2:Run → Edit Configurations → + → Tomcat Server → Local → Name 填Tomcat 9(需提前下载 Apache Tomcat 9.0.x,解压即可,无需安装)→ 在 Deployment 标签页 → + → Artifact → 选student-mgmt:war exploded→ Application context 填/(根路径)。
Step 3:关键!点击 Configure → Application server → 选你解压的 Tomcat 根目录(如/opt/tomcat或C:\apache-tomcat-9.0.83)→ OK。
2.3 编写第一个 Servlet 并注册到 web.xml
在src/下新建包com.example.student.servlet,创建类HelloServlet.java:
package com.example.student.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); out.println("<h1>Hello from Servlet!</h1>"); out.println("<p>Current time: " + System.currentTimeMillis() + "</p>"); } }然后编辑web/WEB-INF/web.xml,必须在<web-app>标签下添加:
<servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.example.student.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>参数说明:
<servlet-class>必须是完整类名(含包路径),IDEA 不会自动帮你补全;<url-pattern>是浏览器访问路径,/hello表示输入http://localhost:8080/hello即可触发该 Servlet。注意:web.xml的 XML 声明(<?xml version="1.0" encoding="UTF-8"?>)必须在第一行,且 DTD 声明要匹配 Tomcat 版本(Tomcat 9 对应web-app_4_0.xsd,IDEA 创建时已自动写好)。
2.4 验证:启动 Tomcat 并访问/hello
点击右上角绿色三角形 RunTomcat 9→ 观察控制台输出,直到出现INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [xxx] milliseconds。打开浏览器访问http://localhost:8080/hello。如果看到Hello from Servlet!和时间戳,说明:
✅ Servlet 编译成功(out/production/student-mgmt/com/example/student/servlet/HelloServlet.class已生成)
✅ Tomcat 正确加载了web.xml中的映射
✅ classpath 中WEB-INF/classes被正确扫描
血泪经验:若页面空白或 404,立刻检查
out/artifacts/student_mgmt_war_exploded/WEB-INF/classes/com/example/student/servlet/HelloServlet.class是否存在。不存在?说明编译失败,常见原因是src/目录未被标记为 Sources Root(右键src→ Mark Directory as → Sources Root)。
3. 用 Bootstrap 4 快速搭建响应式学生列表页:不引入 CDN,本地化 CSS/JS 并解决路径玄学
很多人以为 Bootstrap 只是“加个 CSS 文件就行”,但在 JSP 项目里,CSS 路径、JS 加载时机、表单提交拦截全是坑。本节教你把 Bootstrap 4.6.0 完全本地化,避免线上 CDN 失效导致页面白屏,并解决 JSP 中request.getContextPath()与静态资源路径的绑定问题。
3.1 下载 Bootstrap 4.6.0 并解压到 web/css 和 web/js
去官网 https://getbootstrap.com/docs/4.6/ 下载 Bootstrap 4.6.0 的 Compiled CSS and JS(zip 包),解压后:
- 将
bootstrap.min.css复制到web/css/bootstrap.min.css - 将
bootstrap.bundle.min.js(含 Popper)复制到web/js/bootstrap.bundle.min.js - 将
jquery-3.5.1.min.js(Bootstrap 4 依赖 jQuery 3.5+)复制到web/js/jquery-3.5.1.min.js
为什么不用 CDN?因为学校机房/企业内网常禁外网,CDN 加载失败会导致整个页面样式崩溃。本地化后,即使断网也能正常显示。
3.2 在 index.jsp 中正确引用 Bootstrap 并构建学生列表骨架
编辑web/index.jsp,必须使用 JSP Expression Language (EL) 获取上下文路径:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>学生信息管理系统</title> <!-- Bootstrap CSS --> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css"> </head> <body> <div class="container mt-4"> <h1 class="mb-4">学生信息管理系统</h1> <div class="row mb-3"> <div class="col-md-6"> <a href="${pageContext.request.contextPath}/student/list" class="btn btn-primary">查看学生列表</a> </div> </div> <!-- 学生列表表格(占位) --> <div class="table-responsive"> <table class="table table-striped table-hover"> <thead class="thead-dark"> <tr> <th>学号</th> <th>姓名</th> <th>性别</th> <th>专业</th> <th>操作</th> </tr> </thead> <tbody> <!-- 数据将由 student/list Servlet 动态填充 --> <tr> <td colspan="5" class="text-center text-muted">暂无数据,请先添加学生</td> </tr> </tbody> </table> </div> </div> <!-- Bootstrap JS 依赖顺序不能错:jQuery → Popper → Bootstrap --> <script src="${pageContext.request.contextPath}/js/jquery-3.5.1.min.js"></script> <script src="${pageContext.request.contextPath}/js/bootstrap.bundle.min.js"></script> </body> </html>关键逻辑说明:
${pageContext.request.contextPath}返回应用上下文路径(如/student-mgmt),确保href和src路径始终相对于当前应用,而不是服务器根目录。若直接写/css/bootstrap.min.css,Tomcat 会去找http://localhost:8080/css/bootstrap.min.css(404),而非http://localhost:8080/student-mgmt/css/bootstrap.min.css。
3.3 创建 StudentListServlet 并返回 JSON 数据(为后续 AJAX 奠基)
虽然最终用 JSP 渲染,但先实现一个返回 JSON 的 Servlet,验证数据层连通性。在src/com/example/student/servlet/下创建StudentListServlet.java:
package com.example.student.servlet; import com.example.student.model.Student; import com.example.student.dao.StudentDAO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.List; public class StudentListServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("application/json;charset=UTF-8"); PrintWriter out = resp.getWriter(); try { List<Student> students = new StudentDAO().findAll(); // 手动拼 JSON(生产环境用 Jackson/Gson,此处简化) out.print("["); for (int i = 0; i < students.size(); i++) { Student s = students.get(i); out.print(String.format( "{\"id\":%d,\"no\":\"%s\",\"name\":\"%s\",\"gender\":\"%s\",\"major\":\"%s\"}", s.getId(), s.getNo(), s.getName(), s.getGender(), s.getMajor() )); if (i < students.size() - 1) out.print(","); } out.print("]"); } catch (Exception e) { e.printStackTrace(); out.print("[]"); } } }并在web.xml中注册:
<servlet> <servlet-name>StudentListServlet</servlet-name> <servlet-class>com.example.student.servlet.StudentListServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>StudentListServlet</servlet-name> <url-pattern>/student/list</url-pattern> </servlet-mapping>参数说明:
/student/list是 RESTful 风格路径,比/listStudents更易维护;resp.setContentType("application/json;charset=UTF-8")明确告知浏览器返回的是 JSON,避免中文乱码;StudentDAO.findAll()将在下一节实现,此处先留空方法体。
4. 用 MySQL 8.0 配置 JDBC 连接池:避开 SSL 报错、时区错误和密码加密陷阱
MySQL 8.0 默认启用 SSL 连接和严格模式,而传统 JSP 项目常因驱动版本不匹配、URL 参数缺失、密码含特殊字符直接崩溃。本节以 MySQL 8.0.33 为例,给出可落地的mysql-connector-java-8.0.33.jar配置方案,覆盖从安装、建库、JDBC URL 到连接池初始化的全流程。
4.1 MySQL 8.0 安装与基础配置(Linux/macOS/Windows 通用)
安装:
- Windows:去 https://dev.mysql.com/downloads/mysql/ 下载 MySQL Community Server 8.0.x MSI 安装器,安装时勾选 “Add MySQL to PATH” 和 “Configure MySQL as a Service”。
- macOS:
brew install mysql@8.0(Homebrew)或下载 DMG 安装包。 - Linux(Ubuntu):
sudo apt update && sudo apt install mysql-server,安装后运行sudo mysql_secure_installation设置 root 密码。
创建数据库与用户(登录 MySQL 后执行):
-- 创建数据库,指定 UTF8MB4 字符集(支持 emoji) CREATE DATABASE student_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 创建专用用户(避免用 root 连接应用) CREATE USER 'student_app'@'localhost' IDENTIFIED BY 'Stu@2024Pass'; -- 授权(只给必要权限) GRANT SELECT, INSERT, UPDATE, DELETE ON student_db.* TO 'student_app'@'localhost'; -- 刷新权限 FLUSH PRIVILEGES;为什么不用 root?生产环境严禁应用直连 root,一旦 SQL 注入可删库跑路。
student_app用户仅对student_db有 CRUD 权限,符合最小权限原则。
4.2 下载并放置 mysql-connector-java-8.0.33.jar 到 WEB-INF/lib
去 https://dev.mysql.com/downloads/connector/j/ 下载mysql-connector-java-8.0.33.jar(注意:8.0+ 驱动类名已从com.mysql.jdbc.Driver改为com.mysql.cj.jdbc.Driver)。
将 jar 文件复制到web/WEB-INF/lib/目录下。IDEA 会自动将其加入 classpath,无需额外配置。
验证 jar 是否生效:启动 Tomcat 后,查看
catalina.out日志,搜索mysql,应看到类似Loaded JDBC driver com.mysql.cj.jdbc.Driver。
4.3 编写 DatabaseUtil 工具类并配置 JDBC URL
在src/com/example/student/util/下创建DatabaseUtil.java:
package com.example.student.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class DatabaseUtil { private static final String URL = "jdbc:mysql://localhost:3306/student_db?" + "useUnicode=true&characterEncoding=utf8mb4&" + "serverTimezone=Asia/Shanghai&" + "useSSL=false&" + "allowPublicKeyRetrieval=true"; private static final String USERNAME = "student_app"; private static final String PASSWORD = "Stu@2024Pass"; static { try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) { throw new RuntimeException("MySQL Driver not found!", e); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USERNAME, PASSWORD); } }URL 参数详解:
useUnicode=true&characterEncoding=utf8mb4:强制使用 UTF8MB4,避免中文存入乱码(比utf8更彻底)serverTimezone=Asia/Shanghai:必须设置,否则 MySQL 8.0 报错The server time zone value 'XXX' is unrecognizeduseSSL=false:开发环境关闭 SSL(生产环境应启用并配置证书)allowPublicKeyRetrieval=true:MySQL 8.0.28+ 新增参数,解决Public Key Retrieval is not allowed错误PASSWORD中@符号无需 URL 编码,JDBC 驱动会自动处理
4.4 实现 StudentDAO 并完成首次数据库读取
在src/com/example/student/dao/下创建StudentDAO.java:
package com.example.student.dao; import com.example.student.model.Student; import com.example.student.util.DatabaseUtil; import java.sql.*; import java.util.ArrayList; import java.util.List; public class StudentDAO { public List<Student> findAll() { List<Student> list = new ArrayList<>(); String sql = "SELECT id, no, name, gender, major FROM student ORDER BY id DESC"; try (Connection conn = DatabaseUtil.getConnection(); PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery()) { while (rs.next()) { Student s = new Student(); s.setId(rs.getInt("id")); s.setNo(rs.getString("no")); s.setName(rs.getString("name")); s.setGender(rs.getString("gender")); s.setMajor(rs.getString("major")); list.add(s); } } catch (SQLException e) { e.printStackTrace(); } return list; } }避坑重点:
PreparedStatement比Statement安全,防止 SQL 注入;try-with-resources自动关闭连接,避免连接泄漏;ORDER BY id DESC让最新添加的学生排在最前,符合用户直觉。
5. 避坑:JSP+Servlet+MySQL 开发中 5 个高频翻车点及血泪解决方案
这节不讲“应该怎么做”,只列真实发生在我带的学生项目中的 5 个具体翻车现场。每个都按“现象 → 原因 → 解决”还原,拒绝泛泛而谈。
5.1 现象:JSP 页面中文显示为乱码(),但数据库里中文正常
原因:JSP 文件本身编码、HTTP 响应头、HTML meta 标签三者不一致。常见组合是:
- JSP 文件用 ANSI(Windows 默认)保存,但
pageEncoding="UTF-8"声明失效 response.setContentType("text/html;charset=UTF-8")漏写或写在out.println()之后- HTML 中
<meta charset="UTF-8">被注释或位置错误
解决:
- 在 IDEA 中右下角点击文件编码(如
GBK),选Convert to UTF-8→ Save - 在 JSP 第一行添加
<%@ page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" %> - 在
<head>内确保<meta charset="UTF-8">存在且未被注释 - Servlet 中
response.setContentType("text/html;charset=UTF-8")必须在getWriter()之前调用
5.2 现象:点击“新增学生”按钮,页面跳转到http://localhost:8080/student/add,但报 404
原因:Servlet 映射路径与表单action属性不匹配,且未处理 POST 请求。
web.xml中只配置了<url-pattern>/student/add</url-pattern>,但未声明该 Servlet 支持doPost()- JSP 表单
action="/student/add"是绝对路径,但实际应用上下文是/student-mgmt,应为action="${pageContext.request.contextPath}/student/add"
解决:
- 在
AddStudentServlet.java中重写doPost()方法(doGet()通常用于展示表单,doPost()处理提交) web.xml中<servlet-mapping>的<url-pattern>必须与表单action完全一致(包括斜杠)- 表单
method="post",且action使用 EL 表达式${pageContext.request.contextPath}/student/add
5.3 现象:MySQL 插入中文时报错Incorrect string value: '\xE4\xBD\xA0\xE5\xA5\xBD' for column 'name' at row 1
原因:MySQL 数据库、表、字段的字符集均为utf8(MySQL 的utf8实际是utf8mb3,最多 3 字节),而 Java 字符串是 UTF-16,某些中文字符(如 emoji、生僻字)需 4 字节存储。
解决:
- 创建数据库时用
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci(见 4.1 节) - 修改现有表:
ALTER TABLE student CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - JDBC URL 中必须包含
characterEncoding=utf8mb4(见 4.3 节)
5.4 现象:Bootstrap 按钮点击无反应,浏览器控制台报Uncaught ReferenceError: $ is not defined
原因:jQuery 未加载成功,或加载顺序错误。常见于:
<script>标签放在<head>中,而 DOM 尚未渲染完成jquery-3.5.1.min.js路径错误(如写成/js/jquery.min.js但实际是/js/jquery-3.5.1.min.js)- Bootstrap JS 依赖 jQuery,但 jQuery script 标签在 Bootstrap 之后
解决:
- 将所有
<script>标签移到</body>之前(确保 DOM 加载完毕) - 用浏览器开发者工具 Network 标签页,检查
jquery-3.5.1.min.js是否返回 200 - 严格按顺序加载:
jquery→bootstrap.bundle.min.js(bundle 已含 Popper)
5.5 现象:Tomcat 启动后,修改 JSP 文件,刷新页面内容不变
原因:Tomcat 默认开启 JSP 编译缓存,且 IDEA 的热部署(Hot Swap)对 JSP 支持有限。
解决:
- 在
conf/context.xml中添加<Context reloadable="true"/>(开发环境启用热重载) - 在
conf/server.xml的<Host>标签下添加autoDeploy="true" deployOnStartup="true" - 最简单粗暴法:每次修改 JSP 后,在 IDEA 中右键
web/→Reload project,或重启 Tomcat
6. 把学生信息管理系统变成可交付作品:3 个进阶技巧与我的实战习惯
做到前面五章,你已经能跑通增删改查。但一个能交差、能演示、能写进简历的系统,还需要三个关键动作:一是让数据持久化真正可靠(不只是插入成功),二是让界面交互有反馈(不只是跳转),三是让代码结构经得起导师/面试官深挖。下面是我带学生验收时必看的三个点,附可直接抄的代码和配置。
6.1 给 MySQL 添加事务控制:避免“新增学生成功但日志失败”这类数据不一致
StudentDAO当前是单条 SQL 执行,但真实业务中,新增学生可能伴随插入操作日志、更新班级人数统计等。若其中一步失败,必须回滚全部。JDBC 原生支持事务:
// 在 StudentDAO.java 中添加 insertWithTx 方法 public boolean insertWithTx(Student student) { String sql = "INSERT INTO student (no, name, gender, major) VALUES (?, ?, ?, ?)"; try (Connection conn = DatabaseUtil.getConnection()) { conn.setAutoCommit(false); // 关闭自动提交 try (PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { ps.setString(1, student.getNo()); ps.setString(2, student.getName()); ps.setString(3, student.getGender()); ps.setString(4, student.getMajor()); int rows = ps.executeUpdate(); if (rows > 0) { // 获取自增主键 try (ResultSet rs = ps.getGeneratedKeys()) { if (rs.next()) { student.setId(rs.getInt(1)); } } conn.commit(); // 提交事务 return true; } else { conn.rollback(); // 回滚 return false; } } } catch (SQLException e) { e.printStackTrace(); try { if (conn != null) conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } return false; } }为什么值得做:事务是数据一致性的基石。面试官问“你怎么保证转账操作不丢钱”,答案就是这段代码的逻辑。它不依赖 Spring 的
@Transactional,而是直击 JDBC 底层。
6.2 用 Bootstrap Toast 实现操作成功提示:告别“跳转后才看到结果”的割裂感
用户点击“新增”,页面不该直接跳走,而应原地弹出提示。JSP 无法直接调用 Toast(需 JS),但可以传递状态:
<!-- 在 add_success.jsp 中 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <% String message = request.getAttribute("message") != null ? (String) request.getAttribute("message") : "操作成功!"; %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>操作结果</title> <link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container mt-5"> <div class="alert alert-success alert-dismissible fade show" role="alert"> <%= message %> <button type="button" class="close"><?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="10MB"/> </RollingFile> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>然后在StudentDAO.java的insertWithTx方法末尾加:
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class StudentDAO { private static final Logger logger = LogManager.getLogger(StudentDAO.class); public boolean insertWithTx(Student student) { // ... 原有代码 ... if (rows > 0) { logger.info("新增学生成功:学号={}, 姓名={}", student.getNo(), student.getName()); conn.commit(); return true; } // ... } }我的习惯:日志级别设为
INFO,记录所有 CRUD 操作;WARN记录预期外但可恢复的情况(如重复学号);ERROR记录数据库连接失败等致命错误。日志文件自动压缩归档,不撑爆磁盘。这比写“System.out.println("add success")”高到不知哪里去了。
最后说一句:这个系统不是古董,它是你理解 Java Web 的“解剖刀”。当别人还在背 Spring Boot 自动配置原理时,你能手写一个 Servlet 处理表单、用 JDBC 连 MySQL、用 Bootstrap 做响应式页面——这种能力,在面试中比刷一百道八股文都管用。我坚持让学生从零搭这个项目,不是怀旧,是让他们亲手摸到技术的骨头。希望帮到你。
本文还有配套的精品资源,点击获取