
简介这是一套基于JSP与Java技术开发的体育成绩管理系统实战项目面向高校计算机专业学生、Web开发初学者及体育信息化管理人员解决学校体育教学、赛事组织中班级管理、项目报名、成绩统计与秩序册生成等核心业务的数字化需求。资源包共98个文件含16个JSP页面实现前后端交互与业务展示、15个JAR依赖库支撑系统运行、12个编译后CLASS文件及4个核心JAVA源码含数据库操作与算法逻辑辅以SQL建表脚本、CSS/JS前端资源及GIF操作示例图整体压缩包仅4.96MB轻量易部署。已有469人学习下载提供完整可运行工程结构含MyEclipse项目配置文件、WebRoot目录与db_tybs.sql数据库脚本附带tybs系统演示EXE录屏便于快速理解模块关联与权限控制机制是掌握JSPServletMySQL三层架构开发的典型教学案例。1. JSPJava体育成绩管理系统不是“老古董”而是教学场景下最稳的快速落地方案你可能刚在毕业设计选题表里看到“JSP体育成绩管理系统”第一反应是皱眉——都2024年了还写JSPSpring Boot不香吗但现实很骨感高校机房服务器还是Windows Server 2008 Tomcat 7数据库用SQL Server 2008 R2学生连IDEA都装不上只能靠Eclipse JDK 1.6跑通老师验收只看“能增删改查、有登录验证、导出Excel”不关心你用了多少注解。这套系统恰恰卡在“够用、易部署、零依赖、能讲清楚MVC分层”的黄金点上——它不是技术秀场而是教学闭环里的最小可行单元一个学生花3天能搭起骨架再用2天补全班级管理、成绩录入、统计报表三个核心模块答辩时现场演示不卡顿、代码逻辑能口述、数据库ER图能手绘。它解决的从来不是“高并发”或“微服务”而是“如何让大三学生在没有云服务器、没有Docker、没有Git协作的前提下独立交付一个带权限控制的真实业务系统”。适合课程设计、实训周、毕业设计初期原型验证尤其适合Java基础尚可但工程经验为零的新手——因为它的每一行代码都在教你怎么把“体育成绩”这个业务实体从纸面表格一步步变成可运行、可调试、可讲明白的Web应用。2. 系统架构与技术选型为什么JSPServletJDBC仍是教学级系统的理性选择2.1 三层结构怎么分Model层不是摆设而是业务逻辑的锚点这套系统严格遵循经典MVC分层View层JSP负责页面渲染只做简单EL表达式取值和JSTL循环禁止写Java脚本% %所有业务逻辑必须剥离Controller层Servlet每个功能对应一个Servlet如ScoreAddServlet接收请求、调用Service、转发跳转不处理数据格式化Model层JavaBean DAOStudent.java、Score.java等POJO封装属性ScoreDAO.java封装JDBC操作SQL语句全部硬编码教学场景下不引入MyBatis避免XML配置干扰主干逻辑。提示教学系统里“不引入框架”不是倒退而是降低认知负荷。学生先理解request.getParameter(score) → new Score().setScore(...) → scoreDao.add(score)这条链路比背RequestBody Valid Transactional更有价值。2.2 数据库设计体育成绩的四个核心实体与关联逻辑系统围绕“人-课-项-绩”构建ER模型共5张表含用户表关键设计如下表名主键关键字段业务约束t_useridusername,password,roleadmin/teacher/student密码明文存储教学简化实际需BCrypt加密t_studentstu_idname,class_id,gender,birth_dateclass_id关联班级表非外键避免初学者被约束报错卡住t_coursecourse_idcourse_name,semester2023-1体育课按学期开设如“篮球2023-1”、“田径2023-2”t_itemitem_iditem_name,unit秒/米/个,standard_type达标/等级支撑不同评分标准50米跑按秒数定等级引体向上按次数定达标t_scoreidstu_id,course_id,item_id,score_value,record_time复合唯一索引(stu_id,course_id,item_id) 防止重复录入2.3 开发环境配置拒绝“版本地狱”锁定教学友好组合JDK1.6 或 1.7Tomcat 7 默认兼容避免学生装JDK 17后报UnsupportedClassVersionErrorTomcat7.0.99官方最后稳定版Win/Linux双平台无坑数据库驱动sqljdbc4.jarSQL Server 2008专用放WEB-INF/lib/下不能用sqljdbc42.jar编译编码所有.java文件保存为GBK中文Windows默认JSP页面声明% page contentTypetext/html;charsetGBK %避免乱码项目结构标准Dynamic Web Projectsrc/放Java类WebContent/放JSP/JS/CSSWebContent/WEB-INF/web.xml手动配置Servlet映射。2.4 核心功能链路从登录到成绩导出的四步闭环以教师录入学生成绩为例走通完整MVC链路登录验证LoginServlet获取username/password→ 查询t_user→roleteacher则存入session成绩录入页ScoreInput.jsp通过request.getAttribute(studentList)显示班级学生下拉框提交处理ScoreAddServlet接收stu_id、item_id、score_value→ 封装Score对象 → 调用ScoreDAO.add()执行INSERT结果反馈成功则重定向至ScoreList.jsp带查询参数失败则request.setAttribute(error, 分数超出范围)并转发回录入页。注意所有跳转用response.sendRedirect()重定向而非RequestDispatcher.forward()转发确保浏览器地址栏URL实时更新方便学生调试时看清当前路径。3. 关键模块实现手把手写出可运行的成绩录入与统计报表3.1 成绩录入模块动态加载项目与智能校验ScoreInput.jsp需根据所选课程动态加载考核项目避免硬编码选项。核心逻辑在Servlet中// ScoreInputServlet.java String courseId request.getParameter(course_id); ListItem itemList itemDao.findByCourseId(courseId); // 查询该课程所有考核项目 request.setAttribute(itemList, itemList); request.getRequestDispatcher(ScoreInput.jsp).forward(request, response);JSP端用JSTL遍历渲染select nameitem_id c:forEach items${itemList} varitem option value${item.itemId}${item.itemName}${item.unit}/option /c:forEach /select前端校验增强防误操作// ScoreInput.jsp 内嵌JS function validateScore() { const scoreVal parseFloat(document.getElementById(score_value).value); const unit document.querySelector(select[nameitem_id] option:checked).text; if (unit.includes(秒)) { if (scoreVal 0 || scoreVal 300) { // 50米跑不可能超5分钟 alert(时间应在0-300秒之间); return false; } } else if (unit.includes(米)) { if (scoreVal 0 || scoreVal 100) { // 立定跳远超10米属异常 alert(距离应在0-100米之间); return false; } } return true; }3.2 成绩统计报表用原生JDBC实现分组聚合不依赖图表库ScoreReportServlet生成班级平均分、及格率、最高分三类统计SQL直写// ScoreReportServlet.java String sql SELECT t_class.class_name, AVG(t_score.score_value) as avg_score, COUNT(CASE WHEN t_score.score_value 60 THEN 1 END) * 100.0 / COUNT(*) as pass_rate, MAX(t_score.score_value) as max_score FROM t_score JOIN t_student ON t_score.stu_id t_student.stu_id JOIN t_class ON t_student.class_id t_class.class_id WHERE t_score.course_id ? GROUP BY t_class.class_name; PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, courseId); ResultSet rs ps.executeQuery(); while (rs.next()) { ReportItem item new ReportItem(); item.setClassName(rs.getString(class_name)); item.setAvgScore(rs.getDouble(avg_score)); item.setPassRate(rs.getDouble(pass_rate)); item.setMaxScore(rs.getDouble(max_score)); reportList.add(item); } request.setAttribute(reportList, reportList);报表页面ScoreReport.jsp用表格呈现table border1 trth班级/thth平均分/thth及格率(%)/thth最高分/th/tr c:forEach items${reportList} varr tr td${r.className}/td tdfmt:formatNumber value${r.avgScore} pattern0.00//td tdfmt:formatNumber value${r.passRate} pattern0.00//td td${r.maxScore}/td /tr /c:forEach /table3.3 Excel导出功能用Apache POI 3.9生成兼容Office 2003的.xls文件教学系统不追求.xlsx.xls更稳妥POI 3.9支持JDK 1.6且文件体积小// ExportScoreServlet.java HSSFWorkbook workbook new HSSFWorkbook(); HSSFSheet sheet workbook.createSheet(体育成绩); // 表头 String[] headers {学号, 姓名, 班级, 项目, 成绩, 录入时间}; HSSFRow headerRow sheet.createRow(0); for (int i 0; i headers.length; i) { headerRow.createCell(i).setCellValue(headers[i]); } // 数据行 ListScore scoreList scoreDao.findAllByCourse(courseId); int rowNum 1; for (Score s : scoreList) { HSSFRow row sheet.createRow(rowNum); row.createCell(0).setCellValue(s.getStuId()); row.createCell(1).setCellValue(s.getStuName()); // 从student表联查 row.createCell(2).setCellValue(s.getClassName()); row.createCell(3).setCellValue(s.getItemName()); row.createCell(4).setCellValue(s.getScoreValue()); row.createCell(5).setCellValue(new SimpleDateFormat(yyyy-MM-dd).format(s.getRecordTime())); } // 响应输出 response.setContentType(application/vnd.ms-excel); response.setHeader(Content-Disposition, attachment;filenamescore_export_ new SimpleDateFormat(yyyyMMddHHmmss).format(new Date()) .xls); workbook.write(response.getOutputStream());注意HSSFWorkbook生成的是二进制流必须用response.getOutputStream()写入绝不能用PrintWriter否则Excel打开报错。4. 避坑指南教学部署中最常翻车的五个血泪现场4.1 现象Tomcat启动后访问http://localhost:8080/xxx/login.jsp报404原因项目未正确部署为Web Application或web.xml中Servlet映射路径错误。常见误操作Eclipse中右键项目→“Run As”→“Java Application”错应选“Run As”→“Run on Server”web.xml里servlet-mapping的url-pattern写成/login但JSP实际路径是/login.jsp导致Servlet无法接管请求。解决检查Eclipse的Servers视图确认项目已发布到Tomcat图标为绿色勾打开web.xml确认servlet-mapping的url-pattern与表单action完全一致如url-pattern/login/url-pattern对应form actionlogin若仍404在Tomcat日志logs/catalina.out中搜索Deploying web application确认项目名是否含空格或中文改为纯英文。4.2 现象登录成功后跳转到空白页或session.getAttribute(user)返回null原因HttpSession未正确传递或JSP页面未启用session。web.xml中未配置session-config导致某些Tomcat版本默认禁用sessionJSP页面顶部缺失% page sessiontrue %指令导致每次请求新建session。解决在web.xml中添加session-config session-timeout30/session-timeout /session-config所有JSP页面第一行强制声明% page languagejava contentTypetext/html;charsetGBK pageEncodingGBK sessiontrue %登录Servlet中存入sessionsession.setAttribute(user, user)不要用request.setAttribute()。4.3 现象录入成绩时中文显示为??数据库里存的是乱码原因JDBC连接URL未指定字符集或SQL Server数据库排序规则不匹配。连接字符串漏写useUnicodetruecharacterEncodingGBKSQL Server数据库默认排序规则为SQL_Latin1_General_CP1_CI_AS不支持中文。解决修改DBUtil.java中的连接URLString url jdbc:sqlserver://localhost:1433;DatabaseNamesportsdb;useUnicodetrue;characterEncodingGBK;;在SQL Server Management Studio中执行ALTER DATABASE sportsdb COLLATE Chinese_PRC_CI_AS;重启Tomcat重新部署项目。4.4 现象点击“导出Excel”后浏览器下载文件名是download.xls且内容为空原因HTTP响应头设置错误或POI写入流后未关闭。Content-Type写成application/octet-stream通用二进制类型Office无法识别workbook.write(outputStream)后未调用outputStream.close()导致部分数据未刷入响应流。解决严格使用application/vnd.ms-excel作为MIME类型workbook.write(response.getOutputStream())后无需手动close容器会自动关闭关键检查点在Servlet末尾加return;防止后续代码干扰输出流。4.5 现象统计报表中“及格率”显示为0.0实际数据有及格记录原因SQL中整数除法截断COUNT(CASE...)/COUNT(*)结果为0。SQL Server中两个整数相除结果仍是整数如5/100未转为浮点运算。解决将SQL中的除法改为COUNT(CASE WHEN t_score.score_value 60 THEN 1 END) * 100.0 / COUNT(*) as pass_rate注意100.0带小数点强制类型提升100整数无效。5. 进阶技巧让系统真正“可用”的三个实战优化5.1 权限精细化基于角色的页面级拦截不用框架也能做教学系统常被要求“学生只能看自己成绩教师能管本班管理员全权限”。不用Shiro手写Filter即可// AuthFilter.java public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) resp; String uri request.getRequestURI(); HttpSession session request.getSession(false); if (session null !uri.endsWith(login.jsp) !uri.contains(/LoginServlet)) { response.sendRedirect(request.getContextPath() /login.jsp); return; } if (session ! null) { User user (User) session.getAttribute(user); if (user ! null) { // 学生只能访问个人成绩页 if (student.equals(user.getRole()) !(uri.endsWith(myScore.jsp) || uri.contains(/MyScoreServlet))) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } // 教师只能访问本班相关页面 if (teacher.equals(user.getRole()) uri.contains(class) !uri.contains(class_id user.getClassId())) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } } } chain.doFilter(req, resp); }web.xml中注册filter filter-nameAuthFilter/filter-name filter-classcom.sports.filter.AuthFilter/filter-class /filter filter-mapping filter-nameAuthFilter/filter-name url-pattern/*/url-pattern /filter-mapping5.2 数据安全加固两步杜绝SQL注入与XSS攻击SQL注入防护所有DAO方法禁用字符串拼接SQL强制使用PreparedStatement// ✅ 正确参数化查询 String sql SELECT * FROM t_student WHERE class_id ?; PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, classId); // ❌ 错误拼接SQL教学系统也绝不允许 String sql SELECT * FROM t_student WHERE class_id classId ;XSS防护JSP输出用户数据前用自定义函数转义HTML特殊字符% taglib prefixfn urihttp://java.sun.com/jsp/jstl/functions % !-- 在c:out标签中启用escapeXml -- c:out value${student.name} escapeXmltrue/ !-- 或用EL函数 -- ${fn:escapeXml(student.name)}5.3 部署包瘦身一键打包可运行的WAR包告别环境差异学生交作业最怕“我本地能跑老师机子打不开”。终极方案提供build-war.bat脚本自动打包含Tomcat的便携版echo off REM build-war.bat - 生成含内嵌Tomcat的可运行WAR包 set PROJECT_DIR. set TOMCAT_HOMEapache-tomcat-7.0.99 set WAR_NAMEsports.war REM 清理旧包 if exist %WAR_NAME% del %WAR_NAME% if exist %TOMCAT_HOME% rmdir /s /q %TOMCAT_HOME% REM 复制Tomcat xcopy template-tomcat %TOMCAT_HOME% /E /I /Y REM 构建WAREclipse导出或命令行jar jar -cf %WAR_NAME% -C WebContent . REM 将WAR放入Tomcat webapps copy %WAR_NAME% %TOMCAT_HOME%\webapps\ echo. echo ✅ 已生成可运行包%WAR_NAME% echo ✅ 双击 start-tomcat.bat 即可启动 pause配套start-tomcat.batecho off cd /d apache-tomcat-7.0.99\bin startup.bat echo. echo 访问 http://localhost:8080/sports/login.jsp pause从那以后我每次帮学生调试都强制走一遍build-war.bat再发包——不是信不过IDE的导出功能而是亲眼看着jar -cf命令跑完、startup.bat弹出黑窗、浏览器输入URL立刻出现登录框这种确定性比任何口头保证都管用。教学系统的价值不在代码多炫酷而在“交给老师那一刻它就该稳稳跑起来”。希望帮到你。本文还有配套的精品资源点击获取