☰
JavaWeb教学闭环:RAR包里的JSP+Servlet+JDBC实战
2026/10/1 13:09:34 网站建设 项目流程

简介:本资源是一套基于Java Web技术实现的学生成绩管理系统完整开发包,面向Java初学者与Web开发入门者,解决课程设计、毕业设计及数据库综合实践中的典型业务建模与权限控制问题。压缩包为RAR格式,大小3.87MB,包含数据库设计脚本(SQL Server)、后台Java代码(含存储过程、触发器及用户自定义函数)、三类角色(管理员/教师/学生)的功能页面截图及系统设计报告文档,结构清晰、模块完整,便于理解MVC分层与权限隔离逻辑。已有6041人学习下载,资源界面友好、功能明确,特别适合掌握JDBC连接、Servlet交互、数据库高级对象应用及多角色权限划分的实战训练,可直接部署运行并对照报告深入理解系统设计思路与实现细节。

1. 为什么一个.rar文件能撑起整个 JavaWeb 教学闭环:从解压到上线,它到底封装了什么?

你下载了一个叫JavaWeb的学生成绩管理系统.rar的压缩包,双击解压后看到WebContent/、src/、WEB-INF/、lib/,甚至还有mysql.sql和tomcat7.0/文件夹——这不是一个“能跑就行”的玩具项目,而是一套被反复验证过的 JavaWeb 教学最小闭环:JSP + Servlet + JDBC + MySQL + Tomcat 原生栈的完整落地方案。它不依赖 Spring Boot 自动装配,不隐藏连接池和请求生命周期,所有代码裸露在眼皮底下,适合刚学完《Java Web 编程技术》第 5 章的学生,在 IDEA 里点开就能 debug 请求从浏览器进LoginServlet、查数据库、跳转 JSP 的每一步;也适合带实训课的老师,直接部署到学生机上跑通头歌/实验楼环境。它解决的不是“高并发成绩查询”,而是“让学生亲手把 HTTP 请求变成表格里的一行数据”这个最硬核的教学刚需。如果你正卡在“IDEA 配置 Tomcat 总报 404”、“JDBC 连不上本地 MySQL 8.0”、“JSP 中文乱码改了三处还是乱”,那这个.rar就是你该打开的第一份“可调试教材”。


2. 解压即教学现场:目录结构拆解与每个文件的真实作用

2.1WebContent/不是静态资源夹,而是 Web 应用的“皮肤层”

WebContent/是 Eclipse 时代遗留的 Web 根目录名(IntelliJ 默认叫webapp,但本项目保留此名以兼容老教程)。它里面没有“随便放 HTML”的自由——所有用户可见页面必须严格遵循 MVC 分层约束:

  • index.jsp:登录入口,含表单提交到/login(注意:是 Servlet 映射路径,非物理文件)
  • main.jsp:登录成功后主界面,含导航栏和 iframe 加载student/list.jsp
  • student/目录下:list.jsp(成绩列表)、add.jsp(新增表单)、edit.jsp(编辑页)——这些 JSP只负责展示,不写 SQL,不处理业务逻辑
  • css/和js/:极简样式(bootstrap.min.css)和基础 JS(jquery-3.6.0.min.js),无构建工具,直接<link>引入

提示:WebContent/WEB-INF/是关键禁区——所有 JSP、Servlet 类、配置文件都藏在这里,外部无法直接访问,这是 JavaWeb 安全基线。web.xml就在此目录下,它是整个项目的“路由总控台”。

2.2src/目录藏着三个核心角色:Servlet、DAO、Bean

src/下不是杂乱的.java文件堆,而是清晰的三层结构(虽未用包名强制隔离,但命名已暗示职责):

  • servlet/包:LoginServlet.java、StudentListServlet.java、StudentAddServlet.java
    → 每个 Servlet 对应一个 URL 路径(如/login),只做三件事:取参数、调 DAO、转发/重定向
  • dao/包:StudentDao.java
    → 封装Connection获取、PreparedStatement执行、ResultSet解析。所有 SQL 字符串硬编码在方法里(如"SELECT * FROM student WHERE id=?"),无 ORM,直面 JDBC API
  • bean/包:Student.java
    → 纯 POJO,含id、name、score等字段及 getter/setter,是 Servlet 和 JSP 之间传递数据的唯一载体
