The JSP Files (part 4): The Red Pill

Find out JSP can be used to process form data, and learn about the Request object.

Applying The Theory

Last time out, we gave you a crash course in the numerous controls structures available to you in JSP - operators, conditional statements, and loops. But there's a big difference between learning theory in a classroom and actually practicing it in the real world - which is why this issue of The JSP Files is devoted to a discussion of how JSP can be used to extract and use data from HTML forms.

Over the next few pages, we're going to show you how JSP can be used to process the data entered into a Web form - everything from simple text boxes to lists and checkboxes - and we're also going to demonstrate how to use array variables in JSP.

The Last Action Hero

HTML forms are typically used to obtain information from visitors to a Web site - things like their name, mailing address, phone number, and the like - and this information is then processed in a variety of different ways. Some sites store it in a database; others email it to the webmaster; and still other simply redirect it to the trash basket. By using JSP to process a form, you can write simple code snippets that accomplish all of these actions.

Let's begin with a simple example.

<html>

<head>
<basefont face="Arial">
</head>

<body>

<center>
<form method="GET" action="matrix.jsp">
<table cellspacing="5" cellpadding="5" border="0">

<tr>
<td>
<font size="-1">Name, rank and serial, number, soldier!</font>
</td>
<td align="left">
<input type="text" name="name" size="10">
</td>
</tr>

<tr>
<td colspan="2" align="center">
<input type="submit">
</td>
</tr>

</table>
</form>

</center>
</body>

</html>

The most critical line in this entire page is the <form> tag

<form method="GET" action="matrix.jsp">

...

</form>

As you probably already know, the ACTION attribute of the <FORM> tag specifies the name of the server-side script - "matrix.jsp" in this case - that will process the information entered into the form, while the METHOD attribute specifies the manner in which the information will be passed.

Entering The Matrix

Once the form has been submitted, the script "matrix.jsp" is called upon to parse the date entered into the form. At this point, the script simply reads the name entered into the form, and displays a message containing that name; however, at a later point, it will be modified to grant or deny access based on the name entered.

<html>
<head>
<basefont face="Arial">
</head>

<body>
<center>
<%
// matrix.jsp

// define the variables used in the scriptlet
String fname;

// assign values
fname = request.getParameter("name");

// print the details
out.println("Welcome to The Matrix, " + fname + "!");

%>
</center>
</body>
</html>

And now, if you enter some data into the form (say, "joe"), this is what you should see:

Welcome to The Matrix, joe!

An explanation is in order here. As always, the first step is to define the variables that will be used throughout the script - in this case, the variable "fname".

<%
// define the variables used in the scriptlet
String fname;
%>

Next, the value of the form variable "name" has to be assigned to the JSP variable "fname" - this is accomplished with the getParameter() method, which accepts a variable name as parameter and returns the variable value.

The getParameter() method actually belongs to a JSP object called the Request object; unlike many other objects in JSP, the Request object is an "implicit" object, so called because you do not need to explicitly create an instance of the object when you want to use it. The getParameter() method is just one of many methods available in this object, and we'll be exploring some of the others as well in this tutorial.

Once the value of a form variable has been assigned to a JSP variable, it can be treated in exactly the same manner as other JSP variables. In the example above, a println() function call takes care of printing the welcome string, with the name incorporated into it.

You can also use the POST method (which offers greater security and reliability) to process form data - simply alter the HTML form so that the METHOD used is POST.

<form method="POST" action="matrix.jsp">

...

</form>

The script "matrix.jsp" will continue to function as advertised without requiring any changes. Thus, the getParameters() method can be used to access form variables regardless of the method used to post the data.

And you can add a simple conditional statement to deny access to all but the most favoured:

<html>
<head>
<basefont face="Arial">
</head>

<body>
<center>
<%
// matrix.jsp

// define the variables used in the scriptlet
String fname;

// assign values
fname = request.getParameter("name");

