当前位置: 首页 > news >正文

【web考试系统的设计】

文章目录

    • 一、实验背景与目的
    • 二、实验设计与实现思路
      • 1. 功能架构
      • 2. 核心代码实现
    • 总结

一、实验背景与目的

本次实验旨在深入理解Request、response对象的作用,Request对象的作用是与客户端交互,收集客户端的Form、Cookies、超链接,或者收集服务器端的环境变量。客户端可通过表单或在网页地址后面提供参数的方法提交数据,然后服务器通过Servlet控制器获得request对象封装的这些数据,经过逻辑运算后利用Response对象发送信息给用户,完成对客户端的动态响应,掌握基于Servlet的动态Web工程框架的搭建,熟悉Request、Response等内置对象在JSP编程中的运用

二、实验设计与实现思路

1. 功能架构

(1)考试页面(test.jsp)
表单结构:
5 道单选题采用,每个题目设置唯一name属性(如 “1”、“2”),确保后端能精准获取对应答案。
提交按钮绑定action=“test.do”,指定请求路径为 Spring MVC 映射的控制器。
用户体验:
题干使用 空格符优化排版,确保选项对齐;重置按钮type="reset"方便用户重新答题。
(2)评分页面(grade.jsp)
动态渲染:通过 EL 表达式${score}直接获取控制器传递的分数,避免 Java 代码嵌入页面,保持视图纯净。
样式优化:使用 CSS 类.center居中显示分数,红色加粗字体突出成绩,提升视觉反馈。

2. 核心代码实现

(1)web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"><display-name>test8</display-name><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><servlet><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class></servlet><servlet-mapping><servlet-name>myspringmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>
</web-app>

(2)Servlet逻辑

package com.jmu.controller;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;public class Controller1 extends AbstractController {@Overrideprotected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {String key1 = request.getParameter("1");String key2 = request.getParameter("2");String key3 = request.getParameter("3");String key4 = request.getParameter("4");String key5 = request.getParameter("5");String rightkey1 = "C";String rightkey2 = "A";String rightkey3 = "C";String rightkey4 = "D";String rightkey5 = "C";int score = 0;if (rightkey1.equals(key1)) {score+=20;}if (rightkey2.equals(key2)) {score+=20;}if (rightkey3.equals(key3)) {score+=20;}if (rightkey4.equals(key4)) {score+=20;}if (rightkey5.equals(key5)) {score+=20;}ModelAndView modelAndView=new ModelAndView("grade");modelAndView.addObject("score", score);return modelAndView;}}

(3)JSP页面
1.test.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试页面</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="test.do"><h2>C语言标准化测试</h2><p>1.C语言程序是由(&emsp; )构成的。</p><input type="radio" name="1" value="A">A) 一些可执行的语言&emsp;<input type="radio" name="1" value="B">B) main函数&emsp;<input type="radio" name="1" value="C">C) 函数&emsp;<input type="radio" name="1" value="D">D) 包含文件中的第一个函数&emsp;<p>2.(&emsp; )是构成C语言程序的基本单位。</p><input type="radio" name="2" value="A">A) 函数&emsp;<input type="radio" name="2" value="B">B) 过程&emsp;<input type="radio" name="2" value="C">C) 子程序&emsp;<input type="radio" name="2" value="D">D) 子例程&emsp;<p>3.C语言可执行程序从(&emsp; )开始执行。</p><input type="radio" name="3" value="A">A) 程序中第一条可执行语句&emsp;<input type="radio" name="3" value="B">B) 程序中第一个函数&emsp<p>4.C语言程序从main(&nbsp;)函数开始执行,所以这个函数要写在(&emsp; )。</p><input type="radio" name="4" value="A">A) 程序文件的开始&emsp;<input type="radio" name="4" value="B">B) 程序文件的最后&emsp;<input type="radio" name="4" value="C">C) 它调用的函数的前面&emsp;<input type="radio" name="4" value="D">D) 程序文件的任何位置&emsp;<p>5.以下说法中正确的是(&emsp; )。</p><input type="radio" name="5" value="A">A) C语言程序总是从第一个定义的函数开始执行&emsp;<input type="radio" name="5" value="B">B) 在C语言程序中,要调用的函数必须在main(&nbsp; )函数中定义&emsp;<p><input type="radio" name="5" value="C">C) C语言程序总是从main(&nbsp; )函数开始执行&emsp;&emsp;<input type="radio" name="5" value="D">D) C语言程序中的main(&nbsp; )函数必须放在程序的开始部分&emsp;<p>&emsp;&emsp;<input type="reset" name="reset" value="重置"/>&emsp;&emsp;<input type="submit" name="submit" value="提交"/>
</form>
</body>
</html>

