Java Programming, Lecture Notes # 692, Revised 3/16/99.
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.
This and the next several lessons will show you some of the ways to implement session tracking using servlets.
An earlier lesson showed you how to implement session tracking using hidden fields on the HTML form. This lesson illustrates a similar approach using URL rewriting. Other approaches will be illustrated in subsequent lessons.
If you observed the URL window in your browser while running the program named Servlet07 from an earlier lesson, you probably noticed that after several cycles, the window contained something like the following.
http://baldwin:8080/servlet/Servlet07? |
What you are seeing here is the standard way in which HTML forms pass parameters to their HTTP servers. (Manual line breaks were inserted to force the material to fit on the page.)
When the user clicks on the submit button, a string containing the names and values for all of the fields is created and concatenated onto the URL. The string of parameter values is joined to the URL with a "?" character. The individual parameters are separated from one another with the "&" character.
Recall that in Servlet07, the field named firstName was the visible field in which the user entered a name. The fields named item were hidden fields that were created and populated with historical data when the servlet generated the HTML form for return to the client.
It doesn't really matter how these parameter names and values come to be concatenated onto the URL. As far as the servlet is concerned, their values are accessible using the methods getParameter() and getParameterValues().
This suggests that in some cases, it might be beneficial for the servlet to save the historical data by concatenating it onto a URL referenced in the HTML page before returning the page to the client. That is one of the ways that URL rewriting can be used to implement session tracking.
This sample program is designed to illustrate the concept of URL rewriting and is not intended to have any particular value in its own right.
Servlet08.java
illustrates session tracking using URL rewriting. In this case, parameters containing the historical data are added to the servlet's URL each time the servlet generates a new HTML page.Each time the servlet is invoked, it creates and displays an HTML page on the client screen. The page displays:
Each time the user clicks on the hyperlink, the client sends a GET request to the server. The GET request invokes the servlet, which determines the current date and time. An HTML page is created and sent back to the client.
The current date and time in milliseconds is added as a parameter named item to the servlet URL referenced by the hyperlink in the newly-created HTML page. In addition to the current date and time, the values of the previous dates and times when the user invoked the servlet by clicking the hyperlink are retrieved from the incoming URL and appended to the new URL.
In other words, the parameter values for each successive URL that is generated match those of the previous URL. In addition, a new parameter value is added which represents the current date and time.
The historical data is saved by embedding it in the new HTML page that is returned to the client. There is no requirement to save the historical data in a database or in the server's file system.
This approach places no special requirements on the server software and should be compatible with all browsers that support hyperlinks.
A typical screen output produced by running this program through several cycles during a single session is shown below.
Click Here Your list of times is: 16-Mar-99 9:35:52 PM 16-Mar-99 9:58:03 PM 16-Mar-99 9:58:05 PM 16-Mar-99 9:58:06 PM 16-Mar-99 9:58:08 PM |
The URL that produced this output is shown below with manual line breaks inserted to force it to fit on the page.
http://baldwin:8080/servlet/Servlet08? |
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 Servlet08 extends HttpServlet{ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{ |
An HTTP URL can have multiple parameters with the same name. In this case, the parameters are all named item. The next fragment gets the values stored in all of the parameters named item and saves them in a String array named items.
The fragment also instantiates and initializes a String object used later to construct a new parameter string for the URL.
String parameters = "?"; String[] items = req.getParameterValues("item"); |
The next fragment uses the parameter values from the old parameter string to construct a new parameter string. The new parameter string will later be concatenated to the URL for the servlet.
if(items != null){ for(int i = 0; i < items.length; i++){ parameters = parameters + "item=" + items[i] + "&"; }//end for loop }//end if |
The next fragment gets the current date and time in milliseconds and saves it in a long variable named theDate. Then it concatenates the current date and time in milliseconds onto the new parameter string constructed above.
long theDate = new Date().getTime(); parameters = parameters + "item=" + theDate; |
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>Servlet08</TITLE></HEAD>"); out.println("<BODY>"); |
The next fragment constructs the hyperlink containing the URL for the servlet. Note that the hyperlink references a URL that includes the parameter string constructed above.
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.
out.println("<A HREF=\"http://baldwin:8080/servlet/" + "Servlet08" + parameters + "\">Click Here</A>"); |
The next fragment simply provides a line of introductory text for the list of dates and times to be displayed on the screen.
out.println("<BR><BR>Your list of times is:<BR>"); |
An earlier fragment retrieved all of the data in the incoming URL parameters and saved that data in a String array named items.
If that array contains data, the next fragment displays the date and time for each element in the array.
The parameter values in milliseconds are first converted from String to long. Each of the long values is then used to instantiate a new Date object, which is displayed in the format shown earlier.
if(items != null){ for(int i = 0; i < items.length; i++){ long millis = Long.parseLong(items[i]); Date aDate = new Date(millis); out.println(DateFormat.getDateTimeInstance(). format(aDate) + "<BR>"); }//end for loop }//end if |
An earlier fragment also obtained the current date and time and saved it in milliseconds. As above, this representation of the date and time is used to instantiate a new Date object that is formatted and displayed at the end of the list on the HTML page.
Date aDate = new Date(theDate); out.println(DateFormat.getDateTimeInstance(). format(aDate) + "<BR>"); |
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.
A complete listing of the program follows.
/*File Servlet08.java, Copyright 1999, R.G.Baldwin Rev 3/16/99 The purpose of this program is to illustrate session tracking through the use of rewritten URLs Each time the servlet is activated, it creates an HTML file and sends it back to the client. The HTML file displays an HTML hyperlink on the client screen. In addition, it displays a list of date/time values representing the dates and times at which the servlet was accessed from that page by clicking on that hyperlink. Each time the user clicks the hyperlink,the servlet is activated, causing it create and send a new HTML page to the client. Each time the HTML page is created and sent to the client, the URL of the servlet referenced by the hyperlink is modified to include the current date and time plus the date and time of each previous access made by clicking on the hyperlink. The date/time information is converted to milliseconds and appended to the URL in the form of standard URL parameters. Thus, the length of the URL increases each time the HTML form is created. The servlet illustrates how it is possible to store historical data in the parameter string that can be appended to a URL. 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 java.util.*; import java.text.*; import javax.servlet.*; import javax.servlet.http.*; public class Servlet08 extends HttpServlet{ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{ //Ref variable used to construct the parameter string String parameters = "?"; //An array for getting and saving the values contained // in the parameters named item. String[] items = req.getParameterValues("item"); if(items != null){ for(int i = 0; i < items.length; i++){ //Access the old parameter string to construct the // new parameter string to append to the URL below. parameters = parameters + "item=" + items[i] + "&"; }//end for loop }//end if //Get the current date and time in milliseconds. Add // the current date and time to the parameter string // constructed above. long theDate = new Date().getTime(); parameters = parameters + "item=" + theDate; //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>Servlet08</TITLE></HEAD>"); out.println("<BODY>"); //Construct the hyperlink referencing the servlet here. // Note that the hyperlink references a URL that // includes the parameter string constructed above. //Substitute the name of your server or localhost in // place of baldwin in the following statement. out.println("<A HREF=\"http://baldwin:8080/servlet/" + "Servlet08" + parameters + "\">Click Here</A>"); //Display the historical data stored in the parameter // string. out.println("<BR><BR>Your list of times is:<BR>"); if(items != null){ for(int i = 0; i < items.length; i++){ long millis = Long.parseLong(items[i]); //Convert from milliseconds as a String to a Date // object. Then format for display. Date aDate = new Date(millis); out.println(DateFormat.getDateTimeInstance(). format(aDate) + "<BR>"); }//end for loop }//end if //Convert from milliseconds to a Date object and then // format for display. Date aDate = new Date(theDate); out.println(DateFormat.getDateTimeInstance(). format(aDate) + "<BR>"); out.println("</BODY></HTML>");//finish HTML page }//end doGet() }//end class Servlet08 |
-end-