首页 / 资讯中心 / 文章详情

JavaWeb学生成绩管理系统:JSP+Servlet+JDBC实战源码

JavaWeb学生成绩管理系统:JSP+Servlet+JDBC实战源码 ★ FEATURED ARTICLE
简介本资源是一套完整可用的JavaWeb学生成绩管理系统项目源码专为计算机类专业学生设计适用于课程设计、期末大作业及JavaWeb实战能力提升。系统功能覆盖学生、教师、管理员三类角色的登录认证、成绩录入、查询统计与报表导出等核心业务代码结构清晰、注释规范经导师指导并获98分高分评价。压缩包共337个文件含84个Java源文件、84个编译后Class文件、36个JSP页面、61个JavaScript脚本及28个CSS样式文件辅以SQL建表语句、Jar依赖库与基础静态资源整体3.32MB开箱即用。已有5296人学习下载配套数据库脚本与完整目录层级便于快速部署调试内容预览显示包含ScoreDaoImpl、StudentDaoImpl等典型DAO实现类及ServletUploadFile等关键控制器体现MVC分层设计思想与常见Web开发实践模式。1. 这不是又一个“Hello World”式 JavaWeb 项目98 分高分课程设计源码真能跑通增删改查、文件上传下载、角色权限分离的学生成绩管理系统你手头正赶着《Java Web 应用开发》期末大作业Deadline 前 72 小时导师刚在群里甩出一句“系统要有真实业务逻辑不能只做登录跳转”。你点开网上搜到的第 17 个“学生成绩管理系统源码”解压后发现——web.xml里连 servlet-mapping 都没配全StudentDaoImpl.class编译报错数据库脚本缺字段注释更别说ServletUploadFile.class根本没写文件保存路径校验……这种“半成品”不是帮你过关是给你埋雷。而眼前这份基于 JavaWeb 的学生成绩管理系统是真实通过高校计算机专业课程设计评审、获 98 分满分 100的完整项目源码包。它不是 Demo是带生产级结构的实战工程含完整 MySQL 数据库建表语句与初始化数据、6 个核心 DAO 实现类StudentDaoImpl,ScoreDaoImpl,CourseDaoImpl,TeacherDaoImpl,UserDaoImpl,CourseDaoImpl、4 个功能明确的 ServletServletUploadFile,ServletDownloadFile,ServletaddTeacher,ServletDownloadFile以及清晰的角色权限控制学生查分、教师录分、管理员维护课程/教师/学生信息。它专为两类人准备一是正在硬啃 JSPServletJDBC 技术栈、需要可运行、可调试、可答辩的课程设计学生二是想从零复现一个“非玩具级” JavaWeb 项目的自学者——这里没有 Spring Boot 自动装配的黑匣子所有 JDBC 连接、SQL 拼接、请求参数解析、文件流处理都裸露在代码里你能看清每一行request.getParameter(score)是怎么变成数据库里一条INSERT INTO score的。这不是拿来即用的“后悔药”而是你亲手搭起第一个 Web 系统的脚手架。2. 从零部署IDEA Tomcat 9 MySQL 8.0 环境搭建与项目导入全流程2.1 环境版本选择依据为什么必须是 Tomcat 9 而非 10MySQL 8.0 的驱动兼容性陷阱在哪很多同学卡在第一步IDEA 导入项目后启动 Tomcat 报java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet。这不是你配置错了是版本踩坑。本项目基于 Servlet 4.0 规范由 Java EE 8 定义而 Tomcat 10 已全面迁移到 Jakarta EE 9所有javax.*包名被替换为jakarta.*。但本项目源码中所有 import 仍是import javax.servlet.http.*强行用 Tomcat 10 会导致编译期找不到类。必须用 Tomcat 9.0.x推荐 9.0.85它同时支持 Servlet 4.0 和javax.*命名空间。MySQL 方面项目使用mysql-connector-java-5.1.47.jar经典 JDBC 驱动它对 MySQL 5.7/8.0 兼容性极好但有一个关键限制不支持 MySQL 8.0 默认的caching_sha2_password认证插件。若你本地 MySQL 8.0 是全新安装默认认证方式就是这个直接导致DriverManager.getConnection()抛Access denied for user异常。解决方案不是降级 MySQL而是修改用户认证方式——这是每个用 MySQL 8.0 跑老项目的人必过的一关。2.2 IDEA 中导入项目并配置 Tomcat 的实操步骤附关键截图逻辑说明提示本项目是标准的 Dynamic Web Project 结构非 Maven 项目因此无需pom.xml解析直接以“Existing Sources”方式导入。解压与目录确认将下载的源码包解压到无中文、无空格路径如D:\javaweb-score-system。确认根目录下存在src/Java 源码、WebContent/Web 资源含WEB-INF/web.xml、lib/含mysql-connector-java-5.1.47.jar和servlet-api.jar。IDEA 导入打开 IDEA →File→New→Project from Existing Sources...→ 选择解压后的根目录 → 选择Import project from external model→ 选None→ 点击Next。在后续向导中务必取消勾选Create project from template直接点击Finish。配置 Project SDK 与 Language LevelFile→Project Structure→Project→Project SDK选择已安装的 JDK 1.8本项目编译级别为 1.8→Project language level选8 - Lambdas, type annotations etc.。添加 Tomcat ServerRun→Edit Configurations...→→Tomcat Server→Local。在Server选项卡中Application server点击Configure...→ 选择你的 Tomcat 9 安装目录如D:\apache-tomcat-9.0.85。在Deployment选项卡中点击→Artifact→ 选择javaweb-score-system:war explodedIDEA 会自动识别WebContent为 Web Root。验证 web.xml 配置打开WebContent\WEB-INF\web.xml检查servlet和servlet-mapping是否完整。例如ServletUploadFile的配置应为servlet servlet-nameupload/servlet-name servlet-classcom.servlet.ServletUploadFile/servlet-class /servlet servlet-mapping servlet-nameupload/servlet-name url-pattern/upload/url-pattern /servlet-mapping若缺失需手动补全否则访问/upload会 404。2.3 MySQL 数据库初始化建库、建表、授权、解决caching_sha2_password认证问题项目数据库脚本位于sql/目录或doc/目录下的.sql文件通常命名为score_system.sql。执行前需先创建数据库并处理认证问题。创建数据库用 MySQL 客户端如 MySQL Workbench 或命令行执行CREATE DATABASE IF NOT EXISTS score_system CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;使用utf8mb4是为了完整支持 emoji 和生僻汉字避免插入学生姓名时报错。解决caching_sha2_password认证关键执行以下 SQL 修改 root 用户或你项目连接用的用户的认证方式-- 登录 MySQL 后执行假设用户名为 root密码为 123456 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 123456; FLUSH PRIVILEGES;逻辑说明mysql_native_password是 MySQL 5.7 及之前默认的认证插件mysql-connector-java-5.1.47.jar仅支持此插件。FLUSH PRIVILEGES是强制刷新权限缓存否则修改不生效。导入数据表结构与初始数据在 MySQL 客户端中选中score_system数据库执行score_system.sql脚本。该脚本应包含student,teacher,course,score,user等核心表的CREATE TABLE语句及INSERT INTO初始化数据如管理员账号admin/admin。验证数据库连接打开src/com/util/DBUtil.java或类似名称的数据库工具类检查url,username,password是否与你本地 MySQL 配置一致。典型配置为private static final String URL jdbc:mysql://localhost:3306/score_system?useUnicodetruecharacterEncodingutf8; private static final String USERNAME root; private static final String PASSWORD 123456;注意?useUnicodetruecharacterEncodingutf8参数确保中文不乱码。3. 核心功能模块拆解DAO 层实现原理与 Servlet 业务逻辑链路分析3.1ScoreDaoImpl与StudentDaoImplJDBC 手写 CRUD 的典型范式与事务边界本项目未使用 MyBatis 或 Hibernate所有数据库操作均基于原生 JDBC。理解ScoreDaoImpl成绩管理和StudentDaoImpl学生管理的实现是掌握整个项目数据层的关键。ScoreDaoImpl的核心方法addScore(Score score)展示了标准 JDBC 流程public boolean addScore(Score score) { String sql INSERT INTO score (student_id, course_id, score_value, term) VALUES (?, ?, ?, ?); Connection conn null; PreparedStatement pstmt null; try { conn DBUtil.getConnection(); // 1. 获取连接 pstmt conn.prepareStatement(sql); // 2. 预编译SQL防SQL注入 pstmt.setString(1, score.getStudentId()); // 3. 设置参数 pstmt.setString(2, score.getCourseId()); pstmt.setDouble(3, score.getScoreValue()); pstmt.setString(4, score.getTerm()); return pstmt.executeUpdate() 0; // 4. 执行返回影响行数 } catch (SQLException e) { e.printStackTrace(); return false; } finally { DBUtil.close(null, pstmt, conn); // 5. 关闭资源顺序ResultSet-Statement-Connection } }参数说明与逻辑说明PreparedStatement的setXxx(index, value)方法按?占位符顺序设置参数index从 1 开始。executeUpdate()用于INSERT/UPDATE/DELETE返回受影响行数。DBUtil.close()是封装的资源关闭方法必须按 ResultSet → Statement → Connection 顺序关闭否则可能引发连接泄漏。Score实体类的getXXX()方法与数据库字段一一映射这是典型的 POJOPlain Old Java Object模式。StudentDaoImpl的findStudentById(String id)则展示了查询流程public Student findStudentById(String id) { String sql SELECT * FROM student WHERE student_id ?; Connection conn null; PreparedStatement pstmt null; ResultSet rs null; try { conn DBUtil.getConnection(); pstmt conn.prepareStatement(sql); pstmt.setString(1, id); rs pstmt.executeQuery(); // 1. executeQuery() 用于 SELECT if (rs.next()) { // 2. rs.next() 移动到第一行返回 true 表示有数据 Student student new Student(); student.setStudentId(rs.getString(student_id)); student.setName(rs.getString(name)); student.setGender(rs.getString(gender)); student.setClassId(rs.getString(class_id)); return student; } return null; } catch (SQLException e) { e.printStackTrace(); return null; } finally { DBUtil.close(rs, pstmt, conn); // 3. ResultSet 必须在此处关闭 } }关键细节ResultSet的next()方法是游标移动的核心if (rs.next())是判断是否有结果的标准写法。rs.getString(column_name)通过列名获取值比rs.getString(1)更安全列顺序变化不影响代码。3.2ServletUploadFile与ServletDownloadFile文件上传下载的底层实现与安全校验文件操作是本项目区别于“Hello World”的重要标志。ServletUploadFile处理学生/教师头像上传ServletDownloadFile提供成绩报表下载。ServletUploadFile的核心在于request.getInputStream()和文件路径处理protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 获取上传的文件名和内容 Part filePart request.getPart(file); // 获取名为 file 的表单字段 String fileName Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // 获取原始文件名 InputStream fileContent filePart.getInputStream(); // 2. 安全校验检查文件类型白名单 String contentType filePart.getContentType(); if (!image/jpeg.equals(contentType) !image/png.equals(contentType)) { request.setAttribute(message, 只允许上传 JPG 或 PNG 格式图片); request.getRequestDispatcher(upload.jsp).forward(request, response); return; } // 3. 构建安全保存路径防止路径遍历攻击 String uploadPath request.getServletContext().getRealPath() File.separator uploads; File uploadDir new File(uploadPath); if (!uploadDir.exists()) uploadDir.mkdir(); // 创建 uploads 目录 String filePath uploadPath File.separator fileName; // 4. 写入文件 Files.copy(fileContent, Paths.get(filePath), StandardCopyOption.REPLACE_EXISTING); request.setAttribute(message, 文件上传成功); request.getRequestDispatcher(upload.jsp).forward(request, response); }逻辑说明与参数说明request.getPart(file)对应 HTML 表单中input typefile namefile的name属性。Paths.get(filePart.getSubmittedFileName()).getFileName()是安全提取文件名的标准做法避免../../../etc/passwd这类路径遍历。contentType校验是前端校验的“后悔药”必须后端二次验证。getServletContext().getRealPath()获取 Web 应用在服务器上的绝对路径uploads目录需手动在WebContent/下创建。ServletDownloadFile的核心是设置响应头和输出流protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String fileName request.getParameter(filename); // 从URL参数获取文件名如 /download?filenamereport.pdf String downloadPath request.getServletContext().getRealPath() File.separator downloads File.separator fileName; File file new File(downloadPath); if (file.exists()) { // 1. 设置响应头告知浏览器这是附件且指定文件名 response.setContentType(application/octet-stream); response.setHeader(Content-Disposition, attachment; filename\ fileName \); response.setContentLength((int) file.length()); // 2. 将文件字节流写入响应输出流 FileInputStream in new FileInputStream(file); OutputStream out response.getOutputStream(); byte[] buffer new byte[4096]; int length; while ((length in.read(buffer)) 0) { out.write(buffer, 0, length); } in.close(); out.close(); } else { response.sendError(HttpServletResponse.SC_NOT_FOUND, 文件不存在); } }关键点Content-Disposition: attachment强制浏览器下载而非在页面中打开。filename参数必须经过严格校验如正则匹配^[a-zA-Z0-9._-]$防止恶意文件名注入。3.3ServletaddTeacher与权限控制如何在 Servlet 中实现简单的角色路由ServletaddTeacher并非仅添加教师它体现了项目的基础权限思想只有管理员user_roleadmin才能访问。其doPost方法开头通常有如下校验// 从Session中获取当前登录用户 User user (User) request.getSession().getAttribute(user); if (user null || !admin.equals(user.getRole())) { request.setAttribute(message, 权限不足无法执行此操作); request.getRequestDispatcher(error.jsp).forward(request, response); return; } // ... 后续执行添加教师的业务逻辑逻辑说明request.getSession().getAttribute(user)是登录成功后存入 Session 的用户对象。user.getRole()返回字符串admin或teacher或student。这种基于 Session 的简单角色判断是 JavaWeb 基础项目最常用的权限控制方式虽不如 Shiro/Spring Security 严谨但足够支撑课程设计需求。4. 避坑指南90% 的同学在部署和调试时踩过的 5 个具体坑4.1 现象启动 Tomcat 后访问http://localhost:8080/login.jsp显示 404原因IDEA 未正确部署WebContent目录为 Web Root或web.xml中 servlet-mapping 的url-pattern与实际访问路径不匹配。例如web.xml中配置url-pattern/login/url-pattern但你直接访问了/login.jsp。解决在 IDEA 的Project Structure→Modules→Web选项卡中确认Web resource directories指向WebContent且Web.xml路径正确。检查web.xml中所有servlet-mapping的url-pattern确保访问路径与之完全一致如配置为/login则应访问http://localhost:8080/login而非.jsp文件名。4.2 现象登录时输入正确账号密码却始终跳转到error.jsp或空白页原因UserDaoImpl.login(String username, String password)方法中SQL 查询语句错误或数据库连接失败导致rs.next()返回falselogin()方法返回null后续if (user ! null)判断失败。常见错误是 SQL 字段名写错如user_name写成username或password字段在数据库中是加密存储MD5但代码中直接比较明文。解决在UserDaoImpl.login()方法内rs.next()前加日志System.out.println(SQL: sql , username: username);并在数据库中手动执行该 SQL 验证。检查score_system.sql中user表结构确认字段名与代码中rs.getString(xxx)一致。若密码是 MD5 加密代码中需用DigestUtils.md5Hex(password)需引入 commons-codec再比较。4.3 现象ServletUploadFile上传图片后在 JSP 页面显示为破损图标原因文件保存路径错误或 JSP 中img src...的路径是相对路径未指向WebContent/uploads/目录。例如代码中保存到WebContent/uploads/1.jpg但 JSP 中写img srcuploads/1.jpg而该 JSP 本身在WebContent/下路径正确但如果 JSP 在WebContent/admin/下则应写img src../uploads/1.jpg。解决在ServletUploadFile中打印filePath的绝对路径System.out.println(Saved to: filePath);确认文件确实生成。在浏览器中直接访问http://localhost:8080/uploads/1.jpg若能显示图片则 JSP 中的src路径需据此调整。最佳实践是在web.xml中配置一个context-param定义upload.dir并在 JSP 中用${pageContext.request.contextPath}/uploads/。4.4 现象ScoreDaoImpl.addScore()执行后数据库score表无新增记录也无任何异常日志原因DBUtil.getConnection()返回的Connection对象未设置autoCommitfalse且addScore()方法中未显式调用conn.commit()。虽然单条 INSERT 通常自动提交但若 DAO 方法被其他事务包裹如未来扩展或数据库连接池配置了autoCommitfalse则必须手动提交。本项目虽未显式开启事务但DBUtil类中getConnection()方法可能遗漏了conn.setAutoCommit(true)。解决打开DBUtil.java找到getConnection()方法在return conn;前添加conn.setAutoCommit(true);。或者在addScore()方法的try块末尾添加conn.commit();需捕获SQLException。4.5 现象在 IDEA 中修改了StudentDaoImpl.java重新部署后页面行为未改变原因IDEA 的Build→Rebuild Project未触发或 Tomcat 的On Update action设置为Update classes and resources但未勾选Update resources导致 JSP/HTML/CSS 等静态资源未更新更常见的是target/classes/或out/production/目录下的.class文件未被 Tomcat 热加载需重启。解决Build→Rebuild Project强制重新编译所有 Java 文件。在Run→Edit Configurations...→Tomcat Server→On Update action中勾选Update classes and resources和Update resources。若仍无效点击 Tomcat 控制台的Redeploy按钮循环箭头图标或直接Stop后Start。5. 进阶技巧三步完成从“能跑”到“能讲”的答辩级优化5.1 第一步为所有 Servlet 添加日志输出让答辩时的“过程演示”有据可依答辩时老师常问“你如何确认数据真的插入了数据库” 光说“我看了数据库”不够有力。在每个关键 Servlet 的doGet/doPost开头和结尾添加System.out.println()日志形成清晰的执行链路。这不是低级调试而是构建可追溯的证据链。以ServletaddTeacher为例在doPost开头加入System.out.println([ServletaddTeacher] 开始处理添加教师请求参数name name , gender gender , title title);在teacherDao.addTeacher(teacher)调用后加入boolean result teacherDao.addTeacher(teacher); System.out.println([ServletaddTeacher] 调用 TeacherDaoImpl.addTeacher()返回结果 result); if (result) { System.out.println([ServletaddTeacher] 教师添加成功ID teacher.getId()); } else { System.out.println([ServletaddTeacher] 教师添加失败请检查数据库连接或约束条件); }价值点答辩时你可以当着老师面启动 Tomcat打开控制台IDEA 下方Run标签页然后在浏览器操作添加教师。老师立刻能看到控制台滚动的日志从“开始处理”到“添加成功”每一步都实时可见、可截图。这比口头描述“我写了 DAO”有力十倍。日志中包含具体参数值name,gender证明你理解了请求参数的获取与传递。5.2 第二步用web.xml的welcome-file-list和error-page提升系统健壮性与专业感一个“高分项目”必须有基础的用户体验兜底。web.xml不只是配置 Servlet更是定义应用入口和错误处理的契约。设置欢迎页在web.xml的web-app标签下添加welcome-file-list welcome-filelogin.jsp/welcome-file /welcome-file-list这样访问http://localhost:8080/会自动跳转到login.jsp而不是显示 Tomcat 默认的 404 页面给老师留下“系统有入口”的第一印象。配置全局错误页添加error-page error-code404/error-code location/error/404.jsp/location /error-page error-page error-code500/error-code location/error/500.jsp/location /error-page并在WebContent/error/下创建404.jsp和500.jsp内容可以是友好的提示如“页面走丢了请返回首页”。这表明你考虑了异常场景不是只关注 happy path。5.3 第三步用JSTL替换 JSP 中的% %脚本让代码更易读、更符合现代 Web 开发规范项目源码中大量使用% %嵌入 Java 代码如% for(int i0; ilist.size(); i) { %。这在课程设计中可接受但答辩时若被问及“如何提升代码可维护性”这就是绝佳的加分点。引入 JSTL将jstl-1.2.jar和standard-1.1.2.jar或jstl-api-1.2.jar和jstl-impl-1.2.jar放入WebContent/WEB-INF/lib/。在 JSP 顶部声明% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %替换循环将原始 JSP 中的% ListStudent students (ListStudent) request.getAttribute(students); % % for(Student s : students) { % tr td% s.getStudentId() %/td td% s.getName() %/td /tr % } %替换为c:forEach items${students} vars tr td${s.studentId}/td td${s.name}/td /tr /c:forEach参数说明items${students}绑定 request 属性vars定义循环变量${s.studentId}是 EL 表达式自动调用getStudentId()。这消除了% %的混乱使 JSP 更专注于展示逻辑。从那以后我每次准备课程设计答辩都强制走一遍这三步加日志、配 welcome/error、换 JSTL。它不增加核心功能但能让老师一眼看到你的工程素养——你知道代码不仅要能跑还要能被看见、能被理解、能被信任。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站