Article

Java Servlets - Part 2

Page: 1 2 3 4 5 Next

A Practical Example: An Online Quiz

A common element on the Web is the multiple-choice question. It can be used in a survey to poll your users for their opinion, or in an educational setting for an online exam; uses for this type of application are many and varied. To solidify the concepts demonstrated in this article, we'll develop a Servlet that displays a multiple-choice question and then informs the user if their selection was correct. We'll use our newly-found form handling skills to check their answer, and we'll use initialization parameters to set the question, the four answers available, and the correct one.

First, let's start by creating a Servlet that asks a particular question. Once that's working we'll adapt it to get the question and answers from initialization parameters. This first version of our quiz Servlet won't actually be that different from the last example in our section on form handling. Instead of a form prompting for the user's name, we'll display the question and four radio buttons for the possible answers. That form, as in the personalized greeting example, will be submitted right back to the same Servlet, which will detect the presence of the request parameter (the selected answer, in this case) and will check if the value corresponds to the correct answer. Here's the code:

import java.io.*;    
import javax.servlet.*;    
import javax.servlet.http.*;    
   
public class QuizServlet extends HttpServlet {    
   
 public void doGet(HttpServletRequest req, HttpServletResponse rsp)    
               throws ServletException, IOException {    
   rsp.setContentType("text/html");    
   PrintWriter out = rsp.getWriter();    
   
   String answer = req.getParameter("answer");    
   String correct = "C";    
   
   out.println("<html>");    
   out.println("<head><title> Online Quiz </title></head>");    
   out.println("<body>");    
   
   if (answer == null) {    
     StringBuffer action = HttpUtils.getRequestURL(req);    
   
     out.println("<form action=\"" + action + "\" method=\"POST\">\n");    
     out.println("<p><b>Question:</b> What is WORA?</p>");    
     out.println("<p><input type=\"radio\" name=\"answer\" " +    
                 "value=\"A\" /> Wear Only Reinforced Acryllic<br />");    
     out.println("   <input type=\"radio\" name=\"answer\" " +    
                 "value=\"B\" /> Where Old Rhinos Assemble<br />");    
     out.println("   <input type=\"radio\" name=\"answer\" " +    
                 "value=\"C\" /> Write Once Run Anywhere<br />");    
     out.println("   <input type=\"radio\" name=\"answer\" " +    
                 "value=\"D\" /> Walk Or Run Anywhere<br />");    
     out.println("   <input type=\"submit\" value=\"Submit\" /></p>");    
     out.println("</form>");    
   } else {    
     if (answer.equals(correct))    
       out.println("<p><b>YES!</b> That's the right answer!</p>");    
     else    
       out.println("<p><b>Sorry.</b> That's the wrong answer.</p>");    
   }    
   
   out.println("</body></html>");    
 }    
   
 public void doPost(HttpServletRequest req, HttpServletResponse rsp)    
               throws ServletException, IOException {    
   doGet(req,rsp);    
 }    
}

Now, this is all well and good, but we want to be able to use this Servlet for more than this single question. To do this, we'll take the question, answers, and the correct answer out of the code and instead use initialization parameters to set them. The question will come from the question parameter, the answers will be answerA, answerB, answerC, and answerD, while the letter indicating the correct answer will be set by the correct parameter. All of these parameters are read into property variables of the same name in the Servlet's init method:

 public void init() throws ServletException {    
   question = getInitParameter("question");    
   answerA  = getInitParameter("answerA");    
   answerB  = getInitParameter("answerB");    
   answerC  = getInitParameter("answerC");    
   answerD  = getInitParameter("answerD");    
   correct  = getInitParameter("correct");    
   if (question == null || answerA == null || answerB == null ||    
       answerC == null || answerD == null || correct == null) {    
     throw new ServletException("Missing required init parameter(s)!");    
   }    
 }

At the end of the init method, you'll notice a rather sizeable if statement. It checks if any of the initialization parameters are missing (and therefore null), using the OR (||) operator to check all the parameters with a single if statement. It can be read aloud "if question is null OR answerA is null OR ...". If any of the required parameters are deemed missing, we throw a ServletException. ServletException is a Java class like any other, so to create an Object of the class we type new followed by the name of the class. ServletException lets us give a reason for the error by passing a string to the constructor, which is exactly what we do above. Finally, the throw keyword indicates that we want to stop execution of the method at that point and pass the error (the ServletException Object) up to whatever code called the method in the first place (in this case, part of the Web server). The Web server would then handle it by displaying an error page in the user's Web browser in response to any request.

