JavaWeb-05-JSP规范-07-在线考试管理系统-考试管理模块
JavaWeb-05-JSP规范-07-在线考试管理系统-考试管理模块
本次工程文件:点击下载
提取码:jmjh
用户信息管理模块传送门:用户信息管理
试题信息管理模块传送门:试题信息管理
1.任务
考试管理模块
实现功能:
- 随机出题:考生点击【参加考试】,系统【随机】为其分配四道考试题。
- 自动改卷:考生点击【交卷】,系统自动计算分数并展示。
2.功能实现1:随机出题
2.1流程图
2.2随机sql语句
2.2.1所有试题
2.2.2根据不同字段排序,截取的结果不同
当根据一张表中不同字段进行排序时,截取前4条记录的顺序通常都不一样
SELECT * FROM t_question ORDER BY questionId DESC LIMIT 0,4;
SELECT * FROM t_question ORDER BY subject DESC LIMIT 0,4;
SELECT * FROM t_question ORDER BY optionA DESC LIMIT 0,4;
2.2.3使用数字表示字段
在一张表中,可以用数字来表示字段
SELECT * FROM t_question ORDER BY questionId DESC LIMIT 0,4;
SELECT * FROM t_question ORDER BY 1 DESC LIMIT 0,4;#代表第一个字段questionId
SELECT * FROM t_question ORDER BY subject DESC LIMIT 0,4;
SELECT * FROM t_question ORDER BY 2 DESC LIMIT 0,4;#代表第二个字段subject
SELECT * FROM t_question ORDER BY optionA DESC LIMIT 0,4;
SELECT * FROM t_question ORDER BY 3 DESC LIMIT 0,4;#代表第三个字段optionA
2.2.4利用rand()随机函数实现随机查询
rand()随机函数可以生成[0,1]之间的随机小数
在MySQL中,当rand()位于order by 后面时,生成的[0,1]之间的随机小数就会转换为[1,10]之间的随机整数。(当数字超过字段长度时会自动归1)
利用这一点,可以实现随机查询四道试题。
select * from t_question order by rand() limit 0,4;
2.3在导航页添加考试相关按钮
在left.html文件中添加考试相关超链接
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>left</title>
</head>
<body>
<ul>
<li>用户信息管理
<ol>
<li><a href="/MyWeb/user_add.html" target="right">用户信息注册</a></li>
<li><a href="/MyWeb/user/find" target="right">用户信息查询</a></li>
</ol>
</li>
<li>试题信息管理
<ol>
<li><a href="/MyWeb/question_add.html" target="right">试题信息添加</a></li>
<li><a href="/MyWeb/question/find" target="right">试题信息查询</a></li>
</ol>
</li>
<li>考试管理
<ol>
<li><a href="/MyWeb/question/rand" target="right">参加考试</a></li>
<li><a href="/MyWeb/question/find" target="right">试题信息查询</a></li>
</ol>
</li>
</ul>
</body>
</html>
2.4编写QuestionRandServlet
1.调用Dao对象从t_question表中获取随机的四道题目
2.将四道题目写入当前会话作用域对象中
3.通过请求转发向Tomcat申请调用exam.jsp文件,将题目写入响应体
package com.tsccg.controller;
import com.tsccg.dao.QuestionDao;
import com.tsccg.entity.Question;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: TSCCG
* @Date: 2021/08/26 14:36
*/
public class QuestionRandServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Question> randList = new ArrayList<>();
//1.调用Dao对象从question表中获取随机的四道题目
QuestionDao dao = new QuestionDao();
randList = dao.findRand();
//2.将四道题目写入当前会话作用域对象中
HttpSession session = request.getSession(false);//除登陆外,其他所有地方都要用getSession(false)
session.setAttribute("randList",randList);
//3.通过请求转发向Tomcat申请调用exam.jsp文件,将题目写入响应体
request.getRequestDispatcher("/exam.jsp").forward(request,response);
}
}
2.5在QuestionDao中添加随机查询试题方法
package com.tsccg.dao;
import com.tsccg.entity.Question;
import com.tsccg.util.JdbcUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: TSCCG
* @Date: 2021/08/23 23:32
* 通过jdbc连接数据库,对t_question表中数据进行操作
*/
public class QuestionDao {
/**
* 1.添加试题信息
* @param question 需要添加的试题信息
* @return 返回添加结果,成功返回true,失败返回false
*/
public boolean questionAdd(Question question) {}
/**
* 2.查询全部试题信息
* @return 返回存放试题信息的List集合
*/
public List<Question> findAll() {}
/**
* 3.根据试题编号删除试题信息
* @param questionId 试题编号
* @return 返回执行结果
*/
public boolean delete(Integer questionId) {}
/**
* 4.根据试题编号查询试题信息
* @param questionId 试题编号
* @return 返回查询出的试题信息
*/
public Question findById(Integer questionId) {}
/**
* 5.更新试题信息
* @param question 新的试题信息
* @return 返回更新结果
*/
public boolean questionUpdate(Question question) { }
/**
* 6.随机查询四道试题信息
* @return 返回查询到的四道试题信息
*/
public List<Question> findRand() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Question> questionList = new ArrayList<>();
try {
conn = JdbcUtil.connect();
String sql = "select * from t_question order by rand() limit 0,4;";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
Integer questionId = rs.getInt("questionId");
String subject = rs.getString("subject");
String optionA = rs.getString("optionA");
String optionB = rs.getString("optionB");
String optionC = rs.getString("optionC");
String optionD = rs.getString("optionD");
String answer = rs.getString("answer");
Question question = new Question(questionId,subject,optionA,optionB,optionC,optionD,answer);
questionList.add(question);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtil.closeAll(conn,ps,rs);
}
return questionList;
}
}
2.6将查到的四道试题写入响应体【exam.jsp】
<%@ page import="com.tsccg.entity.Question" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>开始考试</title>
</head>
<body>
<center>
<form action="/MyWeb/exam">
<table border="1" cellpadding="0" cellspacing="0">
<tr>
<th>题目编号</th>
<th>题目描述</th>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>答案</th>
</tr>
<!-- 从会话作用域对象中读取查询到的四道题目 -->
<%
List<Question> questionList = (List)session.getAttribute("randList");
for (Question question : questionList) {
%>
<tr>
<td><%=question.getQuestionId()%></td>
<td><%=question.getSubject()%></td>
<td><%=question.getOptionA()%></td>
<td><%=question.getOptionB()%></td>
<td><%=question.getOptionC()%></td>
<td><%=question.getOptionD()%></td>
<td>
<input type="radio" name="answer<%=question.getQuestionId()%>" value="A">A
<input type="radio" name="answer<%=question.getQuestionId()%>" value="B">B
<input type="radio" name="answer<%=question.getQuestionId()%>" value="C">C
<input type="radio" name="answer<%=question.getQuestionId()%>" value="D">D
</td>
</tr>
<%
}
%>
<tr>
<td>
<input type="submit" value="交卷">
<input type="reset" value="重做">
</td>
</tr>
</table>
</form>
</center>
</body>
</html>
注意:在选择答案处,如果所有raido类型的input标签的name都一样,那么最终只能选择一项。
为了避免这种情况,需要为每题答案处的name属性加上该题的编号
<td>
<input type="radio" name="answer<%=question.getQuestionId()%>" value="A">A
<input type="radio" name="answer<%=question.getQuestionId()%>" value="B">B
<input type="radio" name="answer<%=question.getQuestionId()%>" value="C">C
<input type="radio" name="answer<%=question.getQuestionId()%>" value="D">D
</td>
2.7测试随机出题功能
3.功能实现2:自动改卷
3.1流程图
3.2编写ExamServlet
1.从会话作用域对象中获取考试的四道题目
2.从请求包中获取考生提交答案
3.计分
4.将总分数写入请求作用域对象
5.请求转发调用info.jsp
package com.tsccg.controller;
import com.tsccg.entity.Question;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
/**
* @Author: TSCCG
* @Date: 2021/08/26 16:25
*/
public class ExamServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.从会话作用域对象中获取考试的四道题目
HttpSession session = request.getSession(false);//除登陆外,其他所有地方都要用getSession(false)
List<Question> questionList = (List)session.getAttribute("randList");
//2.计分
int result = 0;//定义总分数
for(Question question:questionList) {
//获取当前题目考生提交答案
String subAnswer = request.getParameter("answer" + question.getQuestionId());
//判断正确答案与考生提交答案是否一致
if(question.getAnswer().equals(subAnswer)) {
//每答对一道题加25分
result += 25;
}
}
//3.将总分数写入请求作用域对象
request.setAttribute("result",result+"分");
//4.请求转发调用info.jsp
request.getRequestDispatcher("info.jsp").forward(request,response);
}
}
3.3改写info.jsp
使用EL表达式来获取请求作用域中的信息
<%@ page import="static java.awt.SystemColor.info" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>结果</title>
</head>
<body>
<center>
<%--展示处理信息--%>
<font style="font-size: 30px" color="red">${result}</font>
</center>
</body>
</html>