一、实验背景与目的
本次实验旨在深入理解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语言程序是由(  )构成的。</p>
<input type="radio" name="1" value="A">A) 一些可执行的语言 
<input type="radio" name="1" value="B">B) main函数 
<input type="radio" name="1" value="C">C) 函数 
<input type="radio" name="1" value="D">D) 包含文件中的第一个函数 
<p>2.(  )是构成C语言程序的基本单位。</p>
<input type="radio" name="2" value="A">A) 函数 
<input type="radio" name="2" value="B">B) 过程 
<input type="radio" name="2" value="C">C) 子程序 
<input type="radio" name="2" value="D">D) 子例程 
<p>3.C语言可执行程序从(  )开始执行。</p>
<input type="radio" name="3" value="A">A) 程序中第一条可执行语句 
<input type="radio" name="3" value="B">B) 程序中第一个函数&emsp
<p>4.C语言程序从main( )函数开始执行,所以这个函数要写在(  )。</p>
<input type="radio" name="4" value="A">A) 程序文件的开始 
<input type="radio" name="4" value="B">B) 程序文件的最后 
<input type="radio" name="4" value="C">C) 它调用的函数的前面 
<input type="radio" name="4" value="D">D) 程序文件的任何位置 
<p>5.以下说法中正确的是(  )。</p>
<input type="radio" name="5" value="A">A) C语言程序总是从第一个定义的函数开始执行 
<input type="radio" name="5" value="B">B) 在C语言程序中,要调用的函数必须在main( )函数中定义 
<p>
<input type="radio" name="5" value="C">C) C语言程序总是从main( )函数开始执行  
<input type="radio" name="5" value="D">D) C语言程序中的main( )函数必须放在程序的开始部分 
<p>
  
<input type="reset" name="reset" value="重置"/>
  
<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显示成绩页面。
- 遇到的问题
- 前端表单
在设计 5 道单选题时,我一度将 radio 的 name 统一写成 “question”,导致后端只能获取最后一个题的答案。调试时发现request.getParameter(“1”)返回 null,才惊觉每个题的 name 必须唯一(如 “1”、“2”)。这个细节让我明白:前端表单的 name 属性是后端数据提取的 “钥匙”,必须与业务逻辑一一对应。 - 逻辑漏洞
当用户未选任何答案直接提交时,request.getParameter(“1”)返回 null,与预设的 “C” 比较导致空指针。通过添加key1 == null ? “未选” : key1的防御性判断,最终在 grade.jsp 显示 “0 分” 而非报错。这教会我:永远假设用户输入是 “恶意” 的,后端必须做好参数校验。
这次实验让我告别 “纸上谈兵”,真正体会到 Web 开发是 “带着镣铐跳舞”—— 既要遵守 HTTP 协议的规则,又要在框架约束中实现创意。那些曾让我头疼的 web.xml 配置、ModelAndView 传参,如今都变成了脑海中清晰的流程图。或许,这就是实践的力量:让抽象的概念,落地成可运行的代码,最终内化为解决问题的能力。