基于Spring MVC实现标准化在线考试系统
基于Spring MVC实现标准化在线考试系统
一、项目介绍
本次项目是一个C语言单选题在线测试系统,整体流程:
- 用户进入考试页面(
exam.jsp),完成5道单选题。 - 提交表单后,由Spring MVC控制器接收答案。
- 控制器自动判分,把结果传给结果页面。
- 结果页面(
result.jsp)显示最终得分。
技术栈:
- 后端:Spring MVC
- 视图:JSP + HTML + CSS + JavaScript
- 服务器:Tomcat 8
- 环境:JDK 1.8
二、项目结构
WebContent
├── WEB-INF
│ ├── web.xml
│ ├── myspringmvc-servlet.xml
│ └── classes
│ └── com/exam/controller
│ └── ExamController.class
├── exam.jsp
├── result.jsp
└── View.jsp
三、核心配置(web.xml)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>springmvc</display-name>
<welcome-file-list>
<welcome-file>exam.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>myspringmvc</servlet-name>
<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>
四、考试页面(exam.jsp)
提供5道单选题,带简单美化和提交前非空校验:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>C语言标准化测试</title>
<style>
body {
font-family: 'Microsoft YaHei', Arial, sans-serif;
background: #f0f2f5;
margin: 0;
padding: 20px;
}
.container {
max-width: 900px;
margin: 0 auto;
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 0 20px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
color: #2c3e6e;
border-bottom: 3px solid #2c3e6e;
padding-bottom: 15px;
}
.subtitle {
text-align: center;
color: #666;
font-size: 14px;
margin-bottom: 30px;
}
.question {
margin: 25px 0;
padding: 15px 20px;
background: #f9f9f9;
border-radius: 10px;
border-left: 5px solid #2c3e6e;
}
.question-title {
font-weight: bold;
font-size: 16px;
color: #333;
margin-bottom: 12px;
}
.option {
margin: 8px 0 8px 25px;
}
.option input {
margin-right: 8px;
cursor: pointer;
}
.option label {
cursor: pointer;
color: #555;
}
.submit-btn {
text-align: center;
margin-top: 30px;
}
.submit-btn input {
background: #2c3e6e;
color: white;
border: none;
padding: 12px 45px;
font-size: 16px;
border-radius: 30px;
cursor: pointer;
font-weight: bold;
transition: background 0.3s;
}
.submit-btn input:hover {
background: #1a2a4a;
}
.footer {
text-align: center;
margin-top: 25px;
color: #999;
font-size: 12px;
}
</style>
</head>
<body>
<div class="container">
<h1>C语言标准化测试</h1>
<div class="subtitle">共5道单选题,每题20分,满分100分</div>
<!-- 关键:这里必须写成 exam.do 匹配你的控制器 -->
<form action="../exam.do" method="post">
<!-- 第1题 -->
<div class="question">
<div class="question-title">1. C语言程序是由______构成的。</div>
<div class="option">
<input type="radio" name="q1" value="A" id="q1_a">
<label for="q1_a">A. 一些可执行语言</label>
</div>
<div class="option">
<input type="radio" name="q1" value="B" id="q1_b">
<label for="q1_b">B. main函数</label>
</div>
<div class="option">
<input type="radio" name="q1" value="C" id="q1_c">
<label for="q1_c">C. 函数</label>
</div>
<div class="option">
<input type="radio" name="q1" value="D" id="q1_d">
<label for="q1_d">D. 包含文件中的第一个函数</label>
</div>
</div>
<!-- 第2题 -->
<div class="question">
<div class="question-title">2. ______是构成C语言程序的基本单位。</div>
<div class="option">
<input type="radio" name="q2" value="A" id="q2_a">
<label for="q2_a">A. 函数</label>
</div>
<div class="option">
<input type="radio" name="q2" value="B" id="q2_b">
<label for="q2_b">B. 过程</label>
</div>
<div class="option">
<input type="radio" name="q2" value="C" id="q2_c">
<label for="q2_c">C. 子程序</label>
</div>
<div class="option">
<input type="radio" name="q2" value="D" id="q2_d">
<label for="q2_d">D. 子例程</label>
</div>
</div>
<!-- 第3题 -->
<div class="question">
<div class="question-title">3. C语言可执行程序从______开始执行。</div>
<div class="option">
<input type="radio" name="q3" value="A" id="q3_a">
<label for="q3_a">A. 程序中第一条可执行语句</label>
</div>
<div class="option">
<input type="radio" name="q3" value="B" id="q3_b">
<label for="q3_b">B. 程序中第一个函数</label>
</div>
<div class="option">
<input type="radio" name="q3" value="C" id="q3_c">
<label for="q3_c">C. 程序的main函数</label>
</div>
<div class="option">
<input type="radio" name="q3" value="D" id="q3_d">
<label for="q3_d">D. 包含文件中的第一个函数</label>
</div>
</div>
<!-- 第4题 -->
<div class="question">
<div class="question-title">4. C语言程序从main()函数开始执行,所以这个函数要写在______。</div>
<div class="option">
<input type="radio" name="q4" value="A" id="q4_a">
<label for="q4_a">A. 程序文件的开始</label>
</div>
<div class="option">
<input type="radio" name="q4" value="B" id="q4_b">
<label for="q4_b">B. 程序文件的最后</label>
</div>
<div class="option">
<input type="radio" name="q4" value="C" id="q4_c">
<label for="q4_c">C. 它所调用的函数的前面</label>
</div>
<div class="option">
<input type="radio" name="q4" value="D" id="q4_d">
<label for="q4_d">D. 程序文件的任何位置</label>
</div>
</div>
<!-- 第5题 -->
<div class="question">
<div class="question-title">5. 以下说法中正确的是______。</div>
<div class="option">
<input type="radio" name="q5" value="A" id="q5_a">
<label for="q5_a">A. C语言程序总是从第一个定义的函数开始执行</label>
</div>
<div class="option">
<input type="radio" name="q5" value="B" id="q5_b">
<label for="q5_b">B. 在C语言程序中,要调用的函数必须在main()函数中定义</label>
</div>
<div class="option">
<input type="radio" name="q5" value="C" id="q5_c">
<label for="q5_c">C. C语言程序总是从main()函数开始执行</label>
</div>
<div class="option">
<input type="radio" name="q5" value="D" id="q5_d">
<label for="q5_d">D. C语言程序中的main()函数必须放在程序的开始部分</label>
</div>
</div>
<div class="submit-btn">
<input type="submit" value="提交试卷">
</div>
<div class="footer">
请认真作答,每道题只有一个正确答案
</div>
</form>
</div>
<script>
document.querySelector("form").addEventListener("submit", function(e) {
var q1 = document.querySelector('input[name="q1"]:checked');
var q2 = document.querySelector('input[name="q2"]:checked');
var q3 = document.querySelector('input[name="q3"]:checked');
var q4 = document.querySelector('input[name="q4"]:checked');
var q5 = document.querySelector('input[name="q5"]:checked');
if(!q1 || !q2 || !q3 || !q4 || !q5) {
e.preventDefault();
alert("请完成所有题目后再提交!");
}
});
</script>
</body>
</html>
五、控制器(ExamController.java)
接收答案、自动判分、转发到结果页:
package com.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class ExamController {
// 正确答案:5道题的标准答案
private final String[] correctAnswers = {"C", "A", "C", "D", "C"};
// 只改这一行:@PostMapping → @RequestMapping(..., method = RequestMethod.POST)
@RequestMapping(value = "/submitExam", method = RequestMethod.POST)
public String submitExam(
@RequestParam("q1") String q1,
@RequestParam("q2") String q2,
@RequestParam("q3") String q3,
@RequestParam("q4") String q4,
@RequestParam("q5") String q5,
Model model) {
// 1. 把用户答案存入数组
String[] userAnswers = {q1, q2, q3, q4, q5};
// 2. 评分算法:对比正确答案,计算分数
int score = 0;
for (int i = 0; i < correctAnswers.length; i++) {
if (userAnswers[i].equals(correctAnswers[i])) {
score += 20; // 每题20分
}
}
// 3. 封装结果信息(传给result.jsp)
String msg = "考试完成!\n你的得分:" + score + "分";
if(score == 100) {
msg += "\n太棒了,满分通过!";
} else if(score >= 60) {
msg += "\n成绩合格!";
} else {
msg += "\n不合格,请继续努力!";
}
// 4. 把数据放入model,前端可直接用${info}显示
model.addAttribute("info", msg);
// 5. 跳转到 result.jsp
return "result";
}
}
六、结果页面(result.jsp)
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>考试评分结果</title>
</head>
<body>
<h2>考试评分结果</h2>
<p>总分:${score} 分</p>
<p>答对题数:${correct} 题</p>
<p>答错题数:${error} 题</p>
</body>
</html>
七、运行效果
-
打开
exam.jsp→ 显示5道C语言选择题。
![image]()
-
全部做完后提交 → 后端自动判分。
-
跳转到
result.jsp→ 显示分数(满分100)。
![image]()
八、实验心得
这次实验让我完整走了一遍Spring MVC + JSP的请求流程:
Request:前端把答案传给后端。Controller:处理业务逻辑、判分。Model:把结果数据传给视图。Response:返回结果页面给用户。


浙公网安备 33010602011771号