ARTICLE DETAIL

资讯详情

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

JSP+SQL实验教学管理系统源码实战:环境搭建、核心模块与避坑指南

JSP+SQL实验教学管理系统源码实战:环境搭建、核心模块与避坑指南 简介这是一套面向高校计算机相关专业学生与Java初学者、以JavaWeb技术栈实现的实验教学管理系统实战项目可作为毕业设计或课程设计参考方案帮助解决选题难、代码不完整、文档缺失等常见问题。压缩包为zip格式整体约3.66MB内含前后端源码、数据库脚本、说明文档与配套论文覆盖JSP页面、Java后端逻辑、SQL建表与数据操作等核心模块便于读者理解系统从数据库设计到页面交互的完整链路。资源围绕实验教学管理场景展开涉及用户权限、实验课程与成绩等典型业务模块适合对照学习JavaWeb分层开发思路与调试方法。目前已有88人学习下载可作为课程设计选题、毕业设计实现与答辩材料整理的参考帮助读者快速搭建可运行环境并梳理项目结构。1. 从一份 JSPSQL 实验教学管理系统源码说起它到底能解决什么如果你正在找 JavaWeb 方向的课程设计或毕设选题JSPSQL 实验教学管理系统大概率已经出现在你的候选清单里。这个标题背后是一套典型的传统 JavaWeb 项目前端用 JSP 页面渲染后端用 Servlet 或简单 MVC 分层处理请求数据落在 MySQL 或 SQL Server 里配套还有论文、数据库脚本和说明文档。它要解决的问题很具体——高校实验教学里实验项目发布、学生选课、实验报告提交、教师批改、成绩统计这几件事如果靠 Excel 和邮件来回传教师端统计一次成绩要花掉整个下午学生也查不到自己历次实验的完成状态。这套系统适合三类人一是 JavaWeb 课程设计需要完整案例的学生二是准备用传统 JSP 技术栈做毕设的人三是想通过一个真实项目把 JSP、Servlet、JDBC、SQL 串起来理解的初学者。它不适合追求 Spring Boot 前后端分离的人因为技术栈本身就是“传统”二字。但正因为传统它反而能让你看清一个 Web 请求从浏览器到数据库再回到页面的完整链路这对后面学任何框架都有底子上的帮助。下面我按实际复现顺序把环境、数据库、核心模块和踩坑点拆开讲。2. 环境搭建与项目导入IDEA 里跑通第一个 JSP 页面2.1 为什么传统 JSP 项目在 IDEA 里容易翻车很多人拿到源码后第一步就卡住IDEA 新建项目时选了 Jakarta EE结果 JSP 页面里的% page %指令报错或者 Tomcat 启动后 404。根本原因是 JSP 属于 Java EE现 Jakarta EE的 Web 层技术IDEA 不同版本对 Web 模块的支持方式不一样。常见做法是不要用“New Project”里的 Jakarta EE 模板而是直接打开源码目录然后手动配置 Facet 和 Artifact。另一个高频问题是 JDK 版本——JSPServlet 项目通常跑在 JDK 8 或 JDK 11 上如果你用 JDK 17 配 Tomcat 9编译时可能遇到javax.servlet包找不到因为 Tomcat 10 之后包名已经变成jakarta.servlet。所以选 Tomcat 9 JDK 8/11 是最稳的组合。具体操作上先确认本机 Java 环境变量配好命令行java -version能输出 1.8 或 11。然后下载 Tomcat 9 的 zip 包解压到不含中文和空格的路径。IDEA 里 File → Open 选中项目根目录等 Maven 或普通 Web 项目结构加载完。如果项目没有 pom.xml就在 Project Structure → Modules 里添加 Web Facet把 web 目录或 WebContent 目录指定为 Web Resource Directoryweb.xml 路径指向 WEB-INF 下的文件。2.2 在 IDEA 中配置 Tomcat 并部署 war 包配置 Tomcat 的入口在 Run → Edit Configurations → 加号 → Tomcat Server → Local。关键参数有三个Application server 指向你解压的 Tomcat 目录HTTP port 默认 8080如果被占用就改 8081Deployment 标签页里点加号选 Artifact通常选项目名:war exploded这样改 JSP 不用每次重新打包。Application context 建议设成/或/exp后面访问地址就是http://localhost:8080/exp/。# 检查端口占用避免 Tomcat 启动时报 Address already in use # Windows netstat -ano | findstr :8080 # Linux / macOS lsof -i :8080 # 如果 8080 被占用要么杀掉进程要么在 IDEA 里把 HTTP port 改成 8081上面命令的作用是排查端口冲突。参数说明findstr是 Windows 下过滤文本的命令lsof -i在类 Unix 系统下列出指定端口的占用进程。如果你看到 PID 后想强制结束Windows 用taskkill /PID 进程号 /FLinux 用kill -9 进程号。但更推荐直接换端口避免影响其他服务。部署时还有一个细节Artifact 的输出目录里必须包含WEB-INF/classes和WEB-INF/lib。如果 classes 目录是空的说明源码没有被编译到 Web 输出路径。去 Project Structure → Artifacts → 选中 war exploded → Output Layout把 “Compiler Output” 加进去。这样 Tomcat 启动时才能找到编译后的 Servlet 类。2.3 数据库选型与连接配置MySQL 还是 SQL Server标题里写的是 SQL没有指定具体数据库。从热搜词看MySQL 和 SQL Server 都有人用。我的建议是如果源码里带的是.sql脚本且语法是AUTO_INCREMENT那就是 MySQL如果是IDENTITY(1,1)那就是 SQL Server。两者在 JDBC 连接串上差别很大。MySQL 8 的连接配置# db.properties 常见写法 jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/exp_teaching?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse jdbc.usernameroot jdbc.password你的密码SQL Server 2019 的连接配置jdbc.drivercom.microsoft.sqlserver.jdbc.SQLServerDriver jdbc.urljdbc:sqlserver://localhost:1433;databaseNameexp_teaching;encryptfalse jdbc.usernamesa jdbc.password你的密码参数说明MySQL 的serverTimezone不设会导致时间字段差 8 小时useSSLfalse在本地开发时避免证书警告。SQL Server 的encryptfalse是为了绕过驱动默认开启 SSL 导致的连接失败热搜词里“驱动程序无法通过使用安全套接字层加密与 SQL Server 建立安全连接”就是这个原因。如果你坚持用加密连接需要在 Java 侧导入证书本地开发没必要。导入数据库脚本时先建库再导表。命令行方式# MySQL mysql -u root -p -e CREATE DATABASE exp_teaching DEFAULT CHARACTER SET utf8mb4; mysql -u root -p exp_teaching exp_teaching.sql # SQL Server 用 sqlcmd sqlcmd -S localhost -U sa -P 你的密码 -Q CREATE DATABASE exp_teaching sqlcmd -S localhost -U sa -P 你的密码 -d exp_teaching -i exp_teaching.sql导入后检查表数量和中文字段是否乱码。如果乱码把连接串里的characterEncoding改成utf8或utf8mb4并确认数据库排序规则是utf8mb4_general_ci。3. 核心模块拆解实验项目发布、选课与报告提交的 JSPServlet 实现3.1 实验项目发布模块的表结构与 Servlet 映射实验教学管理系统的核心表通常有四张experiment实验项目、student学生、selection选课记录、report实验报告。以experiment为例字段包括exp_id、exp_name、exp_content、publish_time、teacher_id、deadline。发布实验的流程是教师在 JSP 表单填写实验名称、内容、截止时间提交到ExperimentServletServlet 调用 DAO 插入数据库然后重定向到列表页。// ExperimentServlet.java 核心 doPost 片段 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); String expName request.getParameter(expName); String expContent request.getParameter(expContent); String deadline request.getParameter(deadline); int teacherId (int) request.getSession().getAttribute(userId); Experiment exp new Experiment(); exp.setExpName(expName); exp.setExpContent(expContent); exp.setDeadline(java.sql.Date.valueOf(deadline)); exp.setTeacherId(teacherId); ExperimentDao dao new ExperimentDao(); boolean success dao.insert(exp); if (success) { response.sendRedirect(request.getContextPath() /experiment/list); } else { request.setAttribute(msg, 发布失败请检查数据库连接); request.getRequestDispatcher(/teacher/publish.jsp).forward(request, response); } }逻辑说明request.setCharacterEncoding(UTF-8)必须放在获取参数之前否则中文实验名称会乱码。java.sql.Date.valueOf(deadline)把 HTML 日期输入框的yyyy-MM-dd字符串转成 SQL 日期类型。sendRedirect和forward的区别是前者让浏览器重新发起请求地址栏变化后者在服务器内部转发地址栏不变。发布成功后用重定向可以避免刷新页面重复提交。参数说明expName对应表单nameexpNamedeadline对应input typedate namedeadline。如果表单用的是enctypemultipart/form-datarequest.getParameter会取不到值需要用文件上传组件先解析。这是 JSP 项目里非常隐蔽的一个坑。3.2 学生选课与 SQL 去重、空值处理选课模块的典型逻辑是学生点击“选课”按钮系统在selection表插入一条记录同时要防止重复选同一门实验。热搜词里“sql 语句去重”和“sql 去除空值”在这个场景下很实用。-- 插入前先检查是否已选避免重复记录 INSERT INTO selection (student_id, exp_id, select_time) SELECT 1001, 5, NOW() FROM DUAL WHERE NOT EXISTS ( SELECT 1 FROM selection WHERE student_id 1001 AND exp_id 5 ); -- 查询某学生已选实验过滤掉实验名称为空的脏数据 SELECT s.exp_id, e.exp_name, s.select_time FROM selection s LEFT JOIN experiment e ON s.exp_id e.exp_id WHERE s.student_id 1001 AND e.exp_name IS NOT NULL AND e.exp_name ;逻辑说明第一条 SQL 用INSERT ... SELECT ... WHERE NOT EXISTS实现“存在即跳过”比先查再插少一次数据库往返也避免了并发下的重复插入。第二条用LEFT JOIN保留选课记录同时用IS NOT NULL和 过滤掉实验项目被删除后留下的空关联。注意NULL和空字符串在 SQL 里不是一回事IS NOT NULL不会过滤空字符串所以要两个条件都写。参数说明student_id和exp_id在实际项目里应该用?占位符配合PreparedStatement不要直接拼字符串否则会有 SQL 注入风险。热搜词里“sql 注入万能密码绕过”就是拼接 SQL 的后果。用PreparedStatement后即使用户输入 OR 11也会被当成普通字符串处理。3.3 实验报告提交与文件上传的 JSP 实现实验报告提交涉及文件上传JSP 页面必须设置enctypemultipart/form-data后端用commons-fileupload或 Servlet 3.0 的MultipartConfig处理。下面用 Servlet 3.0 原生方式不额外引包。WebServlet(/report/upload) MultipartConfig(maxFileSize 10 * 1024 * 1024, maxRequestSize 12 * 1024 * 1024) public class ReportUploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); int studentId (int) request.getSession().getAttribute(userId); int expId Integer.parseInt(request.getParameter(expId)); Part filePart request.getPart(reportFile); String fileName filePart.getSubmittedFileName(); // 防止文件名冲突用时间戳前缀 String savedName System.currentTimeMillis() _ fileName; String saveDir getServletContext().getRealPath(/uploads); File dir new File(saveDir); if (!dir.exists()) dir.mkdirs(); filePart.write(saveDir File.separator savedName); ReportDao dao new ReportDao(); dao.insert(new Report(studentId, expId, savedName, new java.util.Date())); response.sendRedirect(request.getContextPath() /report/list); } }逻辑说明MultipartConfig注解限定了单文件和整个请求的大小超过会抛异常。getSubmittedFileName()拿到原始文件名但不同浏览器可能带路径实际项目里应该用Paths.get(fileName).getFileName().toString()再处理一次。getRealPath(/uploads)把 Web 路径映射到磁盘路径但注意war 包重新部署后这个目录可能被清空生产环境应该存到外部目录数据库里只存相对路径。参数说明maxFileSize是单个文件上限maxRequestSize是包含表单字段在内的总上限。如果学生上传 20MB 的 PDF会直接报IllegalStateException前端最好用 JavaScript 先校验大小。filePart.write()的路径分隔符用File.separator保证跨平台。4. 避坑与排查JSPSQL 项目最常见的 5 个翻车现场4.1 中文乱码从 JSP 页面到数据库的全链路排查现象实验名称在表单里输入中文保存到数据库变成????或者页面显示成乱码。原因通常有三层JSP 页面编码、请求编码、数据库连接编码。解决顺序是JSP 文件头部确认% page contentTypetext/html;charsetUTF-8 languagejava %Servlet 里request.setCharacterEncoding(UTF-8)放在第一行数据库连接串加characterEncodingutf8MySQL 建库时用utf8mb4。如果是 Tomcat 8 以上GET 请求的中文还需要在 server.xml 的 Connector 上加URIEncodingUTF-8。4.2 404 与 500web.xml 版本和 Servlet 映射的对应关系现象Tomcat 启动正常访问登录页 404或者提交表单 500。原因404 多半是url-pattern写错比如 Servlet 注解写/login表单 action 写login.jsp。500 常见于web.xml里 Servlet 版本声明和实际类不匹配比如用了 Servlet 3.0 注解但web-app头还是 2.3。解决确认web.xml的version3.1且metadata-completefalse或者干脆删掉 web.xml 里的 Servlet 配置全用注解。另外WebServlet的 value 必须以/开头。4.3 SQL 注入为什么你的登录框能被万能密码绕过现象登录框输入admin OR 11就能进系统。原因DAO 里用字符串拼接 SQL比如SELECT * FROM user WHERE username name 。解决全部改成PreparedStatement用?占位。下面是对比// 错误写法拼接 SQL存在注入 String sql SELECT * FROM student WHERE username username AND password password ; // 正确写法PreparedStatement 预编译 String sql SELECT * FROM student WHERE username? AND password?; PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, username); ps.setString(2, password); ResultSet rs ps.executeQuery();参数说明setString会自动对特殊字符转义会被当成普通字符。注意密码不要明文存至少做一次 MD5 或 BCrypt虽然 JSP 老项目里经常直接存明文但这是另一个必须改的点。4.4 数据库连接泄漏Tomcat 跑一会儿就卡死现象系统用几分钟后所有页面都转圈重启 Tomcat 又正常。原因DAO 里Connection、Statement、ResultSet没有在 finally 里关闭连接池耗尽。解决用 try-with-resources 自动关闭或者确保 finally 块里按ResultSet → Statement → Connection顺序关闭。如果项目用了 DBCP 或 C3P0检查maxActive和maxIdle配置本地开发设 10 和 5 就够。4.5 war 包部署到 Tomcat 后图片和 CSS 丢失现象IDEA 里跑正常打成 war 放到独立 Tomcat 的 webapps 下页面样式全丢。原因JSP 里引用资源用了相对路径比如hrefcss/style.css但页面 URL 是多级路径/exp/student/list.jsp浏览器会去/exp/student/css/找。解决所有静态资源引用加request.getContextPath()写成href%request.getContextPath()%/css/style.css。或者用c:url标签。另外war 包里的uploads目录如果是空的解压后可能不生成需要手动放一个占位文件。5. 从能跑到能交论文、说明文档与二次开发的取舍5.1 配套论文和说明文档怎么用才不浪费时间这类资源包里的论文通常是毕设模板结构是“绪论→需求分析→系统设计→实现→测试→总结”。我的习惯是先看数据库设计章节和系统功能图这两块直接决定你的表结构和模块划分。说明文档如果写的是部署步骤对照第 2 章的环境配置走一遍遇到不一致的地方以实际代码为准。论文里的“创新点”部分不用照抄但可以改成你实际做的优化比如把 SQL 查询加了索引、把重复选课用NOT EXISTS解决。这样答辩时被问到也有东西说。5.2 二次开发建议加一个实验成绩统计页面如果想让项目看起来不那么像模板最省力的二次开发是加一个成绩统计页。教师端按实验项目分组统计已提交人数、平均分、最高分。SQL 用GROUP BY和聚合函数SELECT e.exp_name, COUNT(r.report_id) AS submit_count, AVG(r.score) AS avg_score, MAX(r.score) AS max_score FROM experiment e LEFT JOIN report r ON e.exp_id r.exp_id WHERE e.teacher_id ? GROUP BY e.exp_id, e.exp_name ORDER BY e.publish_time DESC;参数说明LEFT JOIN保证没有学生提交的实验也会显示submit_count为 0。AVG和MAX会自动忽略 NULL 分数。如果要在 JSP 里展示用 JSTL 的c:forEach遍历结果集注意avg_score用fmt:formatNumber保留一位小数。这个页面代码量不大但能让你的系统从“能跑”变成“有分析功能”答辩时是个加分项。5.3 传统 JSP 项目值不值得继续投入我的判断是作为学习项目值得。它让你亲手处理请求参数、会话管理、JDBC 事务、SQL 优化这些框架帮你封装掉的东西。但作为求职项目它的天花板很明显——现在企业里很少用 JSP 做新系统。所以策略是用这个项目把 JavaWeb 基础打牢然后花两周把同样的业务用 Spring Boot Thymeleaf 或前后端分离重写一遍。重写时你会发现之前踩过的编码、连接池、SQL 注入坑在框架里都有默认解法理解会更深。我自己的习惯是每做完一个传统项目就画一张请求链路图从浏览器到 Tomcat 到 Servlet 到 DAO 到数据库标出每一层可能出问题的地方。这张图比任何笔记都管用。希望帮到你。本文还有配套的精品资源点击获取
返回列表