// print the details
if (fname.equals("neo"))
{
out.println("Welcome to The Matrix, Neo!");
}
else
{
out.println("Leave immediately, Agent!");
}
%>
</center>
</body>
</html>

Requesting More

The Request object also comes with a bunch of other useful methods - the following example demonstrates some of them

<html>
<head>
<basefont face="Arial">
</head>
<body>

<table border="1" cellspacing="5" cellpadding="5">
<tr>
<td><b>Variable</b></td>
<td><b>Value</b></td>
</tr>

<tr>
<td>Request protocol</td>
<td>
<%
// protocol
out.println(request.getProtocol());
%>
</td>
</tr>

<tr>
<td>Hostname</td>
<td>
<%
// server name
out.println(request.getServerName());
%>
</td>
</tr>

<tr>
<td>Port</td>
<td>
<%
// server port
out.println(request.getServerPort());
%>
</td>
</tr>

<tr>
<td>Remote username</td>
<td>
<%
// username if using HTTP authentication
// null if no authentication
out.println(request.getRemoteUser());
%>
</td>
</tr>

<tr>
<td>Remote address</td>
<td>
<%
// get IP address of client
out.println(request.getRemoteAddr());
%>
</td>
</tr>

<tr>
<td>Client browser</td>
<td>
<%
// client browser identification
out.println(request.getHeader("User-Agent"));
%>
</td>
</tr>

</table>
</body>
</html>

And when you view the file in your browser, you'll probably see something like this:

Variable        Value
Request protocol        HTTP/1.0
Hostname        localhost
Port            80
Remote username     null
Remote address      192.168.0.143
Client browser      Mozilla/4.0 (compatible; MSIE 5.5; Windows 95)

All these variables come in handy if you need to make decisions on the basis of remote variables - as the following example demonstrates:

<%
String browser = request.getHeader("User-Agent");
if(browser.indexOf("MSIE") >= 0)
{
    // IE-specific code
}
else if(browser.indexOf("Mozilla") >= 0)
{
    // Mozilla-specific code
}
else
{
    // any other browser
}
%>

Note our usage of the indexOf() method - you may remember this from previous articles in this series.

Taking Some Medication

Just as you can access data from text fields, you can also use the getParameter() method to evaluate the state of radio buttons and list boxes. Suppose you modify the form above to something a little more complex.

<html>

<head>
<basefont face="Arial">
</head>

<body>

<center>
<form method="GET" action="pills.jsp">

<font size="-1" face="Arial">
Gimme
<select name="quantity">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
of those little
<input type="Radio" name="colour" value="red" checked>red
<input type="Radio" name="colour" value="blue">blue
 pills, willya?
</font>

<p>

<input type="Submit">
</form>

</center>
</body>

</html>

And here's "pills.jsp".

<html>
<head>
<basefont face="Arial">
</head>

<body>
<center>
<%
// pills.jsp

// define the variables and assign values
String colour = request.getParameter("colour");
String quantity_string = request.getParameter("quantity");

// convert string to number
int quantity = Integer.parseInt(quantity_string);

// process and display

// who needs green pills?
if (colour.equals("blue"))
{
out.println("Sorry, we don't carry blue pills here.");
}
else
{
    if (quantity >= 50)
    {
    out.println("Stocking up, are we?");
    }
    else
    {
    out.println("Here you go. And would you like fries with that?");
    }
}
%>
</center>
</body>
</html>

Depending on the combination of pill type and quantity, an appropriate message will be displayed.

As you can see, evaluating radio buttons and list boxes is almost exactly the same as evaluating regular text fields.

Before moving on to the other form constructs - namely, checkboxes and multiple-select list boxes - you need to understand a new type of variable: the JSP array.

What's For Dessert?

Thus far, the variables you've used contain only a single value - for example,

int i = 0

However, array variables are a different kettle of fish altogether. An array variable can best be thought of as a "container" variable, which can contain one or more values. For example,

