Richard G Baldwin (512) 223-4758, baldwin@austin.cc.tx.us, http://www2.austin.cc.tx.us/baldwin/

Servlets, Session Tracking Using Hidden Fields

Java Programming, Lecture Notes # 691, Revised 3/16/99.

Preface

Introduction

Sample Program

Interesting Code Fragments

Program Listing


Preface

Students in Prof. Baldwin's Advanced Java Programming classes at ACC will be responsible for knowing and understanding all of the material in this lesson beginning with the spring semester of 1999.

This lesson was originally written on March 16, 1999.

The sample servlet in this lesson was tested using Win95, the JDK 1.2 download package from JavaSoft, the JSDK 2.0 download package from JavaSoft, and the servletrunner program that is included in the JSDK. The sample program was tested using servletrunner both from the same machine, and from a different machine on the network.

Introduction

Session tracking is very important from a web commerce viewpoint. Therefore, this and the next several lessons will show you some of the ways that you can accomplish session tracking using servlets.

Perhaps the most common example of the need for session tracking is with a web commerce application involving a shopping cart. The customer (client) downloads various pages from a vendor catalog, selecting items, and placing them in a shopping cart. At some point, the customer decides either to purchase the items or abandon the shopping trip.

If the customer decides to purchase the items in the cart, the web application must have a record of all the items in the cart. Furthermore, that record must be associated with that particular customer so that the sale can be consummated.

Insofar as the HTTP protocol is concerned, each time the customer views a different page in the catalog, all information regarding previously viewed pages is forgotten. The HTTP protocol doesn't save state information regarding an ongoing session by that customer involving multiple pages. It is the responsibility of the application to track the session involving that client (customer).

In the case of the shopping cart application, it is also the responsibility of the application to keep track of the items in the cart associated with that customer.

There are several different ways to accomplish session tracking with a servlet. This lesson will illustrate one of them. Other ways will be illustrated in subsequent lessons.

Sample Program

Servlet07.java illustrates session tracking using hidden fields on the HTML form.

Each time the servlet is activated, it creates and displays an HTML form on the client screen. The form displays:

Each time the client makes a GET request of the server, an HTML form is created and sent back to the client. Hidden fields are added to the form each time it is created. The hidden fields contain the name submitted for that GET request plus hidden fields containing each of the names submitted by each previous GET request. In other words, the hidden fields on each successive form match those of the previous form plus a new hidden field for the new name submitted with that GET request.

Using this approach, the historical data is saved by embedding it in the new HTML form that is returned to the client. Thus, there is no requirement to save the historical data in a database or in the server's file system.

While not particularly elegant, this approach has been used by CGI programmers for some time, is reliable, and is easy to implement. Furthermore, it places no special requirements on the server software and is compatible with all browsers that support HTML forms.

Interesting Code Fragments

The first fragment shows the beginning of the controlling class and the beginning of the doGet() method. You have seen this before, so I won't discuss it further.