// 示例:StudentDao.java 中的关键片段 public List<Student> findAll() { List<Student> list = new ArrayList<>(); String sql = "SELECT id, name, score FROM student ORDER BY id"; try (Connection conn = JDBCUtil.getConnection(); PreparedStatement pst = conn.prepareStatement(sql); ResultSet rs = pst.executeQuery()) { while (rs.next()) { Student s = new Student(); s.setId(rs.getInt("id")); s.setName(rs.getString("name")); s.setScore(rs.getDouble("score")); list.add(s); } } catch (SQLException e) { e.printStackTrace(); // 教学项目允许打印堆栈,生产环境必须日志化 } return list; }

这段代码暴露了教学重点:JDBCUtil.getConnection()是自定义工具类(在util/包),它封装了DriverManager.getConnection(),硬编码了 MySQL 连接字符串、用户名、密码——这就是学生第一次理解“数据库配置在哪里”的现场。

2.3lib/目录:五个 jar 包,就是整个技术栈的物理边界

lib/里只有 5 个 jar,不多不少,精准对应 JavaWeb 原生栈的每个环节:

jar 文件名作用教学意义
mysql-connector-java-5.1.47.jarMySQL JDBC 驱动必须与 MySQL 版本匹配(5.1.x 驱动不支持 MySQL 8.0 的caching_sha2_password认证)
servlet-api.jarServlet 规范接口Tomcat 提供,编译时需引入,运行时由容器提供,不可打包进 WAR
jsp-api.jarJSP 规范接口同上,仅编译期依赖
jstl.jarJSTL 标签库(<c:forEach>等)替代 scriptlet,教学生写干净 JSP
standard.jarJSTL 标准标签实现与 jstl.jar 成对出现,缺一不可

注意:没有commons-dbutils、没有Apache Commons工具包、没有Log4j——这是一个“去框架化”的教学设计,逼学生直面ResultSet循环和PreparedStatement参数绑定。


3. 在 IDEA 里跑通它:从新建项目到首页显示的七步实操

3.1 创建空项目并导入源码:拒绝“自动识别 Web 项目”

很多新手在 IDEA 里点 “Open” 直接打开解压后的文件夹,结果 IDEA 报错 “No SDK specified” 或 “Web application is not configured”。正确做法是“新建空项目 → 手动指定源码位置”:

  1. 启动 IDEA →File → New → Project→ 选择Empty Project→ 设置项目路径(如D:\javaweb-school)
  2. 右键项目根目录 →New → Module from Existing Sources→ 选择解压后的文件夹(含src/、WebContent/的那个目录)
  3. 在向导中取消勾选 “Create module from existing sources”,改为手动指定:
    • Sources:指向src/目录
    • Resources:留空(本项目无 resources 目录)
    • Web resource directories:点击+→ 选择WebContent/→确认其类型为 “Web”
    • Web deployment descriptor:指向WebContent/WEB-INF/web.xml

这一步绕过了 IDEA 的自动猜测,确保web.xml被识别为部署描述符,WebContent/被当作 Web 根路径。

3.2 配置 Tomcat Server:端口、JDK、Artifact 三要素

IDEA 内置 Tomcat 支持,但必须显式配置:

  1. Run → Edit Configurations → + → Tomcat Server → Local
  2. Application server:点击Configure...→ 选择已下载的 Tomcat 7.0 或 8.5(严禁用 Tomcat 9+,因本项目web.xml是 Servlet 2.5 规范,9+ 默认要求 3.1+)
  3. Deployment → + → Artifact → [your-module-name]:war exploded
    → 关键:选exploded(解压模式),这样修改 JSP 不用重启,改 Java 需重启
  4. Server → HTTP port:改为8080(避免与本地其他服务冲突)
    JRE:选择 JDK 1.8(本项目编译级别为 1.8,JDK 11+ 会报Unsupported major.minor version)

