You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Servlet和JSP的在线Quiz开发:如何获取用户选中的答题选项

解决Servlet/JSP在线Quiz的选项获取与结果存储问题

看起来你现在卡在两个核心问题上:单页展示题目时拿不到用户选中的选项,还有之前尝试分页展示题目没成功。我来一步步帮你理清思路、解决问题。

一、当前单页Quiz的核心错误分析

你的代码里有几个关键问题直接导致无法获取用户选项:

  1. 重复生成<form>标签:在while循环里每输出一道题就生成一个表单,这会让HTML结构无效,浏览器只会识别最后一个表单,前面的选项根本不在提交范围内。
  2. Radio组name重复:所有题目的单选框都用了name="answer",这会把所有选项归为同一组,用户只能选一个选项,而不是每个题目独立选择。
  3. 获取参数时机错误:你在生成题目的Servlet里尝试request.getParameter("answer"),但此时用户还没提交表单,这个参数根本不存在——应该在处理提交的Results.jsp或者专门的结果Servlet里获取。

二、修正单页Quiz的代码实现

1. 调整Servlet的表单生成逻辑

把<form>标签移到循环外面,确保整个页面只有一个表单;给每个题目的单选框组设置唯一的name(比如answer_${i}),同时把题目和正确答案存入session时,和这个序号一一对应。

修改后的Servlet doPost 方法:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    String url = "jdbc:mysql://127.0.0.1:3306/Quiz"; 
    String username1="root"; 
    String password1="root"; 
    PrintWriter out= response.getWriter(); 
    PreparedStatement st = null; 
    ResultSet results = null; 
    int limit=3; 
    HttpSession session = request.getSession(); // 确保获取session对象

    try { 
        Class.forName("com.mysql.jdbc.Driver"); 
        Connection con= DriverManager.getConnection(url,username1,password1); 
        String sql="SELECT Questions.Question, Questions.option1, Questions.option2,Questions.option3, Questions.option4,Questions.correctanswer FROM Questions order by RAND() limit ?"; 
        st = con.prepareStatement(sql); 
        st.setInt(1,limit); 
        results = st.executeQuery(); 

        // 先输出页面头部和表单开始标签
        out.println("<HTML><BODY BGCOLOR='powderblue'>");
        out.println("<FORM method='post' action='Results.jsp'>");
        out.println("<TABLE BORDER = 2 CELLPADDING = 4 CELLSPACING = 2>");
        out.println("<TR><TD COLSPAN = 6 ALIGN = CENTER><H2><B>Quick Quiz</B></H2></TD></TR>");

        int i=1; 
        while (results.next()) { 
            String question = results.getString(1); 
            String opt1 = results.getString(2); 
            String opt2 = results.getString(3); 
            String opt3 = results.getString(4); 
            String opt4 = results.getString(5); 
            String correctAns = results.getString(6); 

            // 输出带序号的题目
            out.println("<TR><TD>" + i + ". " + question + "</TD></TR>");
            // 输出选项,单选框name用answer_+序号,确保每组独立
            out.println("<TR><TD><input type='radio' name='answer_" + i + "' value='1' required> " + opt1 + "</TD></TR>");
            out.println("<TR><TD><input type='radio' name='answer_" + i + "' value='2'> " + opt2 + "</TD></TR>");
            out.println("<TR><TD><input type='radio' name='answer_" + i + "' value='3'> " + opt3 + "</TD></TR>");
            out.println("<TR><TD><input type='radio' name='answer_" + i + "' value='4'> " + opt4 + "</TD></TR>");
            out.println("<TR><TD>&nbsp;</TD></TR>"); // 空行分隔题目

            // 将题目和正确答案存入session,用序号区分
            session.setAttribute("question_" + i, question);
            session.setAttribute("correct_answer_" + i, correctAns);
            i++; 
        } 

        // 输出提交按钮和页面收尾标签
        out.println("</TABLE>");
        out.println("<BR><BR><INPUT type='submit' value='Press to Submit'></FORM></BODY></HTML>" ); 

        results.close(); 
        st.close(); 
        con.close(); 
    } catch (ClassNotFoundException e) { 
        e.printStackTrace(); 
    } catch (SQLException e) { 
        e.printStackTrace(); 
    } 
}

2. 在Results.jsp中处理提交并存储结果

现在在结果页面,你可以获取每个题目的选中选项,对比正确答案,然后把结果存入数据库。示例代码如下:

<%@ page import="java.sql.*" %>
<%@ page import="javax.servlet.http.HttpSession" %>
<html>
<body>
    <h2>Quiz Results</h2>
    <%
        HttpSession session = request.getSession();
        int totalQuestions = 3;
        int score = 0;
        // 这里替换成实际的用户名,比如用户登录后存入session的用户名
        String username = "test_user"; 

        // 数据库连接信息
        String url = "jdbc:mysql://127.0.0.1:3306/Quiz";
        String dbUser = "root";
        String dbPass = "root";
        Connection con = null;
        PreparedStatement stmt = null;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection(url, dbUser, dbPass);
            // 假设你有一个quiz_results表,字段:username, question, user_answer, is_correct
            String insertSql = "INSERT INTO quiz_results (username, question, user_answer, is_correct) VALUES (?, ?, ?, ?)";
            stmt = con.prepareStatement(insertSql);

            for(int i=1; i<=totalQuestions; i++){
                String question = (String)session.getAttribute("question_" + i);
                String correctAns = (String)session.getAttribute("correct_answer_" + i);
                String userAns = request.getParameter("answer_" + i);

                boolean isCorrect = correctAns.equals(userAns);
                if(isCorrect) score++;

                // 插入结果到数据库
                stmt.setString(1, username);
                stmt.setString(2, question);
                stmt.setString(3, userAns);
                stmt.setBoolean(4, isCorrect);
                stmt.executeUpdate();

                // 展示每题结果
                out.println("<p>" + i + ". " + question + "<br>");
                out.println("Your answer: Option " + userAns + "<br>");
                out.println("Correct answer: Option " + correctAns + "<br>");
                out.println(isCorrect ? "<span style='color:green'>Correct!</span>" : "<span style='color:red'>Incorrect!</span></p>");
            }

            out.println("<h3>Total Score: " + score + "/" + totalQuestions + "</h3>");

        } catch(Exception e){
            e.printStackTrace();
        } finally {
            if(stmt != null) stmt.close();
            if(con != null) con.close();
            // 清理session中的临时数据
            for(int i=1; i<=totalQuestions; i++){
                session.removeAttribute("question_" + i);
                session.removeAttribute("correct_answer_" + i);
            }
        }
    %>
</body>
</html>

三、可选:实现分页式Quiz(单页一题+Next按钮)

如果你想回到分页的思路,这里给你一个简单的实现方向:

  1. 初始化题目列表:第一次访问Servlet时,从数据库获取随机题目,存入session(比如session.setAttribute("all_questions", 题目列表)),同时记录当前题目索引session.setAttribute("current_index", 0)。
  2. 处理答题提交:用户点击Next时,提交当前题目的答案,存入session(比如session.setAttribute("answer_" + currentIndex, userAns)),然后索引+1。
  3. 判断是否完结:如果还有下一题,展示新题目;如果没有,跳转到结果页面计算得分并存储。

核心逻辑示例(需要先创建Question实体类封装题目信息):

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    HttpSession session = request.getSession();
    List<Question> allQuestions = (List<Question>)session.getAttribute("all_questions");
    Integer currentIndex = (Integer)session.getAttribute("current_index");

    // 第一次请求,初始化题目列表
    if(allQuestions == null){
        // 从数据库查询随机题目,封装成Question对象存入列表
        // ... 这里写数据库查询逻辑
        session.setAttribute("all_questions", allQuestions);
        currentIndex = 0;
        session.setAttribute("current_index", currentIndex);
    } else {
        // 保存当前题目的答案
        String userAns = request.getParameter("current_answer");
        session.setAttribute("answer_" + currentIndex, userAns);
        currentIndex++;
        session.setAttribute("current_index", currentIndex);
    }

    // 判断是否还有题目
    if(currentIndex < allQuestions.size()){
        // 展示当前题目
        Question currentQ = allQuestions.get(currentIndex);
        PrintWriter out = response.getWriter();
        out.println("<HTML><BODY BGCOLOR='powderblue'>");
        out.println("<FORM method='post' action='QuizServlet'>");
        out.println("<h2>Question " + (currentIndex+1) + "/" + allQuestions.size() + "</h2>");
        out.println("<p>" + currentQ.getQuestion() + "</p>");
        out.println("<p><input type='radio' name='current_answer' value='1' required> " + currentQ.getOpt1() + "</p>");
        out.println("<p><input type='radio' name='current_answer' value='2'> " + currentQ.getOpt2() + "</p>");
        out.println("<p><input type='radio' name='current_answer' value='3'> " + currentQ.getOpt3() + "</p>");
        out.println("<p><input type='radio' name='current_answer' value='4'> " + currentQ.getOpt4() + "</p>");
        out.println("<input type='submit' value='Next'>");
        out.println("</FORM></BODY></HTML>");
    } else {
        // 所有题目答完,跳转到结果页面
        response.sendRedirect("Results.jsp");
    }
}

总结

先把单页版本的表单结构和单选框name修正,确保每个题目的选项组独立,然后在结果页面正确获取参数并存储。如果想做分页,核心是用session维护题目列表和答题进度,逐步处理每个题目的提交。

内容的提问来源于stack exchange,提问作者Anonymous6

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:23:35