String[] desserts = {"chocolate mousse", "tiramisu", "apple pie", "chocolate fudge cake"};

Here, "desserts" is an array variable, which contains the values "chocolate mousse", "tiramisu", "apple pie", and "chocolate fudge cake".

Array variables are particularly useful for grouping related values together - names, dates, phone numbers of ex-girlfriends et al.

The various elements of the array are accessed via an index number, with the first element starting at zero. So, to access the element

"chocolate mousse"

you would use the notation

desserts[0]

while

"chocolate fudge cake"

would be

desserts[3]

Essentially, the array variable name followed by the index number enclosed within square braces. Geeks refer to this as "zero-based indexing".

Defining an array variable in JSP is somewhat convoluted, as compared to languages like PHP and Perl; you need to first declare the variable and its type, and then actually create the array.

<%
// declare type of array
String[] desserts;

// initialize array
// the number indicates the number of elements the array will hold
desserts = new String[4];

// assign values to array elements
desserts[0] = "chocolate mousse";
desserts[1] = "tiramisu";
desserts[2] = "apple pie";
desserts[3] = "chocolate fudge cake";
%>

Or you can use the simpler version:

<%
String[] desserts = {"chocolate mousse", "tiramisu", "apple pie", "chocolate fudge cake"};
%>

Note that if you try to add more elements than the number specified when creating the array, JSP will barf with a series of strange error message.

A Chocolate Addiction

In order to modify an element of an array, you would simply assign a new value to the corresponding variable. If you wanted to replace "chocolate fudge cake" with "chocolate chip cookies", you'd simply use

<%
desserts[3] = "chocolate chip cookies";
%>

and the array would now read

String[] desserts = {"chocolate mousse", "tiramisu", "apple pie", "chocolate chip cookies"};

JSP arrays can only store the type of data specified at the time of declaring the array variable; a string array cannot hold numbers, or vice-versa.

And finally, you can obtain the number of items in an array with the "length" property - the following example demonstrates this:

<html>
<head>
<basefont face="Arial">
</head>

<body>
<%
// define an array
String[] desserts = {"chocolate mousse", "tiramisu", "apple pie", "chocolate fudge cake"};

// display array length
out.println("The dessert menu contains " + desserts.length + " items.");
 %>
 </body>
</html>

And the output is:

The dessert menu contains 4 items.

You can use a "for" loop to iterate through the elements of an array, as the following example demonstrates.

<html>
<head>
<basefont face="Arial">
</head>

<body>
Desserts available:
<ul>

<%
// define counter
int counter;

// define an array
String[] desserts = {"chocolate mousse", "tiramisu", "apple pie", "chocolate fudge cake"};

for (counter=0; counter<desserts.length; counter++)
{
out.println("<li>" + desserts[counter] + "<br>");
}
 %>

</ul>
</body>
</html>

And the output is:

Desserts available:
· chocolate mousse
· tiramisu
· apple pie
· chocolate fudge cake

Couch Potato

Arrays come in particularly handy when dealing with form elements like checkboxes and multiple select list boxes. Take a look at the following form, which includes a bunch of checkboxes:

<html>
<head>
<basefont face="Arial">
</head>
<body>

Pick your favourite shows:
<br>
<form action="potato.jsp" method="POST">
<input type="checkbox" name="shows" value="Ally McBeal">Ally McBeal
<input type="checkbox" name="shows" value="Buffy The Vampire Slayer">Buffy The Vampire Slayer
<input type="checkbox" name="shows" value="The Practice">The Practice
<input type="checkbox" name="shows" value="Sex And The City">Sex And The City
<input type="checkbox" name="shows" value="The Sopranos">The Sopranos
<input type="checkbox" name="shows" value="Survivor">Survivor
<br>
<input type="submit" name="submit" value="Select">
</form>

</body>
</html>

Now, once the form is submitted, the JSP script "potato.jsp" is responsible for processing the states of the various checkboxes. Data from the checkboxes is assigned to an array, and then this array is used to recreate a list of the selected items. Take a look.

