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

网上考试系统JavaEE大作业:架构、代码、报告与避坑指南

网上考试系统JavaEE大作业:架构、代码、报告与避坑指南 ★ FEATURED ARTICLE
简介在JavaEE开发中数据库设计与会话管理是构建Web应用的核心基础。通过合理的表结构规划实体关系利用Servlet与JDBC实现数据交互再借助Filter过滤器解决登录鉴权与角色权限控制这些原理构成了网上考试系统等课程设计的主流技术路线。理解这些基础概念的价值在于既能保障系统的数据一致性又能提升代码的分层清晰度还便于应对答辩时关于底层原理的追问。此类技术广泛应用于在线教育、教务管理等领域也是JavaEE大作业中最常见的选题方向最终沉淀出一套涵盖架构设计、代码实战、报告撰写与部署避坑的完整参考资源。1. 期末大作业选网上考试系统代码、报告、使用说明一次配齐网上考试系统是 JavaEE 课程设计里出现频率最高的题目之一原因很现实它覆盖 Servlet、JSP、JDBC、会话管理、角色权限这些必修考点又不像电商系统那样要处理订单和支付边界足够清晰一个人两周能写完。这份资源包把源代码、设计报告、使用说明三件套打包在一起适合两类人——一类是时间紧、需要一份能讲清楚的设计报告来对照写自己版本的学生另一类是想要一个可运行基线、再往上面加功能当创新点的开发者。我用它复现过一整套流程本文按「架构怎么定、代码怎么写、报告怎么编、部署踩过哪些坑、演示怎么出彩」的顺序给你拆明白每步都能抄作业。2. 架构与数据库设计角色权限与五张表怎么定2.1 三个角色与核心用例从需求到边界网上考试系统的典型角色划分是管理员、教师、学生。从用例图角度管理员管账号和课程/班级教师管题库和试卷学生参加考试和查看成绩。这个三角色模型几乎是所有 JavaEE 课程设计的标准答案因为教科书里的 Servlet 过滤器、会话管理都能用上。我见过不少同学一上来就画了八个用例把「查看历史成绩」「导出成绩单」全塞进去结果代码写到一半发现自己被用例图绑架了。大作业的第一原则是控制边界三个角色每个角色两到三个核心操作其余全部砍掉。比如学生端就是登录、参加考试、查看成绩教师端就是登录、录入试题、组卷、发布考试管理员端就是登录、管理用户、管理课程。这套模型下整个系统的用例数不超过十个数据库表不超过六张工作量刚好卡在两周能写完的区间里。从技术选型上看Servlet JSP JDBC MySQL 是这门课的标准组合。为什么不选 Spring Boot因为大作业评分的重点通常是「你是否理解 Servlet 生命周期、请求响应模型、会话状态管理」Spring Boot 把这些都封装了答辩时你反而说不出底层原理。用原生 Servlet 写控制器用 JSP 写视图用 JDBC 写数据访问每一层都能在报告里单独开一节老师一眼就能看出这是自己写的。2.2 数据库设计六张表撑起一个考试系统网上考试系统的表结构没有想象中复杂我一般建议按这个最小集来设计表名核心字段作用t_userid, username, password, role, real_name统一账号表用 role 区分管理员/教师/学生t_courseid, course_name, teacher_id课程表一对多关联学生t_questionid, course_id, type, content, options, answer, score试题表单选/多选/判断用 type 区分t_paperid, course_id, paper_name, duration, status试卷表关联一个课程的多道题t_paper_questionpaper_id, question_id, score试卷与试题的多对多关联表t_exam_recordid, paper_id, student_id, score, start_time, submit_time考试记录表记录每次答题结果这里有个关键设计决策试题表里的 options 字段。我见过有人为每个选项建一列option_a, option_b, option_c, option_d也有人用 JSON 存。大作业的答案建议用分隔符字符串比如选项内容存成「A.xxx|B.xxx|C.xxx|D.xxx」答案存成「A,C」表示多选。用 JSON 确实更现代但答辩时如果老师问「你用什么解析 JSON」你得能接住用字符串分隔符一个 split() 就能讲清楚知识密度刚好匹配大作业的评分预期。多对多关联表 t_paper_question 是整张 ER 图的枢纽。教师在组卷时往这张表里插记录学生在答题时按这张表的顺序遍历题目。有些同学的实现里把题目内容冗余在试卷表里后续改题时就得同步改试卷数据数据一致性很难维护。用关联表设计的优势在于一套题库可以组合出多套试卷改题只需改 t_question不需要碰 t_paper。2.3 SQL 初始化脚本与测试数据让系统第一次启动就能点起来资源包里的 SQL 脚本通常建好库表和基础数据。我拿到手的第一步不是看代码而是先检查初始化脚本里有没有造测试数据。很多版本的脚本只建表不插数据启动后登录页面空荡荡全班通知「登录不了」——其实不是程序问题是库里根本没有账号。我一般会把脚本改成三步走第一步 CREATE DATABASE第二步 CREATE TABLE第三步 INSERT 基础账号管理员、教师、学生各一个 少量课程和试题。这样设计的好处是报告的需求分析章节可以直接引用「系统预置三类账号用于功能演示」使用说明文档里也可以明确写「管理员账号 admin / admin123教师账号 teacher / teacher123学生账号 student / student123」。答辩演示时直接拿预置账号登录比现场注册省十秒这十秒在紧张状态下能帮你避免不少手滑。SQL 脚本里我习惯给核心表加注释例如CREATE TABLE t_question ( id INT PRIMARY KEY AUTO_INCREMENT, course_id INT NOT NULL COMMENT 所属课程关联t_course.id, type TINYINT COMMENT 1单选 2多选 3判断, content VARCHAR(500) COMMENT 题干, options VARCHAR(1000) COMMENT 选项用|分隔判断题可不填, answer VARCHAR(20) COMMENT 正确答案多选用逗号分隔如A,C, score INT DEFAULT 5 COMMENT 每题分值 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这里的 type 用 TINYINT 而不是 VARCHAR是为了在 Java 里映射时可以直接 switch 分支answer 用 VARCHAR 是因为多选答案天然是集合逗号分隔后用 String.split(,) 就能还原数组。这些字段注释反过来也是报告里「数据库设计」章节的素材不用另写。写到这里我突然想提醒一句SQL 脚本的字符集一定要用 utf8mb4。有的电脑默认 latin1导入完之后前端页面全是问号翻车率极高。顺手把 collation 也指定成 utf8mb4_general_ci排序规则统一后面做模糊查询时不会出幺蛾子。2.4 分层结构对照设计图包名暴露了你的架构能力JavaEE 大作业的分层一般长这样src/main/java ├── com.example.exam │ ├── entity # 实体类对应数据库表 │ ├── dao # 数据访问层JDBC操作 │ ├── service # 业务逻辑层判分、组卷 │ ├── servlet # 控制层接收请求、转发 │ └── filter # 过滤器登录校验、角色鉴权 src/main/webapp ├── jsp │ ├── admin │ ├── teacher │ ├── student │ └── common └── WEB-INF └── web.xml这个包结构看起来普通但放到报告里就是一张现成的「系统架构图」——你只需要在 Word 里把每个包对应的职责用小号字标注出来。答辩时老师问「你分层了吗」直接指着这个结构说「控制层只做参数接收和视图转发业务逻辑在 service 层数据访问在 dao 层」一句废话没有。实体类的写法有讲究。字段要和表结构一一对应但有些同学会用 VARCHAR 存多选题答案实体类里就放 String有些用 TINYINT 存类型实体类里就放 Integer。我见过有人把 t_exam_record 里的 score 字段设成 String理由是「数据库里可能存小数」结果判分时先 Integer.parseInt 再做运算白白多一步转换。大作业的分数建议用整数实体类和数据库字段全部对齐代码里少一层类型转换也就少一个 NPE 的坑。3. 核心代码实战登录鉴权、组卷、在线答题与自动判分3.1 登录与角色鉴权Filter 过滤器怎么写才稳网上考试系统的登录鉴权是大作业的必考项也是答辩时老师最可能追问的地方。标准做法是用 Session 保存登录用户用一个 Filter 拦截所有受保护资源。先看登录 Servlet 的核心逻辑WebServlet(/login) public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username req.getParameter(username); String password req.getParameter(password); // 简化的校验查数据库比对用户 User user userDao.findByUsernameAndPassword(username, password); if (user ! null) { HttpSession session req.getSession(); session.setAttribute(loginUser, user); // 按角色跳转不同首页 if (student.equals(user.getRole())) { resp.sendRedirect(req.getContextPath() /jsp/student/index.jsp); } else if (teacher.equals(user.getRole())) { resp.sendRedirect(req.getContextPath() /jsp/teacher/index.jsp); } else { resp.sendRedirect(req.getContextPath() /jsp/admin/index.jsp); } } else { req.setAttribute(error, 用户名或密码错误); req.getRequestDispatcher(/jsp/common/login.jsp).forward(req, resp); } } }这段代码有几个细节值得在报告里展开。第一密码比对是在 DAO 层完成的Servlet 里不写 SQL这是「分层」的直观体现。第二登录成功后把 User 对象整体放进 Session而不是只放 username这样后续取角色、取姓名都不用再查库。第三失败时用 forward 而不是 redirect这样登录页能显示 error 属性而地址栏不会变化。再来写鉴权 FilterWebFilter(/*) public class AuthFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req (HttpServletRequest) request; HttpServletResponse resp (HttpServletResponse) response; String uri req.getRequestURI(); String ctx req.getContextPath(); // 放行登录页与登录接口避免死循环 if (uri.endsWith(/login.jsp) || uri.endsWith(/login) || uri.endsWith(.css) || uri.endsWith(.js)) { chain.doFilter(request, response); return; } // 未登录一律跳回登录页 HttpSession session req.getSession(false); if (session null || session.getAttribute(loginUser) null) { resp.sendRedirect(ctx /jsp/common/login.jsp); return; } // 角色访问控制教师路径只能教师进 String role ((User) session.getAttribute(loginUser)).getRole(); if (uri.contains(/teacher/) !teacher.equals(role)) { resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } chain.doFilter(request, response); } }这里我把静态资源css、js和登录接口放行了否则会出现「登录页加载不出样式」的尴尬。注意我用了 req.getSession(false)这个重载方法在没有会话时返回 null而不是新建一个——这是一个经典的细节考点很多教科书示例用 getSession(true) 或 getSession()会在未登录用户访问时凭空创建 Session稍微增加服务端内存占用。参数说明/*表示拦截所有路径.endsWith判断在简单的 JSP 项目里够用如果用了更现代的路径风格可以改成uri.startsWith(/api/)这类前缀判断。答辩时如果老师问「Filter 和 Interceptor 有什么区别」直接说「Filter 是 Servlet 规范中的组件基于方法回调在 Web 容器层面生效Interceptor 是 Spring MVC 的组件基于反射机制在 Handler 执行前后生效。我们这里用的是 Filter因为项目没有引入 Spring MVC」。3.2 试题与组卷模块教师端怎么用 JDBC 实现动态组装试题管理模块是网上考试系统的题库基础。教师端需要能增删改查试题、选择试题组成一份试卷。这里有个常见的实现分歧组卷时是「复制题目」还是「引用题目」。我在数据库设计里用了 t_paper_question 关联表组卷的本质就是往关联表里插记录题目本体只存一份。组卷的 SQL 核心是查询可选题目public ListQuestion findQuestionsByCourse(int courseId) { String sql SELECT * FROM t_question WHERE course_id ?; // 使用 PreparedStatement 防止 SQL 注入 ListQuestion list new ArrayList(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, courseId); try (ResultSet rs ps.executeQuery()) { while (rs.next()) { Question q new Question(); q.setId(rs.getInt(id)); q.setType(rs.getInt(type)); q.setContent(rs.getString(content)); q.setOptions(rs.getString(options)); q.setAnswer(rs.getString(answer)); q.setScore(rs.getInt(score)); list.add(q); } } } catch (SQLException e) { e.printStackTrace(); } return list; }这段代码用了 try-with-resourcesJava 7 以后的推荐写法能自动关闭 Connection、Statement、ResultSet。我在好几份报告里看到同学的 DAO 层是手动 close 的Connection 漏关导致连接池耗尽是常见的翻车事故。答辩时主动说出「用 try-with-resources 确保资源释放」是一个不起眼但加分的小点。组卷时还有一个容易忽略的问题试卷时长和总分要与题目的分值匹配。比如老师选了 20 道单选题每题 5 分总分就是 100 分但如果老师选了 30 道题总分就是 150 分学生端显示的成绩会非常奇怪。我一般在组卷界面加一个实时统计「当前已选题目数 / 当前总分」教师调整选题时前端算一次后端保存时再校验一次两层保险。3.3 在线答题与会话内暂存学生端怎么处理半小时的答题过程学生参加在线考试时最怕的是答题中途页面刷新、Session 过期、或者跳转到别的页面填好的答案全没了。大作业级别不用上 Redis用 Session 暂存答案即可。答题页的提交逻辑建议用 AJAX 定时同步到 Session而不是等学生点「交卷」时才一次性提交。我见过最惨的翻车现场是学生做了一半误触浏览器刷新JSP 页面重载后所有 radio 全变回未选中学生当场崩溃。为了给答辩演示时留出容错我一般这样设计每次选项变更时调一个接口把答案存进 Session 的 Map 中。WebServlet(/api/saveAnswer) public class SaveAnswerServlet extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { HttpSession session req.getSession(); User student (User) session.getAttribute(loginUser); if (student null) { resp.setStatus(401); return; } String paperId req.getParameter(paperId); String questionId req.getParameter(questionId); String answer req.getParameter(answer); // 以 试卷-题号 为 key 暂存避免多份试卷互相覆盖 MapString, String answerMap (MapString, String) session.getAttribute(answerMap_ paperId); if (answerMap null) { answerMap new HashMap(); session.setAttribute(answerMap_ paperId, answerMap); } answerMap.put(questionId, answer); resp.getWriter().write(OK); } }参数说明answerMap 的 key 是 paperId避免学生同时打开两份试卷时答案串台。提交瞬间把这个 key 对应的 Map 拿出来逐题判分判完就删除防止重复提交。自动判分的逻辑其实非常简单纯后端遍历一遍即可public int gradePaper(MapString, String answers, ListQuestion questions) { int totalScore 0; for (Question q : questions) { String studentAnswer answers.get(String.valueOf(q.getId())); if (q.getAnswer().equals(studentAnswer)) { totalScore q.getScore(); } } return totalScore; }这里有个隐藏的坑选择题的答案需要处理空格和大小写。有些学生输入时带了个空格或者把 A 写成 a判分时直接比对失败。比较稳妥的做法是比对前对学生答案做 trim()多选答案先用 split(,) 拆开各自 trim 再排序最后 join 起来和标准答案比对。这些细节写进报告的「系统测试」里老师会觉得你想得周到。3.4 成绩查询与导出一张结果页怎么兼容三个角色成绩查询的逻辑在不同角色眼里长得不一样。学生要看自己历次考试的成绩教师要看某份试卷全班学生的成绩管理员可能要看系统整体的考试记录。如果你为每个角色各写一个页面重复代码会很多。更好的做法是后端统一查 t_exam_record 表前端按照当前登录的角色决定显示哪些列。比如学生端隐藏「学号」列显示「分数」列教师端显示学号和分数管理员端额外显示考试时间。用 JSP 在渲染时判断一下 session 里的登录角色比写三个 Servlet 再维护三套转发路径清爽得多。答辩时经常被追问的一个问题「查询成绩时怎么防止学生看到别人的成绩」标准答案是查询时 WHERE 条件强制带 student_id 当前登录人。我看到有同学把 student_id 放在 JSP 的隐藏表单里学生把页面源码改掉就能查别人成绩这是经典的安全翻车。正确做法是从 Session 里取当前登录学生的 id不回显、不传递后端只认 Session 里的值。4. 设计报告怎么写从需求分析到测试章节的完整骨架4.1 报告整体结构与字数分布八章以内解决战斗JavaEE 大作业的设计报告常见要求是 8000 到 12000 字包含需求分析、概要设计、详细设计、系统实现、测试与分析几个固定章节。当你手里已经有一套能跑的代码时报告反而好写因为每个小节都是在描述你已经实现的东西不存在编不出来的情况。我建议的章节骨架是第一章引言选题背景、开发环境第二章需求分析角色分析、用例图、功能需求与非功能需求第三章概要设计架构图、功能模块划分第四章数据库设计E-R 图、表结构说明第五章详细设计核心类、时序图、关键方法第六章系统实现界面截图核心代码片段第七章系统测试测试用例表、问题修复记录第八章总结与展望。八章刚好卡在「完整但不过度膨胀」的位置。这里有个容易犯的错误把代码整段贴进报告。报告里的代码应该是「核心方法 注释」而不是整个 DAO 类三页纸贴进去。我一般只贴 3 到 4 段代码登录校验、判分逻辑、组卷查询、过滤器。每段代码后面接 200 到 300 字的说明讲「为什么这么写、解决了什么问题」老师看了印象分自然会高。字数的分配比例也很关键。很多同学需求分析写 3000 字到系统测试只剩 500 字头重脚轻。我一般按 2:1:1:1:1.5 的比例分配到需求、设计、实现、测试、总结保证测试章节有足够的用例表可以撑篇幅。4.2 核心图表怎么画用例图、E-R 图、时序图一个都不能少设计报告不能只有文字尤其中间三章要配图。我见过最夸张的翻车是把一张网上随便找的架构图里的「XXX 系统」名字都没改就交了这属于学术诚信问题红线绝对不能碰。所有图都应该根据自己的代码结构补其实不难画。用例图推荐画三个角色分开的学生用例图登录、参加考试、查看成绩、教师用例图登录、管理题库、组卷、查看成绩分布、管理员用例图登录、用户管理。画在一个图里也行但三个角色分开画在报告里排版更好看。E-R 图的实体关系要和你实际建的表完全一致。很多同学报告里画了四张表代码里建了六张表答辩时老师一翻代码发现对不上直接印象分打折。E-R 图的实体用矩形属性用椭圆关系用菱形标准的符号体系不用创新画对就是满分。时序图我推荐画「学生在线答题」这一条主线学生提交答案 → Servlet 接收 → 调用 Service 判分 → 查询题库 → 返回成绩 → 展示结果页。一条主线的时序图画起来容易老师也能一眼看懂系统最核心的流程。4.3 测试章节怎么编黑盒用例表与 Bug 记录的真实写法测试章节是大作业报告里最容易被忽视、也最容易出彩的部分。黑盒测试用例表的标准字段是用例编号、测试功能、操作步骤、预期结果、实际结果、是否通过。你可以对照自己的代码写 10 到 15 条用例覆盖登录、角色权限、试题增删改查、在线答题、交卷判分、异常输入几条主干路径。Bug 记录表的格式也简单模块、现象描述、原因分析、解决方案。这里我建议写真实的 Bug因为答辩时老师如果追问真实经历比编的更容易讲圆。比如「Filter 放行路径写错导致 CSS 加载失败」就是一个既有说服力又有技术含量的 Bug 记录现象是登录页样式丢失原因是 AuthFilter 拦截了 .css 后缀解决是在放行条件里补充结尾判断。这种级别的 Bug 修复记录放进报告里比写十个「系统运行良好」强得多。另外报告里最好附带使用说明章节的对应内容。资源包里一般有独立的 README 或使用说明文档报告的附录里可以引用它。这样构成「正文 附录」的双层结构正文讲设计附录讲部署使用说明文档单独成一个文件老师翻起来也方便。5. 避坑与排查部署环境、数据库中文字符、Session 失效三大翻车现场5.1 Tomcat 启动闪退多半是端口冲突或环境变量不对现象启动 Tomcat 后控制台窗口一闪而过访问 localhost:8080 没反应。原因常见有两种一是 Tomcat 端口 8080 被其他程序占用比如某个本地服务占着不放二是 JDK 环境变量没配好Tomcat 的启动脚本找不到 java 命令启动脚本直接退出。还有一种是 Web 应用部署包里 web.xml 写错了XML 解析失败会导致整个 Context 启动失败但 Tomcat 本身不闪退需要看日志。解决步骤我一般是这样先排查端口命令行执行netstat -ano | findstr 8080看到 PID 后确认占用进程或改 Tomcat 的 server.xml 端口。再排查环境变量确认echo %JAVA_HOME%能输出 JDK 安装路径java -version能正常执行。最后打开 Tomcat 的 logs/catalina.out 或 Windows 下的日志文件看具体异常。提示资源包里的使用说明通常会写清 JDK 版本与 Tomcat 版本匹配关系。JDK 8 对应 Tomcat 8.5 或 9.0 都比较保险别用新 Tomcat 跑旧版 JDK 编译的代码Class version 不兼容异常很烦。5.2 数据库中文字符全变问号连接串字符集没到位现象页面正常显示中文但往数据库里插入中文数据后表里变成一排问号。从 MySQL 客户端手动插入中文也是乱码但直接修改表中字符集为 utf8mb4 后插入恢复正常。原因MySQL 连接层字符集和表字符集不一致。JDBC 连接串里如果没有指定编码参数驱动会使用 MySQL 服务端的默认字符集很可能和表的 utf8mb4 对不上。解决改 JDBC URL统一加参数jdbc.urljdbc:mysql://localhost:3306/exam_db?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai参数说明useUnicodetrue 告诉驱动启用 Unicode 映射characterEncodingutf8 指定客户端发送字节的编码serverTimezoneAsia/Shanghai 是 MySQL 8.0 时代驱动的要求不加会报时区错误。建表时统一DEFAULT CHARSETutf8mb4JDBC 用 utf8 指向同一个意思两者对齐后中文字符基本不会再出问题。如果改完还是乱码看 MySQL 服务端全局变量SHOW VARIABLES LIKE character_set%;确认 character_set_server、character_set_database 都是 utf8mb4。老版本 MySQL 安装时默认 latin1改掉这个全局变量后再重启服务才能彻底解决。5.3 Session 丢失或登录态跨页面失效Cookie 路径与持久化问题现象学生登录成功后点「开始考试」跳到答题页结果答了两道题刷新一下页面就被 Filter 弹回登录页了。或者教师登录后点了「试题管理」打开新标签页就掉线。原因登录成功的 Session 在服务器端是正常存在的但浏览器的 JSESSIONID Cookie 丢失了。常见原因是 Tomcat 的 Context 路径默认关联了 Cookie 的 path如果系统部署在 exam 子路径而某些转发或重定向用了绝对路径写死到根路径Cookie 就对应不上了。解决跳转时统一用req.getContextPath() /jsp/...不要写死/jsp/...。登录页面如果用相对路径也从req.getContextPath()拼出来。另外把 Tomcat 的 Cookie 配置改成 HttpOnly既能减少脚本窃取风险也避免前端 JS 误操作 Session Cookie。排查方法浏览器开发者工具 → Application → Cookies 里看 JSESSIONID 的 Path 列如果 Path 是根路径一般没问题如果 Path 是子路径而你访问的是另一段路径就说明路径没拼对。也可以在 Filter 里临时加一行日志打印 Session ID对比刷新前后是否变化——变了就是新 Session说明旧的丢了。5.4 判分结果莫名偏低多选答案比对没做排序和去空格现象学生考完看成绩单选题全对多选题却大面积扣分明明自己选的答案和标准答案看起来一样。原因判断题型是答案字段里存的是字符串。学生的答案存在 Session Map 里也是字符串。单选题答案是 A学生选 A字符串相等的。但多选题标准答案存的是「A,C」学生在页面上勾选时提交顺序可能是 C,A保存进 Map 后变成 C,A与 A,C 不相等判分就错了。解决在保存答案前或判分时对多选题答案做规范化处理。我在前面判分代码里提到过这里给出具体实现public static String normalizeMultiAnswer(String raw) { if (raw null || raw.trim().isEmpty()) { return ; } String[] parts raw.split(,); for (int i 0; i parts.length; i) { parts[i] parts[i].trim().toUpperCase(); } Arrays.sort(parts); return String.join(,, parts); }比对时两边都走normalizeMultiAnswer然后再 equals。判断题答案建议统一为「T/F」或者「正确/错误」关键是和学生端的 radio 取值一致。我见过有人标准答案存「true」前端 radio 的 value 是「T」全场题目全判错这就是前后端约定不一致埋的雷。5.5 部署时 JSP 报错 500Java 版本与 web.xml 头不匹配现象Tomcat 能启动登录页也能打开但一点「提交」就报 500日志里提示Unsupported major.minor version。原因Unsupported major.minor version的本质是 class 文件的字节码版本高于 JVM 支持的版本。比如你用新版本 JDK 编译的 Servlet 代码扔到配置了旧版本 JDK 的 Tomcat 里跑JVM 直接拒绝加载。解决统一 JDK 版本。编译环境和运行环境都用同一大版本的 JDK开发工具的 project structure 里的 SDK 和 Tomcat 运行时 JRE 都指到同一个路径。另外检查 web.xml 的头部版本Servlet 3.1 对应 Tomcat 8.5 以上如果 web.xml 里写的版本比 Tomcat 支持的高也会报错。大作业项目用 Servlet 3.1 Tomcat 8.5 JDK 8 这套组合基本不会出兼容性问题。注意我在多次复现资源包时发现市面上不少网上考试系统项目是用旧版本容器写的直接拿到新环境跑web.xml 头不匹配就会报错。这时把 web.xml 里根元素的版本号改成 3.1并删除旧的 DTD 声明用 Schema 风格的头就能正常加载。6. 让系统答辩时更出彩演示脚本与预置数据设计答辩时老师往往只有五分钟到十分钟浏览你的系统你要在这段时间里让老师看到三个能力系统完整性、代码清晰度、测试充分性。我自己的习惯是写一份「演示脚本」把操作路径固定下来每一步预计多少秒都标注好。演示脚本我按角色拆成三段。第一段用管理员账号登录展示用户管理把教师账号禁用再启用老师能直观看到账号状态变化。第二段切换教师账号先进入题库管理新增一道题然后组卷把刚才加进去的题选进试卷发布考试。第三段切换学生账号参加刚才教师发布的考试故意做错一道题和一道多选提交后展示成绩页的判分明细。三段走完系统三个角色的核心功能全部覆盖时间控制在五分钟内。预置数据的细节也很重要。试卷名称不要用「试卷1」「试卷2」这种占位符要起「《JavaEE 程序设计》期中考试」这种有场景感的名字。试题内容也不要搞「题目1」这种空壳我一般预置十道真实的计算机基础题比如「HTTP 状态码 404 表示什么」「JDBC 中 PreparedStatement 相比 Statement 的优势是什么」。真实题目有两个好处演示时不会被老师看出是瞎填的而且报告测试章节可以直接用这些题目做预期结果。我做完这个小系统后最大的教训是永远在答辩前重新导入一遍 SQL 脚本重新编译一遍整个项目不要带着开发过程中残留的旧数据去演示。那次经历之后我每次拿到类似大作业资源第一步一定是先删掉原本的数据库用脚本重建再把预置账号一一验证一遍——确保第一次点开就能跑通。这个习惯帮我避开了至少三次「演示现场表结构不匹配」的尴尬。希望这篇拆解能帮你把网上考试系统这个大作业稳稳落地无论是代码、报告还是使用说明都能变成你自己讲得清楚的东西。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站