HTML Forms, Components, and Servlets

This document is to give you a brief overview of HTML forms, components, and servlets.  The big picture is that you create a form on a web page. When a user completes the form, the data that the user entered is sent to a servlet for processing.  A servlet is a java class (or object) whose doPost or doGet method is invoked (as prescribed by the form).  The servlet reads the submitted data, and outputs text or a new web page as a result.  In this document, I show how servlets can output either pure text or a web page as a result.

Here is an index to the major sections in this document:

A zip file that contains all of the examples in this document is here.

Preliminaries: Tomcat 4.1

We are using Tomcat 4.1 because it is stand-alone, and not a service.  (This has to do with the way the UTCS microlab is set up and for no other reason).  Although more recent versions are available, Tomcat 4.1 is sufficient for our needs.

We will be using a preconfigured version of Tomcat 4.1, which I first found via Marty Hall's web page:

As Tomcat has been installed in the Microlab, you're all set.  But do try to install it on your home machine, so that you can work at home.  The procedure that worked for me is:

Last bit of warning: when you are debugging servlets, make sure that your internet browser does not show you cached results.  If anything, when you update your servlets (by overriding their binaries in the WEB-INF/classes directory), create a new browser to view their output.  So be careful!

To start tomcat, invoke the above batch file (which can be done via the start menu in the microlab) and type:

%TOMCAT_HOME%\bin> startup

Classpath and path environment variables are already set, so I would recommend that this be the way that you start tomcat.  To stop tomcat, type:

%TOMCAT_HOME%\bin> shutdown

Forms

A form is a container of components that allows users to specify data.  A component could be a text field, radio button, text, etc. (More on this below). Completed forms can be sent to a servlet when a user presses "send" button on the form; or values on the forms can be reset to their initial values.  A form with a text field is shown below. It's image and HTML is shown below.

Type in text and hit submit or reset

Submit should do nothing; reset
should reset the field.

<form method="POST" action="TTT">
    Type in text and hit submit or reset
    <input type="text" name="T1" size="20"><br>
    Submit should do nothing;
     reset should reset the field.</p>
    <p><input type="submit" value="Submit" name="B1">
       <input type="reset" value="Reset" name="B2">
    </p>
</form>

Associated with a form is a "method" and "action" specification.  We will limit methods to be:

The use of these methods is by convention, as both methods have the same set of parameters.  The action is where you will specify the path to the servlet.  The action above "TTT" is meaningless.  However, if you wanted to invoke your servlet whose URL is:

where MachineName is "localhost" or the actual name of a machine "tootles.csres.utexas.edu" or its IP address, you would specify the action (in quotes) in either the following two ways:

I'll show you examples later, but this is the basic idea.

HTML Components

HTML has a few components that can be added to a web page.  They are:

<INPUT TYPE=text NAME=n [ VALUE=v ] [SIZE=s]>
<INPUT TYPE=password NAME=n [size=s]>

Rendered Image HTML

<INPUT TYPE=text NAME=t1 SIZE = 10 >
<INPUT TYPE=text NAME=t2 SIZE = 20 VALUE="nothing changed yet">
<INPUT TYPE="password" NAME="p1" SIZE="20">

Rendered Image HTML

<textarea name=ta1 rows=3 cols=10 >initial contents</textarea><br>
<textarea name=ta2 rows=3 cols=10></textarea><BR>
<INPUT TYPE=checkbox NAME=cb VALUE=v [CHECKED]>

Rendered Image HTML
JavaBeans
ActiveX
<INPUT TYPE=checkbox NAME=c1 VALUE="JavaBeans" CHECKED >JavaBeans<BR>
<INPUT TYPE=checkbox NAME=c2 VALUE="ActiveX" >ActiveX<BR>
<INPUT TYPE=radio NAME=rb VALUE=v [CHECKED]>

Rendered Image HTML
JavaBeans or
ActiveX
<INPUT TYPE=radio NAME=rad VALUE="JavaBeans" CHECKED >JavaBeans or<BR>
<INPUT TYPE=radio NAME=rad VALUE="ActiveX" >ActiveX<BR>

Rendered Image HTML

<SELECT NAME=sel>
   <OPTION VALUE="Ohio">Ohio
   <OPTION VALUE="Texas">Texas
   <OPTION VALUE="Vermont">Vermont
   <OPTION VALUE="California">California
</SELECT>
<INPUT TYPE=hidden  NAME=rb VALUE=v >

Rendered Image HTML
 
<INPUT TYPE=hidden NAME=nosee VALUE="myname">