<html>
<head>
<basefont face="Arial">
</head>
<body>

So your favourite shows are:
<br>
<%

// potato.jsp - process list of selected TV shows

// define variables
String[] Shows;

// assign values to variables
Shows = request.getParameterValues("shows");

out.println("<ul>");

// print by iterating through array
for(int counter = 0; counter < Shows.length; counter++)
{
    out.println("<li>" + Shows[counter]);
}

out.println("</ul>");
%>

</body>
</html>

As you can see, the first order of business is to create an array to hold the checkbox data - in this case, the array "Shows". Then, the Request object is used to obtain the values of the selected items via the getParameterValues() method (similar to the getParameter() method, but returns a list of values, rather than a single value) and these values are then assigned to the "Shows" array. A "for" loop is then used to create a list of the selected items.

This technique can also be used with multiple select list boxes - here's the same example, rewritten to use a list box instead of a series of checkboxes.

<html>
<head>
<basefont face="Arial">
</head>
<body>

Pick your favourite shows:
<br>
<form action="potato.jsp" method="POST">
<select name="shows" multiple>
    <option>Ally McBeal</option>
    <option>Buffy The Vampire Slayer</option>
    <option>The Practice</option>
    <option>Sex And The City</option>
    <option>The Sopranos</option>
    <option>Survivor</option>
</select>
<br>
<input type="submit" name="submit" value="Select">
</form>

</body>
</html>

Obviously, the server-side script "potato.jsp" requires no changes at all.

Beating It Into Submission

You'll have noticed that in all the examples we've shown you thus far, we've used two pages - a single HTML page containing the form, and a separate JSP script which processes the form input and generates appropriate output. However, JSP provides an elegant method to combine those two pages into one via the form's SUBMIT button.

You've already seen that once a form is submitted to a JSP script, all the form variables become available to JSP. Now, in addition to the user-defined variables, each time you hit the SUBMIT button on a form, a variable named "submit" is created. And by testing for the presence or absence of this variable, a clever JSP developer can use a single JSP document to generate both the initial form and the output after it has been submitted.

The following code snippet demonstrates how the "welcome to The Matrix" example above could be rewritten using this technique.

<html>
<head>
<basefont face="Arial">
</head>

<body>
<center>
<%
// matrix.jsp

// check for submit variable
String submit = request.getParameter("submit");

if(submit != null)
{
// form has been submitted, display result

// define the variables used in the scriptlet
String fname;

// assign values
fname = request.getParameter("name");

// print the details
out.println("Welcome to The Matrix, " + fname + "!");

}
else
{
// display initial form
%>

<form method="GET" action="matrix.jsp">
<table cellspacing="5" cellpadding="5" border="0">

<tr>
<td>
<font size="-1">Name, rank and serial, number, soldier!</font>
</td>
<td align="left">
<input type="text" name="name" size="10">
</td>
</tr>

<tr>
<td colspan="2" align="center">
<input name="submit" type="submit">
</td>
</tr>

</table>
</form>

<%
}
%>
</center>
</body>
</html>

As you can see, the script first tests for the presence of the "submit" variable - if it doesn't find it, it assumes that the form has yet to be submitted and so displays the initial form.

Since the ACTION attribute of the <FORM> tag references the same JSP script, once the form has been submitted, the same script will be called to process the form input. This time, however, the "submit" variable will exist, and so JSP will not display the initial page, but rather the result page.

Note that for this to work, your

<input type="submit">

must have a NAME attribute with the value "submit", like this:

<input type="submit" name="submit">

And that's about it. Next time, we'll be hooking JSP up to a database in order to generate dynamic Web page - so don't miss that one. Until then...stay healthy!

Note: All examples in this article have been tested on Linux/i586 with Tomcat 3.2 and JServ 1.1. Examples are illustrative only, and are not meant for a production environment. YMMV!

This article was first published on28 Feb 2001.