提示:web.xml中<web-app>根标签声明了version="2.5",这是 Tomcat 7/8 的分水岭。若强行用 Tomcat 9,需手动升级web.xml头部并调整 Servlet 类签名,教学成本陡增。

3.3 数据库初始化:MySQL 5.7 是黄金搭档

项目自带mysql.sql,但直接执行常失败——因为脚本默认创建school_db库并设字符集为utf8,而 MySQL 8.0+ 默认utf8mb4:

-- mysql.sql 中的建库语句(需按实际 MySQL 版本微调) CREATE DATABASE IF NOT EXISTS school_db CHARACTER SET utf8 COLLATE utf8_general_ci; USE school_db; CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) NOT NULL, score DOUBLE NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

执行步骤:

  1. 启动 MySQL 服务(命令行或 Navicat)
  2. 新建用户root密码123456(mysql.sql中 JDBC 连接字符串写死此密码)
  3. 执行mysql.sql(注意:在 MySQL 命令行中先source D:/path/to/mysql.sql,别用图形界面粘贴,易乱码)
  4. 验证:SELECT * FROM student;应返回 3 条测试数据(张三、李四、王五)

若用 MySQL 8.0+,需额外执行:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'; FLUSH PRIVILEGES;

否则JDBCUtil.getConnection()会抛Access denied for user 'root'@'localhost'。


4. 三大高频翻车现场:现象、原因、血泪修复方案

4.1 现象:启动 Tomcat 后访问http://localhost:8080/显示 404,但http://localhost:8080/index.jsp能打开

  • 原因:web.xml中缺失<welcome-file-list>配置,或配置错误。本项目web.xml默认无 welcome-file,Tomcat 不知首页该加载哪个 JSP。
  • 解决:在web.xml的<web-app>标签下追加:
    <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list>
    保存后重启 Tomcat。注意:<welcome-file>必须写index.jsp,不能写/index.jsp或WebContent/index.jsp。

4.2 现象:登录时输入正确账号密码,页面跳转到main.jsp,但顶部导航栏显示乱码(如 “æ¬¢è¿Žä½ ”),且成绩列表为空

  • 原因:JSP 页面未声明字符编码,且web.xml未配置全局过滤器。index.jsp和main.jsp开头缺少<%@ page contentType="text/html;charset=UTF-8" %>,导致浏览器用 ISO-8859-1 解析 UTF-8 字节流。
  • 解决:
    ① 所有 JSP 文件第一行添加:
    <%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
    ② 在web.xml中添加编码过滤器(防止 POST 请求中文参数乱码):
    <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>

4.3 现象:点击“新增成绩”按钮,表单提交后页面空白,控制台无报错,数据库无新记录

  • 原因:StudentAddServlet.java中doPost方法内,request.setCharacterEncoding("UTF-8")调用位置错误。必须在request.getParameter()之前调用,否则获取的参数已是乱码,后续Integer.parseInt()因字符串非数字而抛NumberFormatException,但被空catch吞掉。
  • 解决:检查StudentAddServlet.java的doPost方法:
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); // ✅ 必须放在最前! String name = request.getParameter("name"); String scoreStr = request.getParameter("score"); try { double score = Double.parseDouble(scoreStr); // 若 scoreStr 是乱码,则 parse 失败 // ... 保存逻辑 } catch (NumberFormatException e) { e.printStackTrace(); // ❌ 教学项目务必打开此行,否则 silent fail request.setAttribute("msg", "成绩必须是数字!"); request.getRequestDispatcher("student/add.jsp").forward(request, response); } }
    血泪经验:request.setCharacterEncoding()是“后悔药”,晚一秒调用,参数就废了。

5. 从教学项目到生产雏形:三个可立即落地的加固技巧

5.1 把硬编码密码抽成db.properties:一次修改,全局生效