You can either write HTML by hand, or what I prefer is to use an HTML editor (e.g., Microsoft's FrontPage).

Servlets

A servlet is a Java class that implements a standardized interface.  The basic form of a servlet class is:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class <yourServletName> extends HttpServlet {...}

There are three methods of HttpServlet that you might implement: init, doPost, and doGet.

init

init() is called once when a servlet is first instantiated.  It is here that you would initialize variables. It is sometimes recommended that you can initialize database connections in init() methods.  This might be fine if there are very few connections that you or others will make to a database.  But in this class, remember that many of your classmates will be trying to make connections to the database at the same time.  Generally, there is a limited number of connections that can be made  to a DBMS at any one time.  Do not hog this resource.  In some benchmarking tests, you won't see much of an overhead or delay if you open a connection, run your query, and close a connection.  Rule: if you open a database connection ALWAYS close it.  Your project grade will be penalized if you do not follow this rule.

Do not initialize database connections in init methods.  Always open and close connections explicitly within a doGet and doPost method.

doPost, doGet

Both methods have exactly the same parameters: an HttpServletRequest request, and an HttpServlet response.  It is from the request object that you can read data from a submitted form. To read form input, you need to know the name of a HTML component. Next, you need to know if the result is scalar or multi-valued.  Suppose the name of a component is "mycomp", and it returns a scalar value.  To obtain this component's (String) value, use:

String mycompValue = request.getParameter("mycomp");

If mycomp returned multiple values, a String array is returned.  To obtain this array, use:

String [] mycompValueArray = request.getParameterValues("mycomp");

To output text, create a PrintWriter from the response variable, and output normally:

PrintWriter out = response.getWriter();
out.println("hello World");

If you want to output HTML, do the following.  Set the content type before creating a PrintWriter from the response variable:

response.setContentType("text/html");
PrintWriter out = response.getWriter();

And before you output HTML text, you must first output an HTML header.  You can use the following method and variable:

public static final String DOCTYPE =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.1 " +
"Transitional//EN\">";

public static String headWithTitle(String title) {
  return(DOCTYPE + "\n" + "<HTML>\n" +"<HEAD><TITLE>" + title + "</TITLE></HEAD>\n");
}

// code your servlet to execute

out.println( headWithTitle("title of my page") );

// now output whatever html that you want.

A quick tutorial on HTML syntax is found at:

I presume that you can learn HTML basics quickly on your own.

Example Servlet that Outputs Text

The figure below is a screen snapshot of a web page that has a form with all of the above elements:

The HTML file (testform2.html) that defines this page is shown below.  This page should be stored in <jakartaTomcat>/webapps/ROOT:

<html>

<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>This is a textbox</title>
</head>

<body>

<form method="GET" action="servlet/coreservlets.register2">
<p>
<input type="text" name="textbox" size="20">This is a textbox</p>
<p>
this is a hidden box<input type="hidden" name="nosee" value="mypassword"></p>
<fieldset style="padding: 1">
<legend>choose1</legend>
<input type="radio" value="V1" name="Rd" >option1<p>
<input type="radio" name="Rd" value="V2" >option2</p>
<p><input type="radio" name="Rd" value="V3" >option3</p>
</fieldset><p><select size="2" name="dropdown" multiple>
<option value="1">choice1</option>
<option value="3">choice3</option>
<option value="2">choice2</option>
</select>dropdown box with multiple selections.</p>
<p>enter your comments here:<textarea rows="4" name="myarea" cols="20">
This is an example of
a multiple line
text box.</textarea></p>
<fieldset style="padding: 2">
<legend>Other Options</legend>
<input type="checkbox" name="cb1" value="on">rocky road<br>
<input type="checkbox" name="cb2" value="on">vanilla</fieldset></p>
<p><input type="submit" value="Submit" name="B1">
<input type="reset" value="Reset" name="B2"></p>
</form>

</body>

The servlet that defines the actions of this form is shown below.  A compiled version of it is stored in <jakartaTomcat>/webapps/ROOT/WEB-INF/classes/coreservlets.

package coreservlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class register2 extends HttpServlet {

   public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
      PrintWriter out = response.getWriter();
      String tb = request.getParameter("textbox");
      String rd = request.getParameter("Rd");
      String dd[] = request.getParameterValues("dropdown");
      String ns = request.getParameter("nosee");
      String tf = request.getParameter("myarea");
      String cb1 = request.getParameter("cb1");
      String cb2 = request.getParameter("cb2");

      out.println("textbox='" + tb + "' ");
      out.println("radio=" +rd);
      out.println("dropdown=(");
      for (int i=0; i< dd.length; i++)
         out.println(" " + dd[i] + " ");
      out.println(") ");
      out.println("hiddenvalue = "+ ns);
      out.println("myarea='"+tf+"' ");
      out.println("cb1="+cb1);
      out.println("cb2="+cb2);
   }
}

