The JSP Files (part 3): Black Light And White Rabbits

More String object methods, and a tour of the various control structures available in JSP.

Counting Down

Last time out, you learned a little bit about the various conditional statements and operators available in JSP. This week, we'll expand on those basics by teaching you a little bit about the different types of loops available in JSP, discuss a few more String object methods, and take a quick tour of the new Response object.

First up, loops.

As you may already know, a "loop" is a programming construct that allows you to execute a set of statements over and over again, until a pre-defined condition is met.

The most basic loop available in JSP is the "while" loop, and it looks like this:

while (condition)
    {
    do this!
    }

Or, to make the concept clearer,

while (temperature is below freezing)
    {
    wear a sweater
    }

The "condition" here is a standard conditional expression, which evaluates to either true or false. So, were we to write the above example in JSP, it would look like this:

while (temp <= 0)
    {
    sweater = true;
    }

Here's an example:

<html>
<head>
</head>
<body>
<%!
int countdown=30;
 %>
<%
while (countdown > 0)
{
out.println(countdown + "&nbsp;");
countdown--;
}
out.println("<b>Kaboom!</b>");
 %>
</body>
</html>

Here, the variable "countdown" is initialized to 30, and a "while" loop is used to decrement the value of the variable until it reaches 0. Once the value of the variable is 0, the conditional expression evaluates as false, and the lines following the loop are executed.

Here's the output:

30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 Kaboom!

Doing More With Loops

There's one caveat with the "while" loop. If the conditional expression evaluates as false the first time, the code within the curly braces will never be executed. If this is not what you want, take a look at the "do-while" loop, which comes in handy in situations where you need to execute a set of statements at least once.

Here's what it looks like:

do
    {
    do this!
    } while (condition)

For example, the following lines of code would generate no output whatsoever, since the conditional expression in the "while" loop would always evaluate as false.

<%
int bingo = 366;

while (bingo == 699)
    {
    out.println ("Bingo!");
    break;
    }
%>

However, the construction of the "do-while" loop is such that the statements within the loop are executed first, and the condition to be tested is checked after. Using a "do-while" loop implies that the code within the curly braces will be executed at least once - regardless of whether or not the conditional expression evaluates as true.

<%
int bingo = 366;

do
    {
    out.println ("Bingo!");
    break;
    } while (bingo == 699);
%>

Try it yourself and see the difference.

For-gone Conclusion

Both the "while" and "do-while" loops continue to iterate for so long as the specified conditional expression remains true. But there often arises a need to execute a certain set of statements a specific number of times - for example, printing a series of thirteen sequential numbers, or repeating a particular set of <TD> cells five times. In such cases, clever programmers reach for the "for" loop...

The "for" loop typically looks like this:

for (initial value of counter; condition; update counter)
    {
    do this!
    }

Looks like gibberish? Well, hang in there a minute...the "counter" here is a JSP variable that is initialized to a numeric value, and keeps track of the number of times the loop is executed. Before each execution of the loop, the "condition" is tested - if it evaluates to true, the loop will execute once more and the counter will be appropriately incremented; if it evaluates to false, the loop will be broken and the lines following it will be executed instead.

And here's a simple example that demonstrates how this loop can be used:

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

<body>
<center>Turning The Tables, JSP-Style!</center>
<br>
<%!
// define the number
int number = 7;
int x;
 %>
<%
// use a for loop to calculate tables for that number
for (x=1; x<=15; x++)
    {
    out.println(number + " X " + x + " = " + (number*x) + "<br>");
    }
 %>

</body>
</html>

And here's the output:

Turning The Tables, JSP-Style!

7 X 1 = 7
7 X 2 = 14
7 X 3 = 21
7 X 4 = 28
7 X 5 = 35
7 X 6 = 42
7 X 7 = 49
7 X 8 = 56
7 X 9 = 63
7 X 10 = 70
7 X 11 = 77
7 X 12 = 84
7 X 13 = 91
7 X 14 = 98
7 X 15 = 105

Let's dissect this a little bit:

Right up front, a variable is defined, containing the number to be used for the multiplication table; we've used 7 here - you might prefer to use another number.

Next, a "for" loop has been constructed, with "x" as the counter variable. If you take a look at the first line of the loop, you'll see that "x" has been initialized to 1, and is set to run no more than 15 times.

Finally, the println() function is used to take the specified number, multiply it by the current value of the counter, and display the result on the page.

The Sound Of Breaking Loops

When dealing with loops, there are two important keywords you should be aware of: "break" and "continue".

The "break" keyword is used to exit a loop when it encounters an unexpected situation. A good example of this is the dreaded "division by zero" error - when dividing one number by another one (which keeps decreasing), it is advisable to check the divisor and use the "break" statement to exit the loop as soon as it becomes equal to zero.

As you've already seen, the "continue" keyword is used to skip a particular iteration of the loop and move to the next iteration immediately - it's demonstrated in the following example:

<%
int x;
for (x=1; x<=10; x++)
        {
        if (x == 7)
                {
                continue;
                }
        else
                {
                out.println(x + "&nbsp;");
                }
        }
 %>

In this case, JSP will print a string of numbers from 1 to 10 - however, when it hits 7, the "continue" statement will cause it to skip that particular iteration and go back to the top of the loop. So your string of numbers will not include 7 - try it and see for yourself.