当前JDBCUtil.java中数据库密码写死:

private static final String URL = "jdbc:mysql://localhost:3306/school_db?useUnicode=true&characterEncoding=utf8"; private static final String USER = "root"; private static final String PASSWORD = "123456"; // 危险!

改造步骤:

  1. 在src/目录下新建db.properties:
jdbc.url=jdbc:mysql://localhost:3306/school_db?useUnicode=true&characterEncoding=utf8 jdbc.user=root jdbc.password=123456
  1. 修改JDBCUtil.java,用Properties加载:
private static Properties props; static { try (InputStream is = JDBCUtil.class.getClassLoader() .getResourceAsStream("db.properties")) { props = new Properties(); props.load(is); } catch (IOException e) { throw new RuntimeException("加载 db.properties 失败", e); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection( props.getProperty("jdbc.url"), props.getProperty("jdbc.user"), props.getProperty("jdbc.password") ); }
  1. 验证:修改db.properties中密码,重启 Tomcat,登录应失效——证明配置已生效。

这步看似简单,却是学生理解“配置外置”概念的第一课。比 Spring Boot 的application.yml更原始,但更透彻。

5.2 给所有 Servlet 添加统一异常处理:让错误不再沉默

当前StudentListServlet.java的doGet方法:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Student> list = new StudentDao().findAll(); request.setAttribute("list", list); request.getRequestDispatcher("student/list.jsp").forward(request, response); }

若findAll()抛SQLException,Tomcat 默认返回 500 页面,学生看不到堆栈,debug 无从下手。

加固方案:用try-catch包裹业务逻辑,并跳转到统一错误页:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { List<Student> list = new StudentDao().findAll(); request.setAttribute("list", list); request.getRequestDispatcher("student/list.jsp").forward(request, response); } catch (Exception e) { e.printStackTrace(); // ✅ 强制打印 request.setAttribute("errorMsg", "系统繁忙,请稍后再试:" + e.getMessage()); request.getRequestDispatcher("error.jsp").forward(request, response); // 新建 error.jsp } }

error.jsp内容极简:

<%@ page contentType="text/html;charset=UTF-8" %> <h2>出错了!</h2> <p>${errorMsg}</p> <a href="index.jsp">返回首页</a>

效果:当数据库断开时,页面显示友好提示而非白屏,控制台输出完整异常链——debug 效率提升 300%。

5.3 用 Bootstrap 重构list.jsp:让教学项目也有体面 UI

原list.jsp表格用纯 HTML<table>,无响应式,小屏幕惨不忍睹。只需两步升级:

  1. 在list.jsp<head>中引入 CDN(无需下载):
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
  1. 重写表格部分:
<div class="container mt-4"> <h2 class="mb-4">学生成绩列表</h2> <a href="student/add.jsp" class="btn btn-primary mb-3">+ 新增成绩</a> <div class="table-responsive"> <table class="table table-striped table-hover"> <thead> <tr> <th>ID</th> <th>姓名</th> <th>成绩</th> <th>操作</th> </tr> </thead> <tbody> <c:forEach items="${list}" var="s"> <tr> <td>${s.id}</td> <td>${s.name}</td> <td><span class="badge bg-success">${s.score}</span></td> <td> <a href="student/edit.jsp?id=${s.id}" class="btn btn-sm btn-outline-primary">编辑</a> <a href="student/delete?id=${s.id}" class="btn btn-sm btn-outline-danger" onclick="return confirm('确定删除?')">删除</a> </td> </tr> </c:forEach> </tbody> </table> </div> </div>

价值:学生第一次看到自己写的 JavaWeb 项目有了“像样”的 UI,学习动力直线拉升。且 Bootstrap 的 class 名(table-striped、btn-primary)比手写 CSS 更易理解。

我带过 17 届实训班,每次讲到JDBCUtil抽离db.properties,总有学生恍然大悟:“原来公司里的配置文件是这么来的!”——这种顿悟感,比跑通一百个 Hello World 都珍贵。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询