Full Stack Web Development Internship Program
- 5k Enrolled Learners
- Weekend/Weekday
- Live Class
In this post we’ll cover the steps in creating an interactive online quiz application using JSP Servlet technology. We’ll look at how to parse XML files, how to handle sessions and keep track of user interaction using session management.
Below are some of the snapshots of the end application:
Before taking a quiz, a user have to first register and login. To register one can directly click on the register menu or a link to registration page is provided on the login page to create an account.
When a user clicks, an exam user is directly redirected to the login page, if the user is not logged in.
Home page is the landing page of the application from where a user can take any quiz by clicking on the quiz. On the home page, if the user is logged in his name is also shown and a logout link is provided to logout from the application.
On starting a quiz, a user is presented with the first question of the quiz with the next and finish button. Note that the previous button is not shown when the user is on first question and next button is not shown when the user is in the last question.
After clicking on the finish button the user is presented with exam results, showing the name of quiz; time when the quiz was started and the number of questions that the user answered correctly.
Well, it works as you expect it to work. To take a quiz, a user must be logged in. If the user is not logged in, the user will automatically be redirected to the login page, where the user can login. If the user is not already registered to the application, he has to create an account first. After successfully logging in to the application, the user can take any of the quiz by clicking on it. Now, the user will be presented with the first question of the quiz. To move through the quiz questions, the user is provided with the next and previous buttons. The quiz can be finished at any time by clicking on the finish button.
Let’s get started on building the application
Below is the snapshot of the project structure in Eclipse IDE.
Home page is pretty straightforward. We have a menu and 8 images displayed in a table format with two rows; each row containing 4 images. On the home page we also make a check, whether the user is logged in or not. If the user is logged in we also display the username and provide a logout link.
Creating Menu for Home Page
< div id='cssmenu'> < ul> < li class=''>< a href='${pageContext.request.contextPath}'>< span>Home< /span>< /a>< /li> < li>< a href='${pageContext.request.contextPath}/login'>< span>Login< /span>< /a>< /li> < li>< a href='${pageContext.request.contextPath}/register'>< span>Register< /span>< /a>< /li> < li class='#'>< a href='#'>< span>Submit a Question< /span>< /a>< /li> < li class='#'>< a href='#'>< span>Feedback< /span>< /a>< /li> < li>< a href='#'>< span>Contribute< /span>< /a>< /li> < li>< a href='#'>< span>Contact us< /span>< /a>< /li> < /ul> < /div>
Checking whether the user is logged in or not
< c:if test='${not empty sessionScope.user}'> < div style="position:absolute;top:70px;left:1100px"> Logged as < a href="#" class="button username">${sessionScope.user}< /a> < /div> < div style="position:absolute;top:70px;left:1300px"> < a href='${pageContext.request.contextPath}/logout'>Logout< /a> < /div> < /c:if>
Showing the quiz images on home page
< div style="position:absolute;left:120px;top:60px"> < table cellpadding="0" cellspacing="50"> < tr> < td>< a href="takeExam?test=java">< img height="200" width="200" src="${pageContext.request.contextPath}/images/java.png"/>< /a>< /td> < td>< a href="takeExam?test=javascript">< img height="200" width="200" src="${pageContext.request.contextPath}/images/javascript.png"/>< /a>< /td> < td>< a href="takeExam?test=sql">< img height="200" width="200" src="${pageContext.request.contextPath}/images/sql-logo.png"/>< /a>< /td> < td>< a href="takeExam?test=python">< img height="200" width="200" src="${pageContext.request.contextPath}/images/python.jpg"/>< /a>< /td> < /tr> < tr> < td>< a href="takeExam?test=css">< img height="200" width="200" src="${pageContext.request.contextPath}/images/css.jpg"/>< /a>< /td> < td>< a href="takeExam?test=php">< img height="200" width="200" src="${pageContext.request.contextPath}/images/php-logo.jpg"/>< /a>< /td> < td>< a href="takeExam?test=linux">< img height="200" width="200" src="${pageContext.request.contextPath}/images/logo-linux.png"/>< /a>< /td> < td>< a href="takeExam?test=mongodb">< img height="200" width="200" src="${pageContext.request.contextPath}/images/mongodb_logo.png"/>< /a>< /td> < /tr> < /table> < /div>
There is nothing fancy in the registration page; just an HTML form awaiting the user to provide his name, email and password. Once we get that, we pass this to RegistrationController servlet to create an account.
Note: We are not doing any validation like password should contain 8 characters with at least one uppercase character, one number and special symbol. We will do that in upcoming posts, when we extend this application.
Registration Code
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username=request.getParameter("username"); String email=request.getParameter("email"); String password=request.getParameter("password"); Connection con=DatabaseConnectionFactory.createConnection(); try { Statement st=con.createStatement(); String sql = "INSERT INTO users values ('"+username+"','"+password+"','"+email+"')"; System.out.println(sql); st.executeUpdate(sql); }catch(SQLException sqe){System.out.println("Error : While Inserting record in database");} try { con.close(); }catch(SQLException se){System.out.println("Error : While Closing Connection");} request.setAttribute("newUser",username); RequestDispatcher dispatcher=request.getRequestDispatcher("/WEB-INF/jsps/regSuccess.jsp"); dispatcher.forward(request, response); }
In this application we have used MySQL database to store user credentials. To get a connection to database we have defined a static method createConnection in DatabaseConnectionFactory class, where all database specific information is stored.
We have just users’ table under quiz database.
Users’ table
create table users(username varchar(50),email varchar(50),password varchar(50))
If you are working with some other database like Oracle you have to change the properties of the DatabaseConnectionFactory class accordingly.
DatabaseConnectionFactory.java
public class DatabaseConnectionFactory { private static String dbURL="jdbc:mysql://localhost/quiz"; private static String dbUser="root"; private static String dbPassword=""; public static Connection createConnection() { Connection con=null; try{ try { Class.forName("com.mysql.jdbc.Driver"); } catch(ClassNotFoundException ex) { System.out.println("Error: unable to load driver class!"); System.exit(1); } con = DriverManager.getConnection(dbURL,dbUser,dbPassword); } catch(SQLException sqe){ System.out.println("Error: While Creating connection to database");sqe.printStackTrace();} return con; } }
Login page is very much similar to registration page where we are providing two input fields asking user to provide a username and password. Once we get the username and password entered by the user we pass it to LoginController to authenticate user.
Login Validation Code
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username=request.getParameter("username"); String password=request.getParameter("password"); Connection con=DatabaseConnectionFactory.createConnection(); ResultSet set=null; int i=0; try { Statement st=con.createStatement(); String sql = "Select * from users where username='"+username+"' and password='"+password+"' "; System.out.println(sql); set=st.executeQuery(sql); while(set.next()) { i=1; } if(i!=0) { HttpSession session=request.getSession(); session.setAttribute("user",username); RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/jsps/home.jsp"); rd.forward(request, response); } else { request.setAttribute("errorMessage","Invalid username or password"); RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/jsps/login.jsp"); rd.forward(request, response); } }catch(SQLException sqe){System.out.println("Error : While Fetching records from database");} try { con.close(); }catch(SQLException se){System.out.println("Error : While Closing Connection");} }
It is the MainController where we have written the code to redirect the user to appropriate page according to the incoming request url.
@WebServlet(urlPatterns = { "/login", "/register", "/takeExam", "/logout" }) public class MainController extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String applicationContextPath = request.getContextPath(); if (request.getRequestURI().equals(applicationContextPath + "/")) { RequestDispatcher dispatcher = request .getRequestDispatcher("/WEB-INF/jsps/home.jsp"); dispatcher.forward(request, response); } else if (request.getRequestURI().equals( applicationContextPath + "/login")) { RequestDispatcher dispatcher = request .getRequestDispatcher("/WEB-INF/jsps/login.jsp"); dispatcher.forward(request, response); } else if (request.getRequestURI().equals( applicationContextPath + "/register")) { RequestDispatcher dispatcher = request .getRequestDispatcher("/WEB-INF/jsps/register.jsp"); dispatcher.forward(request, response); } else if (request.getRequestURI().equals( applicationContextPath + "/takeExam")) { request.getSession().setAttribute("currentExam", null); String exam = request.getParameter("test"); request.getSession().setAttribute("exam", exam); System.out.println(request.getSession().getAttribute("user")); if (request.getSession().getAttribute("user") == null) { request.getRequestDispatcher("/login").forward(request, response); } else { RequestDispatcher dispatcher = request .getRequestDispatcher("/WEB-INF/jsps/quizDetails.jsp"); dispatcher.forward(request, response); } } else if (request.getRequestURI().equals( applicationContextPath + "/logout")) { request.getSession().invalidate(); RequestDispatcher dispatcher = request .getRequestDispatcher("/WEB-INF/jsps/home.jsp"); dispatcher.forward(request, response); } } }
Once the user clicks on logout, link session is invalidated and all the objects bind in the session are removed.
request.getSession().invalidate();
Note that we have stored the questions in separate XML files, not in the database.
< quiz> < title>MongoDB Quiz (01/09/2015)< /title> < questions> < question> < quizquestion>MongoDB is a < /quizquestion> < answer>Relational Database< /answer> < answer>Object Relational Database< /answer> < answer>Graph Database< /answer> < answer>Document Database< /answer> < correct>3< /correct> < /question> < question> < quizquestion>What is the name of MongoDB server ?< /quizquestion> < answer>mongoserver< /answer> < answer>mongod< /answer> < answer>mongodb< /answer> < answer>mongo< /answer> < correct>1< /correct> < /question> < question> < quizquestion>What is the name of MongoDB client ?< /quizquestion> < answer>mongo< /answer> < answer>mongod< /answer> < answer>mongodb< /answer> < answer>mongo-client< /answer> < correct>0< /correct> < /question> < /questions> < /quiz>
To read the questions from the XML file we create a document that represents the XML file containing quiz questions. Whenever the user clicks on the next or previous button we call the setQuestion(int i) method, giving the index of question that we want to read and at the same time that question is saved in an ArrayList of QuizQuestion.
QuizQuestion is the class that represents a single quiz question; each question will have a number, question statement, options and one correct option index.
QuizQuestion.java
public class QuizQuestion { int questionNumber; String question; String questionOptions[]; int correctOptionIndex; public String getQuestion() { return question; } public int getQuestionNumber() { return questionNumber; } public void setQuestionNumber(int i) { questionNumber=i; } public int getCorrectOptionIndex() { return correctOptionIndex; } public String[] getQuestionOptions() { return questionOptions; } public void setQuestion(String s) { question=s; } public void setCorrectOptionIndex(int i) { correctOptionIndex=i; } public void setQuestionOptions(String[]s) { questionOptions=s; } }
Note that since this is a web application, multiple users will be taking exams simultaneously. We have to make sure that one user’s exam does not get into another user’s exam. For example, one user might have just started Java exam and another user is on question 5 of SQL exam; we have to treat them as two separate exams. To do that we will maintain the state of each exam using session.
When the user clicks on start exam button to start the exam, we will create a new instance of exam passing the test type for eg. Java, PHP, CSS etc. So each user will have a different instance of Exam class (that represents an individual exam).
Let’s see what is there in the exam class
public class Exam { Document dom; public int currentQuestion=0; public Map selections=new LinkedHashMap(); public ArrayList questionList = new ArrayList(10); public Exam(String test) throws SAXException,ParserConfigurationException,IOException, URISyntaxException{ dom=CreateDOM.getDOM(test); } // code }
Note that to track the current question in the exam we have currentQuestion property in exam class.
ExamController is the main control from where we control the exam. Here we save user selections (what user have answered for the question) in a Map. ExamController also lets user move through questions by clicking next and previous button, at the back end it is the ExamController which makes the function calls to retrieve questions and store user responses.
When the user clicks on finish button, ExamController calls the calculateResult() method passing the Exam object, calculateResult() compares user responses with correct option for the question and returns how many correct answers a user got.
public int calculateResult(Exam exam){ int totalCorrect=0; Map<Integer,Integer> userSelectionsMap=exam.selections; List userSelectionsList=new ArrayList(10); for (Map.Entry<Integer, Integer> entry :userSelectionsMap.entrySet()) { userSelectionsList.add(entry.getValue()); } List questionList=exam.questionList; List correctAnswersList=new ArrayList(10); for(QuizQuestion question: questionList){ correctAnswersList.add(question.getCorrectOptionIndex()); } for(int i=0;i<selections.size();i++){ System.out.println(userSelectionsList.get(i)+" --- "+correctAnswersList.get(i)); if((userSelectionsList.get(i)-1)==correctAnswersList.get(i)){ totalCorrect++; } } System.out.println("You Got "+totalCorrect+" Correct"); return totalCorrect; }
Note that until now each of our question has 4 options and there is no timer for the quiz. In the upcoming posts we are going to extend this online quiz application and will include the following functionalities :
1. Each quiz can have different number of questions
2. Each question can have different number of options
3. A question can have multiple correct options
4. Implementing a timer for the quiz
5. Maintaining a history of the user; like how many tests a user have taken in the past and his score
6. Randomizing the order of questions presented to the user
7. Giving the user option to review his answers before submitting the test for evaluation
8. A dropdown box to jump to any question in between the test rather then clicking next button multiple times.
As always you can download the code, change it as you like. That’s the best way to understand the code. If you have any question or suggestion please comment below.
Click on the Download button to download the code.
[buttonleads form_title=”Download Code” redirect_url=https://edureka.wistia.com/medias/akdu7ycjex/download?media_file_id=65416744 course_id=44 button_text=”Download Code”]
Got a question for us? Please mention it in the comments section and we will get back to you.
Related Posts:
Creating Online Quiz Application Part 2 – Implementing Countdown Timer
Creating Online Quiz Application Part 3 – Quiz Review Functionality
Course Name | Date | |
---|---|---|
Java Certification Training Course | Class Starts on 28th January,2023 28th January SAT&SUN (Weekend Batch) | View Details |
Java Certification Training Course | Class Starts on 25th February,2023 25th February SAT&SUN (Weekend Batch) | View Details |
edureka.co
sir where is the checkregister.jsp file
hello!!!! I want to know takeExam?test=java what does it mean as you are giving link to images??
Hi, thanks for checking out our blog. TakeExam is a part of URI , means its a part of resource link and test=java is nothing but a parameter with some value java, now see this block of MainController
if (request.getRequestURI().equals(
applicationContextPath + “/takeExam”)) {
request.getSession().setAttribute(“currentExam”, null);
String exam = request.getParameter(“test”);
request.getSession().setAttribute(“exam”, exam);
System.out.println(request.getSession().getAttribute(“user”));
if (request.getSession().getAttribute(“user”) == null) {
request.getRequestDispatcher(“/login”).forward(request,
response);
} else {
RequestDispatcher dispatcher = request
.getRequestDispatcher(“/WEB-INF/jsps/quizDetails.jsp”);
dispatcher.forward(request, response);
}
}
In the above code first of all its checking whether the URI is upto /takeExam or not then it is getting dispatched to the quizDetails.jsp URI, there the value of session variable exam for example java is being used as
Instruction for ${sessionScope.exam} Quiz :
Start Exam
Now notice in the above line the URI exam.jsp is being invoked when the button is clicked, which it taking exam of subjects(for example in our case java).
Hope this helps. Cheers!
is there any link for the source code of this program?
Hi Vikram,
You can get in touch with us for source code related queries and any further clarification by contacting our sales team on +91-8880862004 (India) or 1800 275 9730 (US toll free). You can mail us on [email protected].
https://edureka.wistia.com/medias/akdu7ycjex/download?media_file_id=65416744 course_id=32 button_text
type it in browser as url ..you wll get source code
thanks for the source code…. can you please share how to run this project?
if you have eclipse and tomcat or jBoss server…you will be easily able to run it..
i have eclipse and tomcat as well,,,but wen i try to run home.jsp…it shows requested resource not available..could you help..pleaseeeeeeeee
Thanks,I got answers of my questions,It helped me in understanding concepts of web annotations and controller class.Now I have configured home page of quiz with my application but it is getting difficult for me to understand exam and exam controller class.can u please help me by explaining them in detail that how exaclty is the flow of there execution.
Let’s first go through Exam class
Each Exam is represented by Exam.java which has the following properties:
Document dom (which keeps a reference to DOM object for the quiz file, say the user clicked on Java quiz then this dom will refer to Dom object for java-quiz-1.xml)
int currentQuestion – which is used to keep track on the current question that is presented to the user
int totalNumberOfQuestions – this field is used to store the number of
questions in a particular quiz (remember each quiz can have different
number of questions)
int quizDuration – as its name suggests this field store the time limit for the particular quiz
Mapselections – this map stores the user’s answer for questions, that is needed to evaluate the result of quiz when the user finishes the quiz ListquizSelectionsList – this field is just used to make it easy to retrieve the user’s answer in a List as it gets a bit hard to traverse through Map
ArrayListquestionList – questionList field stores the list of QuizQuestions (
remember each QuizQuestion have its own properties
int questionNumber; // number of question
String question; //question itself
String questionOptions; // options for the question
int correctOptionIndex; // correct option for the question
int userSelected=-1; // what the user selected for the question default value is -1, as the user can click on next to skip to the next question which means the user didn’t answer that question
)
Apart from getters/setters in Exam.java two important methods are setQuestion()and calculateResult()
setQuestion() is called by ExamController to set the question (in the user’s session) whenever the user clicks on next or the previous button
calculateResult() is called by the ExamController to evaluate the quiz when the user clicks on the finish button
ExamController class is the main class which manages the exam.
Note that the question form in exam.jsp uses POST method(verb) to send data to ExamController servlet so all the logic is in doPost method.
When the user clicks on the start exam button to start exam, we set a newly created Exam object into the user’s session to keep track of the user’s activity throughout the entire exam. We also set the remaining time left in the user’s session and update it when the user answers a question.
We also check for which option the user has selected a question and save it to Exam.selections Map.
On clicking the next button, we set the next question by calling Exam.setQuestion(). Similarly, on clicking the previous button, we set the previous question by calling Exam.setQuestion()
Exam can be finished in two ways, one way is by explicitly pressing the finish button and the other way is no time left.
In both the cases, we call Exam.calculateResult() to evaluate the exam and show the response on result.jsp page
Please go through the post:
https://www.edureka.co/blog/creating-an-online-quiz-application-using-jsp-servlet/
This will be help you understand better.
Thanks alot,you explained it very well now i am able to understand its execution flow and working
But i Still have some doubts.
I have attached a image this is a screenshot of exam.jsp,I want to know from where you are fetching this questionNumber which is highlighted.
From where you are fetching values in these lines
session.quest.questionNumber
session.quest.question
session.quest.questionOption
and QuizQuestion Class is used as setters and getters,In exam.jsp you are Setting all the values but I am not able to understand where you are using these values you are not calling any get() methods.
I have to create a web page for a online exam which will display same questions in different sequence for each user and i want to create only one page for all questions and question will display one by one randomly in that page for each users. and i want to disable reload button what should be the code ?
Hi Sangram ,
To show the same set of questions in different order you need to just randomize the order in which questions are shown.
In this quiz application we have used an ArrayList of QuizQuestion , to randomize the sequence in which questions are retrieved. We can just use the shuffle method to randomize the order of of questions in that ArrayList.
We will be coming up with a post on how to randomize the question sequence and how to make the current application an adaptive quiz. An adaptive quiz gets harder and easier based on the answer given to the previous question.
If you answer a question correct, you get a tougher question and if you answer a question wrong the next question becomes easier.
Hi
I want to know about MainControllerServlet,Can you explain how it is getting path from browser uri and where we are setting this path to call particular jsp?
Where are we using url as “home” defined in web.xml and who is calling MainControllerServlet.?
Hi Udit, we have made one entry in web.xml for welcome file which maps url (http://localhost:8080/OnlineQuiz/) to MainController.
home
home
co.edureka.quiz.controller.MainController
home
/home
In addition to (http://localhost:8080/OnlineQuiz/) MainController also handles the following incoming urls
http://localhost:8080/OnlineQuiz/login
http://localhost:8080/OnlineQuiz/register
http://localhost:8080/OnlineQuiz/takeExam
http://localhost:8080/OnlineQuiz/logout
According to incoming request url MainController redirects to appropriate JSP page. To make it more clear here is the description; when you run the application servlet container sees welcome file entry home , then it looks for servlet named home. And MainController have the name as home so it directs the request to MainController which sees the request uri and gives home.jsp
The same thing can be achieved in many different ways. One way could be, you can make a separate servlet(HomeController) which will handle only http://localhost:8080/OnlineQuiz/ url
Hope this helps!!
Hi,
I am having a problem with a execution flow of Quiz Application,as I want to Combine this application with my college project I want to redirect its main page on a click of button and then want its execution continues,can we do this with out MainControllerServlet if yes then please Explain how..?
Hi Udit ,to merge your project with quiz application you have to modify some code. As I understand you want to show home page of Quiz Application when a link from your other project is clicked. One simplest way could be giving a hyperlink on your other project like:
Take Exam
On clicking above link it will take you to home page of quiz.
When’ll we get the updated version of this application.???????????????
Hi Jay,
Please go through the second post here: https://www.edureka.co/blog/creating-an-online-quiz-application-implementing-countdown-timer/ ,where we have added Quiz Timer to the application. We have also added Quiz review functionality here: https://www.edureka.co/blog/online-quiz-application-quiz-review/ , where users can review their answer after submitting the quiz. Soon we will be extending the application so that users can download their exam report as a PDF.
why the exam link doesn’t navigate to the questions how can i link xml file in href?
Hi Malini, hope you liked the post.
Coming to your question, we are setting questions in the user’s session here. We are storing all the quiz questions in an ArrayList of QuizQuestion when the user starts a quiz.
So, if the user clicks on the next button, we increment the quiz question count and fetch that question from the arraylist.
Similarly, when the user clicks on the previous button, we decrement the quiz question and fetch that question
Here is the code from ExamController:
if(“Next”.equals(action)){
exam.currentQuestion++;
exam.setQuestion(exam.
QuizQuestion
q=exam.questionList.get(exam.
session.setAttribute(“quest”,
}
else
if(“Previous”.equals(action))
{
exam.currentQuestion–;
exam.setQuestion(exam.
QuizQuestion
q=exam.questionList.get(exam.
session.setAttribute(“quest”,
}
That is why the exam link remains the same and everything happens through session attributes.
I didn’t understand your second question ” How can I link XML file in href ”
I think you are trying to ask how URLs like /exam?question=1 and /exam?question=2 can be used to fetch the quiz question.
It’s simple. You can do that by just checking the incoming request’s query parameter question.
Hi Team,
Your quiz functionality is working fine. Thanks a lot for !!!!. We are using this functionality in our project as well. I need to know when are you releasing the next updated version of this code with added functionality.
Actually I need to modify this functionality to include multiple type of questions in the same quiz like fill in the blanks, multiple choice, short answer, Image puzzles etc how can we accommodate these changes in this code
i downloaded the source code for quiz review and its not working properly
Hi Sonal, a lot of professionals from Administration background prefer taking Hadoop Administration course. It is like a natural progression. There is no pre-requisite of any programming language, however exposure to basic Linux fundamental comments will be beneficial. You can check out this link to know more about the course: https://www.edureka.co/hadoop-administration-training-certification You can call us at US: 1800 275 9730 (Toll Free) or India: +91 88808 62004 to discuss in detail. You can also email us at [email protected]
WHAT IS THE NECESSARY VERSION REQUIRED FOR THIS PROJECT
Hi Abby, for this project you can use Java 1.7 Version.
Hi ,
I tried to deploy the provided source code on weblogic server and i have changed database connection driver details as per the requirement but i’m getting below error.
java.lang.ClassNotFoundException: co.edureka.quiz.controller.MainController
Can you suggest me workaround for this or else can you provide me built which compatibles with weblogic.
Thanks
Harikrishna
Hey Harikrishna, thanks for checking out our blog. The problem in this case is with the deployed resources “libraries”. The libraries that you are using in the build path should be deployed in your project.
Properties > Deployment Assembly > add libraries from build path
Hope this helps. Cheers!