Paying The Piper

You've already seen a few of the String object's capabilities in the first part of this tutorial. But as we progress further, you're going to need to know a little bit more to make full use of its power.

First, there's the indexOf() method, which is used to locate the first occurrence of a character or substring in a larger string. If you ran the following code snippet,

<%
// define variable
String storyName = "The Pied Piper Of Hamlin";

// find index
int i = storyName.indexOf("i");

// print index
out.println("The letter i first occurs at " + i + " in the string " + storyName);
 %>

this is what you would see:

The letter i first occurs at 5 in the string The Pied Piper Of Hamlin

Yes, the first character is treated as index 0, the second as index 1, and so on. These programmers...

The opposite of this is the lastIndexOf() function, used to identify the last occurrence of a character or substring in a larger string. Take a look:

<%
// define variable
String storyName = "The Pied Piper Of Hamlin";

// find index
int i = storyName.lastIndexOf("Pi");

// print index
out.println("The string Pi last occurs at " + i + " in the string " + storyName);
 %>

And the output is

The string Pi last occurs at 9 in the string The Pied Piper Of Hamlin

In case the character or substring is not located, the function will return an error code of -1.

Screaming Out Loud

Next, the trim() function comes in handy when you need to remove white space from the ends of a string.

<%
// define variable
String whatIWant = "   gimme  my      space        ";

// trim!
// returns "gimme  my      space"
whatIWant.trim();
 %>

The toUpperCase() and toLowerCase() methods come in handy to alter the case of a string.

<%
// define variable
String someString = "don't SCREam, help is oN the WAy!";

// uppercase - returns "DON'T SCREAM, HELP IS ON THE WAY!"
someString.toUpperCase();

// lowercase - returns "don't scream, help is on the way!"
someString.toLowerCase();
 %>

The startsWith() and endsWith() functions are used to verify whether a string starts or ends with a specified character or sequence of characters. The following example should illustrate this clearly.

<%
// define variables
String alpha = "black light";
String beta = "white rabbit";
String prefix = "bl";
String suffix = "it";

// check each string for prefixes and suffixes

if (alpha.startsWith(prefix))
{
out.println("The string " + alpha + " starts with " + prefix + "<br>");
}

if (beta.startsWith(prefix))
{
out.println("The string " + beta + " starts with " + prefix + "<br>");
}

if (alpha.endsWith(suffix))
{
out.println("The string " + alpha + " ends with " + suffix + "<br>");
}

if (beta.endsWith(suffix))
{
out.println("The string " + beta + " ends with " + suffix + "<br>");
}

 %>

And the output is:

The string black light starts with bl
The string white rabbit ends with it

You Say Seven, I Say 7

And finally, in case you've ever wanted to convert strings to numbers, the following example should tell you everything you need to know.

<%
// converting a string to a number

// define variables
String someString = "97";
int aRandomNumber = 3;

// at this stage, someString is still treated as a string
out.println(someString + " plus " + aRandomNumber + " equals " + (someString+aRandomNumber) + "<p>");

// now convert someString to a number
int someNumber = Integer.parseInt(someString);

// at this stage, someString has been converted to a number, stored in someNumber
out.println(someNumber + " plus " + aRandomNumber + " equals " + (someNumber+aRandomNumber));

 %>

And here's the output.

97 plus 3 equals 973
97 plus 3 equals 100

If you'd prefer to do things the other way around, the next example bears careful consideration.

<%
// define variables
int someNumber = 97;
int aRandomNumber = 3;

// at this stage, someNumber is still treated as a number
out.println(someNumber + " plus " + aRandomNumber + " equals " + (someNumber+aRandomNumber) + "<p>");

// now convert someNumber to a string
String someString = Integer.toString(someNumber);

// at this stage, someNumber has been converted to a string, stored in someString
out.println(someString + " plus " + aRandomNumber + " equals " + (someString+aRandomNumber));

 %>

And here's the output.

97 plus 3 equals 100
97 plus 3 equals 973

The upshot? parseInt() and toString() are your best friends when converting between string and numeric data types in JSP.

A Positive Response

Another interesting object, and one that comes in handy in the oddest places, is the Response object. As opposed to the Request object, which is used to retrieve information (come back next time for more on this), the Response object is typically used to send information to the browser; this information could include HTTP headers, redirection URLs, cookies and a variety of other items.

Since the Response 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), you can begin using it immediately in a JSP document. The following example demonstrates using it to turn off caching via the "Cache-Control" header.

<%
response.setHeader("Cache-Control","no-cache");
 %>

You can also use it to redirect the client to another URL.

<%
response.setHeader("Location", "error.html");
 %>

You can use the sendRedirect() method to accomplish something similar - remember to use an absolute URL here.

<%
response.sendRedirect("http://my.server.com/error.html");
 %>

You can set the MIME type of a document with the setContentType() method.

<%
response.setContentType("image/jpeg");
 %>

and even set a cookie with the addCookie() method - more on this as we progress through this series.

That's about all we have time for. Next time, we'll be exploring the JSP Response object, used to process data from HTML forms...so you don't want to miss that one!

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 on23 Feb 2001.