Pages

Friday 29 February 2008

Poll-taking servlet

This is a very simple Servlet that manages a simple poll taking scenario. It tries to get a peoples' opinions on their favorite programming language. The languages involved in the poll are; Java, C++, C, Python and C#. These are stored in a MySQL database created with the following script;


CREATE TABLE `elections` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`language` varchar(20) DEFAULT NULL,
`votes` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1

in a database named 'applications'.
This is what you should expect to see after inserting all the values into your new table;

mysql> SELECT * FROM elections;
+----+----------+-------+
| id | language | votes |
+----+----------+-------+
| 1 | Java | 0 |
| 2 | C++ | 0 |
| 3 | C | 0 |
| 4 | Python | 0 |
| 5 | C# | 0 |
+----+----------+-------+
5 rows in set (0.00 sec)

For those who do not know how to insert data into tables using SQL statements, this should be of help(I expect this code to work in MySQL and PostgreSQL databases. However it may also work in others exactly as this, or may be with afew alterations then maybe with a few adjustments);

INSERT INTO elections(`language`, `votes`) VALUES ("Java", "0");
Remember the semi-colon at the end of the statement------------^.


As those with advanced knowledge of Servlet programming will notice; the database user name and passwords are open for all to see(in otherwords, a sitting or lame duck). However, this was not about security but rather about managing a voting process.

You have to create a sub-directory for your web application in the webapps sub-directory of your Apache Tomcat web-server. Mine, I called it 'Dynamic'. You can give it another name of your choice.
Then, create a sub-directory in the Dynamic. You must name it WEB-INF. That is the way Tomcat will determine that this is a web application.
You can also create another sub-directory under the Dynamic to contain other .html or .jsp web pages. Mine, I called it Pages. You can also store your images or web page assets such as CSS and JavaScript files here.
Then, under the WEB-INF sub-directory, create another sub-directory. You must name it classes. This is the directory where all your Java files (.class files) will(must) be saved
So, this below is the tree structure of my Dynamic directory which is located in the Apache Tomcat webapps directory.

C:PROGRA~1APACHE~1TOMCAT 6.0WEBAPPSDYNAMIC
+---Pages
| Vote.html
|
+---WEB-INF
| web.xml
|
+---classes
Elections.class
Elections.java

Start by placing the web.xml file into the WEB-INF sub-directory of your web application directory.
The code for the web.xml file is this;
(Remember, you will have to do the indentation for this code and the following code yourself for your easy understanding. I originally had it indented. However, due to the requirement for manual hand-coding of html for indentation to display this code in this page, it therefore displays as it does below( If you do not understand this paragraph, just hop over it. It is just a by-the-way)).

<web-app>
<description>
Dynamic site for elections
</description>
<servlet>
<servlet-name>
Vote
</servlet-name>
<servlet-class>
Elections
</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>
Vote
</servlet-name>
<url-pattern>
/Vote
</url-pattern>
</servlet-mapping>
</web-app>



Now, the web page that invokes the servlet has the following code.
<html>
<head>
<title>Vote Now</html>
</head>
<body bgcolor = "#CCCC00" font-family = "verdana" >
<h2>Please participate in our poll.</h2>
<p>
Vote for your favorite programming language; <br />
</p>
<p>
<form action = "/Dynamic/Vote" method = "post">
<input type = "radio" name = "language" value = "1" >Java<br />
<input type = "radio" name = "language" value = "2" >C++<br />
<input type = "radio" name = "language" value = "3" >C<br />
<input type = "radio" name = "language" value = "4" >Python<br />
<input type = "radio" name = "language" value = "5" >C#<br />
<input type = "submit" value = "Vote Now">
</form>
</p>
</body>
</html>

Now, the real code for the Servlet is this. It has been aptly named 'Elections.java'.

//import all packages relevant for processing the servlet and database access.

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.ServletException;
import java.sql.*;

public class Elections extends HttpServlet
{
private Connection con;
private Statement stmt;
private ResultSet rs;

public void init() throws ServletException
{
final String URL = "jdbc:mysql://localhost/applications";
final String JDBC_NAME = "com.mysql.jdbc.Driver";
final String user = "root";
final String password = "mysql";

//try to load MySQL/ConnectorJ Driver.
try
{
Class.forName(JDBC_NAME);
}
catch(ClassNotFoundException ex)
{
}

try
{
con = DriverManager.getConnection(URL, user, password);
stmt = con.createStatement();
}
catch(SQLException sqlEx)
{
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();

out.print("<html><head>");

/* Try to convert the String 'value' posted from Vote.html to an int value
using method Integer method parseInt() */
int value = Integer.parseInt(request.getParameter("language"));
String query;

try
{
query = "UPDATE elections SET votes = votes + 1 WHERE id = " + value;
stmt.executeUpdate(query);

query = "SELECT SUM(votes) FROM elections";
ResultSet rsTotal = stmt.executeQuery(query);
rsTotal.next();
int total = rsTotal.getInt(1);
rsTotal.close();
rsTotal = null;

out.println("<title>");
out.print("Results until now" + value);
out.print("</title></head><body>");
out.print("<h1>Here are the results so far</h1>");

ResultSet rs = stmt.executeQuery("SELECT * FROM elections");
out.println("<p>");
out.print("<table>");
int votes;

while (rs.next())
{
out.print("<tr border = 0>");
out.println("<td>" + rs.getString(2) + "</td>");

votes = rs.getInt(3);
out.println("<td>" + " " + "Votes: " );
out.printf("%d %.2f%s%s", rs.getInt(3), (double)votes / total * 100, "%", "</td>");
for ( int i = 0; i <= rs.getInt(3); i++)
{
if ( i == 0)
{
}
else
{out.println("<td border = 0 bgcolor = blue height = 5>" + " " +"</td>");}
}
out.println("</tr>");
}
rs.close();
rs = null;

out.print("</table>");
out.println("</p>");
out.println("Total number of votes is: " + total);
out.print("</body></html>");
}

catch (Exception ex)
{
//If error is encountered, then display message to user
out.print("Encountered Error!");
out.println("</title></head><body>");
out.println("Encountered an error while processing your vote.<br />");
out.println("Please try again later!");
out.println("<br />");
out.println(ex.getMessage());
out.println("</body></html>");



}
}

//destroy any used resources
public void destroy()
{
try
{
if ( con != null )
{
con.close();
con = null;
}
}
catch (Exception ex)
{

}
}
}
To compile this, remember to include the servlet.jar file in the -classpath option of the javac statement on Command-line. From the site java.sun.com, you can download the servlet-2_5-api.jar file for compiling the servlet .java file. Alternatively, you can locate the servlet.jar file from the lib subdirectory of your Tomcat web container.
-->