2.grade.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>成绩页面</title>
<style>.center {text-align: center;}
</style>
</head>
<body>
<tr><td class="center"><h1 style="color:red;">您本次C语言测试成绩是:${score}分</h1></td>
</tr>
</table>
</body>
</html>

总结

本次实验结果符合预期,当我们选中选项时,后端会进行判断,并进行分数的累加。

最后i显示成绩页面。
在这里插入图片描述

  • 遇到的问题
  1. 前端表单
    在设计 5 道单选题时,我一度将 radio 的 name 统一写成 “question”,导致后端只能获取最后一个题的答案。调试时发现request.getParameter(“1”)返回 null,才惊觉每个题的 name 必须唯一(如 “1”、“2”)。这个细节让我明白:前端表单的 name 属性是后端数据提取的 “钥匙”,必须与业务逻辑一一对应。
  2. 逻辑漏洞
    当用户未选任何答案直接提交时,request.getParameter(“1”)返回 null,与预设的 “C” 比较导致空指针。通过添加key1 == null ? “未选” : key1的防御性判断,最终在 grade.jsp 显示 “0 分” 而非报错。这教会我:永远假设用户输入是 “恶意” 的,后端必须做好参数校验。

这次实验让我告别 “纸上谈兵”,真正体会到 Web 开发是 “带着镣铐跳舞”—— 既要遵守 HTTP 协议的规则,又要在框架约束中实现创意。那些曾让我头疼的 web.xml 配置、ModelAndView 传参,如今都变成了脑海中清晰的流程图。或许,这就是实践的力量:让抽象的概念,落地成可运行的代码,最终内化为解决问题的能力。

http://www.xdnf.cn/news/1621.html

相关文章:

  • 零服务器免备案!用Gitee代理+GitHub Pages搭建个人博客:绕过443端口封锁实战记录
  • 基于Flask的漏洞挖掘知识库系统设计与实现
  • 对抗生成进化:基于DNA算法的AIGC检测绕过——让AI创作真正“隐形“
  • 生物信息学技能树(Bioinformatics)与学习路径
  • 04-libVLC的视频播放器:获取媒体信息
  • 【裁员感想】
  • 关于webpack的知识点
  • 《似锦》:画饼之—你画给我我画给你
  • java 设计模式之代理模式
  • Android Compose Activity 页面跳转动画详解
  • 【Leetcode 每日一题】2176. 统计数组中相等且可以被整除的数对
  • ubuntu磁盘挂载
  • MySQL GTID集合运算函数总结
  • e实例性能测评:Intel Xeon Platinum处理器,经济型入门级服务器
  • Java设计开发商城抢票功能
  • Sql刷题日志(day3)
  • 代码随想录算法训练营第二十天
  • 关于C语言的模拟物理模型
  • vue3 el-dialog新增弹窗,不希望一进去就校验名称没有填写
  • SQL刷题记录贴
  • Oracle测试题目及笔记(单选)
  • 赛灵思 XCVU3P‑2FFVC1517I XilinxFPGA Virtex UltraScale+
  • AI在市场营销分析中的核心应用及价值,分场景详细说明
  • 【创新实训个人博客】前端实现
  • 【运维学习】lvs + keepalived + 主从dns 项目搭建
  • Valgrind的使用复习
  • 更换 CentOS 7.9 的系统源
  • 【软考-系统架构设计师】ATAM方法及效用树
  • 【python】pyCharm常用快捷键使用-(2)
  • C++入门基础:命名空间,缺省参数,函数重载,输入输出