With the parameters loaded, the updated code for producing the form is fairly strightforward:

     out.println("<form action=\"" + action + "\" method=\"POST\">\n");    
     out.println("<p><b>Question:</b> " + question + "</p>");    
     out.println("<p><input type=\"radio\" name=\"answer\" " +    
                 "value=\"A\" /> " + answerA + "<br />");    
     out.println("   <input type=\"radio\" name=\"answer\" " +    
                 "value=\"B\" /> " + answerB + "<br />");    
     out.println("   <input type=\"radio\" name=\"answer\" " +    
                 "value=\"C\" /> " + answerC + "<br />");    
     out.println("   <input type=\"radio\" name=\"answer\" " +    
                 "value=\"D\" /> " + answerD + "<br />");    
     out.println("   <input type=\"submit\" value=\"Submit\" /></p>");    
     out.println("</form>");

That's really all there is to it! Here's the complete code for our QuizServlet class (QuizServlet.java):

import java.io.*;    
import javax.servlet.*;    
import javax.servlet.http.*;    
   
public class QuizServlet extends HttpServlet {    
   
 String question, answerA, answerB, answerC, answerD, correct;    
   
 public void init() throws ServletException {    
   question = getInitParameter("question");    
   answerA  = getInitParameter("answerA");    
   answerB  = getInitParameter("answerB");    
   answerC  = getInitParameter("answerC");    
   answerD  = getInitParameter("answerD");    
   correct  = getInitParameter("correct");    
   if (question == null || answerA == null || answerB == null ||    
       answerC == null || answerD == null || correct == null) {    
     throw new ServletException("Missing required init parameter(s)!");    
   }    
 }    
   
 public void doGet(HttpServletRequest req, HttpServletResponse rsp)    
               throws ServletException, IOException {    
   rsp.setContentType("text/html");    
   PrintWriter out = rsp.getWriter();    
   
   String answer = req.getParameter("answer");    
   
   out.println("<html>");    
   out.println("<head><title> Online Quiz </title></head>");    
   out.println("<body>");    
   
   if (answer == null) {    
     StringBuffer action = HttpUtils.getRequestURL(req);    
   
     out.println("<form action=\"" + action + "\" method=\"POST\">\n");    
     out.println("<p><b>Question:</b> " + question + "</p>");    
     out.println("<p><input type=\"radio\" name=\"answer\" " +    
                 "value=\"A\" /> " + answerA + "<br />");    
     out.println("   <input type=\"radio\" name=\"answer\" " +    
                 "value=\"B\" /> " + answerB + "<br />");    
     out.println("   <input type=\"radio\" name=\"answer\" " +    
                 "value=\"C\" /> " + answerC + "<br />");    
     out.println("   <input type=\"radio\" name=\"answer\" " +    
                 "value=\"D\" /> " + answerD + "<br />");    
     out.println("   <input type=\"submit\" value=\"Submit\" /></p>");    
     out.println("</form>");    
   } else {    
     if (answer.equals(correct))    
       out.println("<p><b>YES!</b> That's the right answer!</p>");    
     else    
       out.println("<p><b>Sorry.</b> That's the wrong answer.</p>");    
   }    
   
   out.println("</body></html>");    
 }    
   
 public void doPost(HttpServletRequest req, HttpServletResponse rsp)    
               throws ServletException, IOException {    
   doGet(req,rsp);    
 }    
   
}

If you compile (QuizServlet.class) and deploy this Servlet without specifying any initialization parameters, you'll see what happens when a Servlet throws a ServletException in its init method:

The result of a ServletExceptionAs you can see, an error page is displayed showing the ServletException, the reason for the error (Missing required init parameter(s)!), and the location in the code where the error occured.

To avoid this unsightly error, let's add the required parameters to web.xml. Here's the code you can add for this Servlet (feel free to use your own question and answers):

 <servlet>    
   <servlet-name>    
     quiz    
   </servlet-name>    
   <servlet-class>    
     QuizServlet    
   </servlet-class>    
   <init-param>    
     <param-name>question</param-name>    
     <param-value>What is WORA?</param-value>    
   </init-param>    
   <init-param>    
     <param-name>answerA</param-name>    
     <param-value>Wear Only Reinforced Acryllic</param-value>    
   </init-param>    
   <init-param>    
     <param-name>answerB</param-name>    
     <param-value>Where Old Rhinos Assemble</param-value>    
   </init-param>    
   <init-param>    
     <param-name>answerC</param-name>    
     <param-value>Write Once Run Anywhere</param-value>    
   </init-param>    
   <init-param>    
     <param-name>answerD</param-name>    
     <param-value>Walk Or Run Anywhere</param-value>    
   </init-param>    
   <init-param>    
     <param-name>correct</param-name>    
     <param-value>C</param-value>    
   </init-param>    
 </servlet>

Now load the Servlet again (remember to use the <servlet-name> you assigned in web.xml, or it won't see the init parameters you just added), and you should see the quiz question appear:

The completed QuizServlet in action

If you liked this article, share the love:
Print-Friendly Version Suggest an Article