An Example that Outputs HTML

To output HTML, minor changes to the HTML page need to be made.  First, alter the form action to redirect to the register3 servlet:

Next, the register3 servlet is modified to output HTML.  Its source is below.  Changes that are made are highlighted.

package coreservlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class register3 extends HttpServlet {
   public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

      response.setContentType("text/html");
      PrintWriter out = response.getWriter();
      String tb = request.getParameter("textbox");
      String rd = request.getParameter("Rd");
      String dd[] = request.getParameterValues("dropdown");
      String ns = request.getParameter("nosee");
      String tf = request.getParameter("myarea");
      String cb1 = request.getParameter("cb1");
      String cb2 = request.getParameter("cb2");

      // new stuff
      String docType ="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.1 " +
         "Transitional//EN\">\n";
      out.println(docType + "<HTML><BODY>");
      out.println("<H2>textbox='" + tb + "' </H2>");
      out.println("<H2>radio=" +rd +"</H2>");
      out.println("<H2>dropdown=(");
      for (int i=0; i< dd.length; i++)
         out.println(" " + dd[i] + " ");
      out.println(") </H2>");
      out.println("<H2>hiddenvalue = "+ ns+"</H2>");
      out.println("<H2>myarea='"+tf+"' </H2>");
      out.println("<H2>cb1="+cb1+"</H2>");
      out.println("<H2>cb2="+cb2+"</H2>");
      out.println("<p><a href=\"http://localhost/testform3.html\">go back</a></p>");
      out.println("</BODY></HTML>");
   }
}

Connecting to Oracle -- Some Advice

Connecting to Oracle via JDBC is simple in general, and no different when writing servlets.  There are two things that you will need to do to make your servlets-to-oracle-connections work:

import oracle.jdbc.driver.OracleDriver;
import java.util.*;
import java.sql.*;
import java.io.*;

Connection conn = null;
Class.forName( oracle.driver );
conn = DriverManager.getConnection( oracle.url, oracle.user, oracle.password );
conn.setAutoCommit( false );
Statement stmt = conn.createStatement();
...

try {
   if (conn!=null) conn.close();
}
catch ( Exception e ) {..};

Be aware that this design will not scale well if you web page/servlet is getting hundreds of hits per second.  You need a different technology, what is called Enterprise Java Beans, to help you.  More on this in class.

Also, here are some hints for displaying images.  In a database design, you could store all the images in a directory, and URLs to these images in the database.  This design has the unfortunate property that the image data is not in the database.  Alternatively, you could store the images as BLOBs (binary large objects) in the database itself.  Doing so will slow down database access, but you will have all the data in the database.

Here's another issue.  Suppose you have tuples that have images, and you want to display these images on an HTML page, along with the text data of a tuple.  In HTML, you reference an image by the construct <img src="path">, where path is a local path (or what I found that works better is an absolute path, such as "http://mymachine/image.gif").  The problem here is that you read in binary data from the database, and have to store it in a temporary file so that the HTML page can reference this file.  Temporary files will accumulate over time, and you'll have to delete them.  I haven't found a better solution to this problem.  (The image reference is actually translated into a reference to your server for a file.  Alternatively, it could be a reference to a servlet that produces the binary of that image.  Unfortunately, this may entail yet another read from the database to get the image itself.  It is unclear what is the best approach to handle this problem).

An example servlet which produces a reference to an image is given below:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class bill extends HttpServlet {
   final String MrBill = 
      "C:\\jakarta-tomcat-4.1.29\\webapps\\ROOT\\WEB-INF\\classes\\MrBill.jpg";
   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      response.setContentType("text/html");
      ServletOutputStream out = response.getOutputStream();
      String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n";
      out.println(docType +
         "<HTML>\n" +
         "<HEAD><TITLE>Hello</TITLE></HEAD>\n" +
         "<BODY BGCOLOR=\"#FDF5E6\">\n" +
         "<H1>Hello</H1>\n");
      out.println("<img src=\"http://localhost/MrBill.jpg\">");
      out.println( "</BODY></HTML>"); 
   }
}

Good luck!

Updated 28-Aug-2007