public class Servlet07 extends HttpServlet{
  public void doGet(HttpServletRequest req, 
                    HttpServletResponse res)
                      throws ServletException, IOException{

An HTML form can have multiple fields with the same name. In this case, the hidden fields are all named item. The next fragment gets the values stored in all of the hidden fields named item and saves them in a String array named items.

    String[] items = req.getParameterValues("item");

The next fragment gets and saves the name value submitted by the client in the field named firstName.

    String name = req.getParameter("firstName");

The next fragment begins the creation of the output HTML page. You have seen code like this many times before, so I won't discuss it further at this point.

    //Establish the type of output
    res.setContentType("text/html");
    
    //Get an output stream
    PrintWriter out = res.getWriter();
    
    //Construct an HTML form and send it back to the client
    out.println("<HTML>");
    out.println("<HEAD><TITLE>Servlet07</TITLE></HEAD>");
    out.println("<BODY>");

The next fragment continues the construction of the HTML form that is to be returned to the client. This is a little more specialized, beginning a series of HTML statements necessary to support the input field and the submit button. You may need to refer to earlier lessons that discussed the format of an HTML form in order to understand the next few fragments.

If you compile and run this servlet, you will need to substitute the name of your server machine or localhost in place of baldwin in this statement. baldwin is the name of my server machine.

This fragment causes a GET request to be sent to the HTTP server containing field data as parameters whenever the user presses the submit button.

    out.println("<FORM METHOD=GET ACTION="
           + "\"http://baldwin:8080/servlet/Servlet07\">");

The next fragment places a line of instructional text on the client screen.

It also creates the HTML statements necessary to place an input field and a submit button on the form that will be displayed on the screen.

    out.println("Enter a name and press the button<P>");
out.println("Name: <INPUT TYPE=TEXT NAME=" + "\"firstName\"><P>"); out.println("<INPUT TYPE=submit VALUE=" + "\"Submit Name\">");

The next fragment provides a line of introductory text for the list of names to be displayed on the screen. The first time the form appears on the screen, the value stored in the name variable is null, and the word Empty is also displayed.

    out.println("<BR><BR>Your list of names is:<BR>");
if(name == null){ out.println("Empty<BR>"); }//end if

An earlier fragment retrieved all of the data in the hidden fields on the form and saved that data in a String array named items.

If that array contains data, the next fragment performs two actions using the data from each element of the array:

Thus, the historical data is passed forward from the hidden fields of one HTML form to the hidden fields of the next HTML form.

    if(items != null){
      for(int i = 0; I < items.length; i++){
        out.println(items[i] + "<BR>");
        out.println("<INPUT TYPE = hidden NAME=item "
                              + "VALUE=" + items[i] + ">");
      }//end for loop
    }//end if

An earlier fragment also retrieved the field value submitted by the client and saved that value in a variable named name.

If that variable contains data, the next fragment also performs two actions using the data stored in the variable.

Thus, each time the client accesses the servlet, one additional hidden field is added to the HTML form under construction. The new hidden field contains the field value submitted by the client.

    if(name != null){
      out.println(name + "<BR>");
      out.println("<INPUT TYPE = hidden NAME=item "
                                  + "VALUE=" + name + ">");
    }//end if

The remainder of the code is typical of what you have seen before and can be viewed in the complete listing of the servlet in the next section.

Program Listing

A complete listing of the program follows.

/*File Servlet07.java, Copyright 1999, R.G.Baldwin
Rev 3/16/99
The purpose of this program is to illustrate session
tracking through the use of hidden fields.

Each time the servlet is activated, it displays an html
form on the client screen.  The form contains:
  An input field for submitting a name
  A submit button
  A list of previously submitted names
  
Each time the html form is created and sent back to the
client, hidden fields are placed on the form.  The hidden
fields contain the name submitted for that GET request
from the client plus hidden fields containing each of
the names submitted by each previous GET request.
 
The servlet was tested using the JDK 1.2 download package
from JavaSoft along with the Java Servlet Development Kit
(JSDK) 2.0 from JavaSoft. All tests were performed 
under Win95.

The servlet was tested using the servletrunner program that
is included in the JSDK with the servletrunner program 
running on the same machine and also with the servletrunner
program running on a different machine on the network. 


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

public class Servlet07 extends HttpServlet{
  public void doGet(HttpServletRequest req, 
                    HttpServletResponse res)
                      throws ServletException, IOException{

    //An array for getting and saving the values contained
    // in the hidden fields named item.
    String[] items = req.getParameterValues("item");
    
    //Get the submitted name for the current GET request
    String name = req.getParameter("firstName");

    //Establish the type of output
    res.setContentType("text/html");
    
    //Get an output stream
    PrintWriter out = res.getWriter();
    
    //Construct an HTML form and send it back to the client
    out.println("<HTML>");
    out.println("<HEAD><TITLE>Servlet07</TITLE></HEAD>");
    out.println("<BODY>");
        
    //Substitute the name of your server or localhost in
    // place of baldwin in the following statement.
    out.println("<FORM METHOD=GET ACTION="
           + "\"http://baldwin:8080/servlet/Servlet07\">");
    out.println("Enter a name and press the button<P>");
    out.println("Name: <INPUT TYPE=TEXT NAME="
                                    + "\"firstName\"><P>");
    out.println("<INPUT TYPE=submit VALUE="
                                     + "\"Submit Name\">");
    out.println("<BR><BR>Your list of names is:<BR>");
    if(name == null){
      out.println("Empty<BR>");
    }//end if 
    
    if(items != null){
      for(int i = 0; i < items.length; i++){
        //Display names previously saved in hidden fields
        out.println(items[i] + "<BR>");
        //Save the names in hidden fields on form currently
        // under construction.
        out.println("<INPUT TYPE = hidden NAME=item "
                              + "VALUE=" + items[i] + ">");
      }//end for loop
    }//end if

    if(name != null){
      //Display name submitted with current GET request
      out.println(name + "<BR>");
      //Save name submitted with current GET request in a
      // hidden field on the form currently under
      // construction
      out.println("<INPUT TYPE = hidden NAME=item "
                                  + "VALUE=" + name + ">");
    }//end if

    out.println("</BODY></HTML>");
      
  }//end doGet()
}//end class Servlet07

-end-