【web考试系统的设计】

一、实验背景与目的

本次实验旨在深入理解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 {
	@Override
	protected 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 传参,如今都变成了脑海中清晰的流程图。或许,这就是实践的力量:让抽象的概念,落地成可运行的代码,最终内化为解决问题的能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值