ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java+MySQL+JSP学生成绩管理系统源码解析与实战避坑指南

Java+MySQL+JSP学生成绩管理系统源码解析与实战避坑指南 简介这份资源是面向Java Web初学者与课程设计者的网上学生成绩管理系统完整源码包采用Java、MySQL与JSP技术栈实现覆盖用户登录、成绩录入、查询、修改与删除等核心业务适合作为毕业设计、课程实训或Web开发入门案例。压缩包共301个文件约20.31MB包含13个Java源文件与对应class文件、9个JSP页面、5个SQL脚本以及scss、css、jpg、png等前端样式与图片资源另有jar依赖、xml配置和论文文档结构上分为源码目录、数据库脚本与说明资料三部分。目前已有1166人学习下载。读者可从中获得一套可直接运行的Java Web项目参考理解Servlet与JDBC如何协同完成数据库增删改查掌握JSP页面与JavaBean分离视图与控制层的设计思路并借助论文文档梳理系统架构与实现流程适合边调试边对照学习。1. 从一份 JSP 成绩管理源码说起它到底能解决什么很多同学做毕业设计时第一反应是去搜「基于 JavaMySQLJSP 网上学生成绩管理系统 源码」下载下来发现能跑但改不动、讲不清、答辩一问就露馅。这份源码本质上是一个典型的 Java Web 三层架构小系统JSP 负责页面渲染Servlet 或 JavaBean 处理业务逻辑MySQL 存成绩数据。它解决的核心问题是——把学生、课程、成绩三张表的关系用增删改查串起来让教务人员能录入分数、学生能查分、老师能统计排名。适合谁适合正在做课程设计或毕业论文的本科生也适合刚学完 Java 基础、想找一个完整项目练手的初级开发者。但要注意网上流传的这类源码质量参差不齐有的连 SQL 注入都没防直接拿来当论文项目答辩时被问到「你的权限怎么控制的」就卡住了。所以这篇不是教你复制粘贴而是拆开讲清楚这套东西怎么跑起来、哪些地方必须自己改、坑埋在哪。2. 把源码跑起来之前环境选型和数据库设计先定死2.1 JDK、Tomcat、MySQL 的版本搭配别乱选我见过太多人卡在第一步——环境装完项目一部署就报 500。血泪经验是JSP 项目对版本很敏感尤其是 JDK 和 Tomcat 的匹配。如果你拿到的源码是几年前写的大概率用的是 JDK 8 Tomcat 8 或 9。别上来就装 JDK 17 配 Tomcat 10Tomcat 10 把 javax.servlet 包名改成了 jakarta.servlet老代码直接编译不过。具体操作先看源码里 import 的是 javax.servlet 还是 jakarta.servlet。如果是 javax就老老实实装 JDK 8 或 11Tomcat 选 9.0.x。MySQL 用 5.7 或 8.0 都行但 8.0 的驱动类名和连接串参数有变化下面会讲。# 检查当前 Java 版本确认是 1.8 还是 11 java -version # 查看 Tomcat 版本解压目录下 cat apache-tomcat-9.0.xx/RELEASE-NOTES | head -5逻辑说明先确认版本再动手比装完再卸省时间。参数上JDK 8 对应-source 1.8 -target 1.8如果源码 pom.xml 里写了 1.7你本地是 1.8 也能跑但反过来不行。2.2 三张核心表学生、课程、成绩怎么建成绩管理系统的数据库设计是论文里必须写清楚的部分。常见做法是三张主表加一张关联表学生表student、课程表course、成绩表score。成绩表里存 student_id 和 course_id 作为外键再加一个 score 字段。但很多网上的源码为了省事直接把学生姓名和课程名冗余进成绩表这样查起来快但改学生姓名时数据不一致。我一般会这样建CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, sno VARCHAR(20) NOT NULL UNIQUE COMMENT 学号, sname VARCHAR(50) NOT NULL COMMENT 姓名, class_name VARCHAR(50) COMMENT 班级 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE course ( id INT PRIMARY KEY AUTO_INCREMENT, cname VARCHAR(100) NOT NULL COMMENT 课程名, credit DECIMAL(3,1) COMMENT 学分 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE score ( id INT PRIMARY KEY AUTO_INCREMENT, student_id INT NOT NULL, course_id INT NOT NULL, score DECIMAL(5,2) COMMENT 分数, exam_time DATE, FOREIGN KEY (student_id) REFERENCES student(id), FOREIGN KEY (course_id) REFERENCES course(id), UNIQUE KEY uk_stu_course (student_id, course_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;逻辑说明utf8mb4而不是utf8因为学生姓名可能有生僻字。UNIQUE KEY防止同一个学生同一门课录入两次成绩。外键约束在论文里是加分项但如果你用的 MySQL 引擎是 MyISAM外键不生效记得改成 InnoDB。参数说明DECIMAL(5,2)表示总分 999.99够用了。exam_time用 DATE 而不是 DATETIME因为成绩录入通常只关心日期。2.3 连接 MySQL 8.0 的驱动配置两个参数必须改如果你装的是 MySQL 8.0老源码里的 JDBC 配置大概率连不上。翻车点有两个驱动类名从com.mysql.jdbc.Driver变成了com.mysql.cj.jdbc.Driver连接串必须加时区和 SSL 参数。// 老写法MySQL 8.0 下会报错 String url jdbc:mysql://localhost:3306/score_db; String driver com.mysql.jdbc.Driver; // 正确写法 String url jdbc:mysql://localhost:3306/score_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue; String driver com.mysql.cj.jdbc.Driver;逻辑说明serverTimezone不设会报「The server time zone value is unrecognized」。useSSLfalse在本地开发时关掉否则会有警告。allowPublicKeyRetrievaltrue是 MySQL 8.0 默认加密方式导致的不加会连不上。参数说明characterEncodingutf8要和数据库的utf8mb4配合Java 侧用 utf8 就行MySQL 驱动会自动处理。3. JSP 页面与后端交互从登录到成绩录入的完整链路3.1 登录模块Session 存什么、怎么防绕过JSP 项目的登录逻辑通常是login.jsp 提交表单到 LoginServletServlet 查数据库验证账号密码成功则session.setAttribute(user, user)然后跳转 main.jsp。问题在于很多源码只在 login.jsp 里用 JavaScript 做了非空校验后端 Servlet 里直接拼 SQL 查询这就给了 SQL 注入的机会。我一般会改成 PreparedStatement// LoginServlet.java 核心片段 String sql SELECT * FROM user WHERE username? AND password?; PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, username); ps.setString(2, password); // 实际项目要加盐哈希毕设可先明文 ResultSet rs ps.executeQuery(); if (rs.next()) { HttpSession session request.getSession(); session.setAttribute(user, rs.getString(username)); session.setAttribute(role, rs.getString(role)); response.sendRedirect(main.jsp); } else { request.setAttribute(msg, 用户名或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); }逻辑说明PreparedStatement用占位符用户输入 OR 11也不会拼进 SQL。session.setAttribute存用户名和角色后续页面用session.getAttribute(role)判断权限。参数说明sendRedirect和forward的区别——前者地址栏变后者不变。登录成功用重定向防止刷新重复提交失败用转发保留提示信息。3.2 成绩录入页面的表单处理与中文乱码成绩录入通常是 teacher 角色才能操作。页面用 JSP 写表单提交到 AddScoreServlet。中文乱码是 JSP 项目的经典坑POST 请求默认用 ISO-8859-1 解码需要在 Servlet 第一行加request.setCharacterEncoding(UTF-8)且必须在获取任何参数之前。!-- addScore.jsp 表单片段 -- form actionAddScoreServlet methodpost 学号input typetext namesnobr 课程select namecourseId option value1Java程序设计/option option value2数据库原理/option /selectbr 分数input typetext namescorebr input typesubmit value录入 /form// AddScoreServlet.java 处理中文 request.setCharacterEncoding(UTF-8); String sno request.getParameter(sno); String courseId request.getParameter(courseId); String scoreStr request.getParameter(score); // 后续根据 sno 查 student_id再插入 score 表逻辑说明setCharacterEncoding只对 POST 有效GET 请求要在 Tomcat 的 server.xml 里配 URIEncoding。表单里课程用下拉框而不是文本框避免用户输入不存在的课程名。参数说明scoreStr要转成BigDecimal或Double直接Double.parseDouble如果用户输入字母会抛异常记得 try-catch 后返回错误提示。3.3 成绩查询与排名统计的 SQL 写法学生查分页面通常按学号查老师看排名则要按课程分组排序。这里用得上ORDER BY和GROUP BY。热搜词里提到的「mysql排序」在这个场景就是刚需。-- 查某个学生的所有成绩 SELECT c.cname, s.score, s.exam_time FROM score s JOIN course c ON s.course_id c.id JOIN student st ON s.student_id st.id WHERE st.sno ? ORDER BY s.exam_time DESC; -- 某门课的成绩排名 SELECT st.sname, s.score FROM score s JOIN student st ON s.student_id st.id WHERE s.course_id ? ORDER BY s.score DESC;逻辑说明JOIN 三张表拿到课程名和学生名避免在 JSP 里再查一次数据库。排名用ORDER BY score DESC如果分数相同可以再加st.sno ASC保证顺序稳定。参数说明?是 PreparedStatement 的占位符按顺序 setString 或 setInt。排名查询如果数据量大可以在 score 字段加索引。4. 避坑与排查JSP 成绩系统最常见的 5 个翻车现场4.1 现象Tomcat 启动报 ClassNotFoundException: com.mysql.jdbc.Driver原因MySQL 8.0 的驱动包没放进WEB-INF/lib或者放了但版本不对。很多人用 Maven 导入了依赖但 Tomcat 部署时没把 jar 包复制过去。解决确认WEB-INF/lib下有mysql-connector-java-8.0.xx.jar。如果用 Maven在 pom.xml 里加依赖后执行mvn package把生成的 war 包丢进 Tomcat。别只把编译后的 classes 拷过去。4.2 现象页面显示「」乱码原因JSP 页面头部没声明% page contentTypetext/html;charsetUTF-8 %或者数据库连接串没加characterEncodingutf8或者 Tomcat 的 server.xml 里 Connector 没加URIEncodingUTF-8。解决三处都检查。JSP 头部加 page 指令JDBC 连接串加参数server.xml 的 Connector 标签加 URIEncoding。如果是 GET 请求乱码重点查 server.xml。4.3 现象录入成绩后查不到但数据库里明明有原因插入时用了事务但没 commit或者 JSP 查询时连的是另一个数据库。常见于源码里写了conn.setAutoCommit(false)但忘了conn.commit()。解决检查 DAO 层的关闭连接逻辑。如果用了连接池确认查询和插入用的是同一个数据源。在 MySQL 命令行里SELECT * FROM score确认数据真的写进去了。4.4 现象删除学生后成绩表出现孤儿记录原因建表时没加外键或者外键没设ON DELETE CASCADE。删除 student 表记录后score 表里还留着 student_id 指向已删除的记录。解决建表时加外键约束或者在删除学生的 Servlet 里先删 score 再删 student。论文里可以讨论两种方案的优劣——级联删除方便但危险手动删除安全但代码多。4.5 现象部署后静态资源CSS/图片加载 404原因JSP 里用了相对路径但 Servlet 转发后路径变了。比如 login.jsp 里写link hrefcss/style.css转发到/servlet/login后浏览器会去/servlet/css/style.css找。解决用绝对路径link href${pageContext.request.contextPath}/css/style.css。${pageContext.request.contextPath}会解析成项目名不管怎么转发都不会错。5. 让这份源码在答辩里加分三个进阶改造方向5.1 把明文密码改成 MD5 加盐顺便讲清楚为什么毕设答辩时老师最爱问「你的密码怎么存的」。如果回答「明文」基本就凉了。改造方法在用户注册时生成一个随机盐值和密码拼接后做 MD5存进数据库。登录时用同样的盐值再算一次比对。// 注册时 String salt UUID.randomUUID().toString().substring(0, 8); String hashed DigestUtils.md5Hex(password salt); // 存 hashed 和 salt 到 user 表 // 登录时 String inputHash DigestUtils.md5Hex(inputPassword storedSalt); if (inputHash.equals(storedHash)) { /* 成功 */ }逻辑说明MD5 本身不安全但加盐后能防彩虹表。答辩时你可以说「生产环境会用 BCrypt这里用 MD5 加盐演示原理」。参数上盐值长度 8 位够用太长没必要。5.2 用过滤器统一处理编码和登录拦截每个 Servlet 都写setCharacterEncoding太啰嗦而且容易漏。加一个 Filter在doFilter里统一设置编码顺便检查 session 里有没有 user没有就踢回登录页。public class EncodingFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding(UTF-8); resp.setContentType(text/html;charsetUTF-8); HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) resp; String uri request.getRequestURI(); if (uri.contains(login.jsp) || uri.contains(LoginServlet)) { chain.doFilter(req, resp); } else { if (request.getSession().getAttribute(user) null) { response.sendRedirect(login.jsp); } else { chain.doFilter(req, resp); } } } }逻辑说明白名单放行登录相关路径其余全部检查 session。web.xml 里配filter-mapping拦截/*。这样新增页面不用改代码自动受保护。参数说明uri.contains判断比较粗糙生产环境应该用正则或 Ant 匹配。毕设够用了。5.3 导出成绩为 Excel用 POI 还是直接 CSV答辩演示时能导出 Excel 是个亮点。两种方案Apache POI 生成真正的 .xlsx或者直接写 CSV 文件。POI 功能强但依赖大CSV 简单但中文需要加 BOM 头否则 Excel 打开乱码。// CSV 方案简单可靠 response.setContentType(text/csv;charsetUTF-8); response.setHeader(Content-Disposition, attachment;filenamescores.csv); PrintWriter out response.getWriter(); out.write(\uFEFF); // BOM 头防 Excel 中文乱码 out.println(学号,姓名,课程,分数); // 循环查数据库写入 out.flush();逻辑说明\uFEFF是 UTF-8 BOMExcel 看到它就知道用 UTF-8 解码。POI 方案代码量大但能设置单元格样式、合并表头适合对格式有要求的场景。参数说明Content-Disposition的 filename 如果含中文要用URLEncoder.encode处理否则浏览器可能乱码。我自己的习惯是拿到任何一份 JSP 源码先别急着改业务先把环境跑通、把数据库建对、把乱码和驱动这两个坑填了。这三步过了后面改功能就是体力活。论文里重点写数据库设计和权限控制这两个是老师最看重的。希望帮到你。本文还有配套的精品资源点击获取
返回列表