Pages

Saturday, February 27, 2010

Basics of Java Programming

Supplementary Objectives
•Introduce the basic terminology and concepts in object-oriented
programming: classes, objects, references, fields, methods, members,
inheritance, aggregation.
•Identify the essential elements of a Java program.
•Learn how to compile and run a Java program.

Introduction

Before embarking on the road to Java programmer certification, it is important to
understand the basic terminology and concepts in object-oriented programming
(OOP). In this chapter, the emphasis is on providing an introduction rather than
exhaustive coverage. In-depth coverage of the concepts follows in subsequent
chapters of the book.
Java supports the writing of many different kinds of executables: applications,
applets, and servlets. The basic elements of a Java application are introduced in
this chapter. The old adage that practice makes perfect is certainly true when learn-
ing a programming language. To encourage programming on the computer, the
mechanics of compiling and running a Java application are outlined

Classes
One of the fundamental ways in which we handle complexity is in abstractions. An
abstraction denotes the essential properties and behaviors of an object that
differentiate it from other objects. The essence of OOP is modelling abstractions,
using classes and objects. The hard part in this endeavor is finding the right
abstraction.
A class denotes a category of objects, and acts as a blueprint for creating such
objects. A class models an abstraction by defining the properties and behaviors for
the objects representing the abstraction. An object exhibits the properties and
behaviors defined by its class. The properties of an object of a class are also called
attributes, and are defined by fields in Java. A field in a class is a variable which can
store a value that represents a particular property of an object. The behaviors of an
object of a class are also known as operations, and are defined using methods in Java.
Fields and methods in a class declaration are collectively called members.
An important distinction is made between the contract and the implementation that
a class provides for its objects. The contract defines what services, and the imple-
mentation defines how these services are provided by the class. Clients (i.e., other
objects) only need to know the contract of an object, and not its implementation, in
order to avail themselves of the object’s services.
As an example, we will implement different versions of a class that models the
abstraction of a stack that can push and pop characters. The stack will use an array
of characters to store the characters, and a field to indicate the top element in the
stack. Using Unified Modeling Language (UML) notation, a class called CharStack
is graphically depicted in Figure 1.1, which models the abstraction.

Declaring Members: Fields and Methods
Example 1.1 shows the declaration of the class CharStack depicted in Figure 1.1. Its
intention is to illustrate the salient features of a class declaration in Java, and not
the effective implementation of stacks.
A class declaration consists of a series of member declarations. In the case of the
class CharStack, it has two fields declared at (1):
• stackArray , which is an array to hold the elements of the stack (in this case,
characters)
• topOfStack, which denotes the top element of the stack (i.e., the index of the last
character stored in the array)
The class CharStack has five methods, declared at (3), that implement the essential
operations on a stack:
• push() pushes a character on to the stack
• pop() removes and returns the top element of the stack
• peek() returns the top element of the stack for inspection
• isEmpty() determines whether the stack is empty
• isFull() determines whether the stack is full
The class declaration also has a method-like declaration with the same name as the
class, (2). Such declarations are called constructors. As we shall see, a constructor is
executed when an object is created from the class. However, the implementation
details in the example are not important for the present discussion.


Objects
Class Instantiation, Reference Values, and References
The process of creating objects from a class is called instantiation. An object is an
instance of a class. The object is constructed using the class as a blueprint and is
aconcrete instance of the abstraction that the class represents. An object must be
created before it can be used in a program.
A reference value is returned when an object is created. A reference value denotes a
particular object. An objectreference (or simply reference) is a variable that can store
a reference value. A reference thus provides a handle to an object, as it can indi-
rectly denote an object whose reference value it holds. In Java, an object can only
be manipulated via its reference value, or equivalently by a reference that holds its
reference value.
The process of creating objects usually involves the following steps:
1.Declaration of a variable to store the reference value of an object.
This involves declaring a reference variable of the appropriate class to store the
reference value of the object.
// Declaration of two reference variables that will refer to
// two distinct objects, namely two stacks of characters, respectively.
CharStack stack1, stack2;
2.Creating an object.
This involves using the new operator in conjunction with a call to a constructor,
to create an instance of the class.
// Create two distinct stacks of chars.1.3: OBJECTS 5
stack1 = new CharStack(10); // Stack length: 10 chars
stack2 = new CharStack(5);// Stack length: 5 chars
The new operator creates an instance of the CharStack class and returns the ref-
erence value of this instance. The reference value can be assigned to a reference
variable of the appropriate class. The reference variable can then be used to
manipulate the object whose reference value is stored in the reference variable.
Each object has its own copy of the fields declared in the class declaration. The
two stacks, referenced by stack1 and stack2, will have their own stackArray and
topOfStack fields.
The purpose of the constructor call on the right side of the new operator is
to initialize the newly created object. In this particular case, for each new
CharStack instance created using the new operator, the constructor creates an
array of characters. The length of this array is given by the value of the argu-
ment to the constructor. The constructor also initializes the topOfStack field.
The declaration of a reference and the instantiation of the class can also be com-
bined, as in the following declaration statement:
CharStack stack1 = new CharStack(10),
stack2 = new CharStack(5);
Figure 1.2 shows the UML notation for objects. The graphical representation of an
object is very similar to that of a class. Figure 1.2 shows the canonical notation,
where the name of the reference variable denoting the object is prefixed to the class
name with a colon (':'). If the name of the reference variable is omitted, as in Fig-
ure 1.2b, this denotes an anonymous object. Since objects in Java do not have
names, but are denoted by references, a more elaborate notation is shown in Figure
1.2c, where objects representing references of the CharStack class explicitly refer to
CharStack objects. In most cases, the more compact notation will suffice

Index

Basics of Java Programming
Language Fundamentals
Declarations
AccessControl
Operators and Expressions
Control Flow
Object-Oriented Programming
Nested Type Declarations
Object Lifetime
Fundamental Classes
Files and Streams
Localization, Pattern Matching and Formatting
Threads
Generics
Collections and Maps
Taking the SCJP 1.6 Exam
Objectives for the SCJP 1.6 Exam
Objectives for the SCJP 1.6 Upgrade Exam
Annotated Answers toReview Questions
Solutions to ProgrammingExercises
Mock Exam
Number Systems and Number Representation

Contents at a Glance

Surviving Setup

Selecting the Right Windows 7 Edition ..
Installing or Upgrading to Windows 7 ...
Hardware and Software Compatibility .

The New and Improved Windows 7 User Experience
What’s New in the Windows 7 User Experience
Where’s My Stuff? Finding and Organizing Files
Personalizing and Confguring Windows 7 .
Security and Networking
Windows 7 Security Features
Users, Accounts, and UAC
Networking and HomeGroup Sharing.
Complete Your Home Network with Windows Home Server
Digital Media and Entertainment
Digital Music and Audio
Organizing, Fixing, and Sharing Digital Photos
Digital Videos and DVD Movies
Microsoft Zune: A Digital Media Alternative
Digital Media in the Living Room
Having Fun: Games and Windows 7
Mobility
Seven to Go: Windows 7 Mobility Features
Using Tablet PCs and Ultra-Mobile PCs
Windows in Your Pocket—Using a Windows Mobile Smartphone
Windows 7 Online
Browsing the Web
Managing E-mail and Contacts
Managing Your Schedule
Your Life in Sync—Windows 7 and Live Services
Windows 7 Power User
Keeping Your Data Safe: File and PC Backup
Troubleshooting and Recovering from Disaster
IT Pro: Windows 7 at Work

About the Technical Editors

Todd Meister has been developing using Microsoft technologies for over 15 years. He’s
been a Technical Editor on over 50 titles ranging from SQL Server to the .NET Framework.
Besides technical editing titles, he is an Assistant Director for Computing Services at Ball
State University in Muncie, Indiana. He lives in central Indiana with his wife, Kimberly,
and their four children.
Joli Ballew is a Microsoft MVP and holds several Microsoft certifcations including MCSE,
MCDST, and MCTS. Joli has written over 30 books, teaches at two local junior colleges,
manages the network and Web site for North Texas Graphics, and regularly writes for
several Web sites. In her spare time, Joli enjoys gardening, golfng, and traveling.

Example Web Application Overview

The examples for this book are packaged as a standard Java web application, as described in Chapter 2. All servers compliant with the JSP 2.0 specification support this file structure, so you can use the example application as a guideline when you create your own web applications. How a web application is installed isn't defined by the specification, however, so it varies between servers. With Tomcat, you simply copy the file structure to the special webapps directory and restart the server. To modify the configuration information for an application, you need to edit the application's WEB-INF/web.xml file using a text editor. Other servers may offer special deployment tools that copy the files where they belong and let you configure the application using a special tool or through web-based forms.

If you look in the ora web application directory, you see that it contains an index.html file and a number of directories corresponding to chapters in this book. These directories contain all the example JSP and HTML pages.

There's also a WEB-INF directory with a web.xml file, a lib directory, and a classes directory. We will look at this in much more detail later, starting in Chapter 5, but here's a quick review:

The web.xml file contains configuration information for the example application in the format defined by the servlet and JSP specifications. It's too early to look at the contents of this file now; we will return to parts of it when needed.

The lib and classes directories are standard directories, also defined by the servlet specification. A very common question asked by people new to servlets and JSP (prior to the standard web application format) was, "Where do I store my class files so that the server can find them?" The answer, unfortunately, differed depending on which implementation was used. With the standard web application format, it's easy to answer this question: if the classes are packaged in a JAR file, store the JAR file in the lib directory; otherwise use the classes directory (with subdirectories mirroring the classes' package structure). The server will always look for Java class files in these two directories.

The lib directory for the example application contains a number of JAR files. The orataglib_3_0.jar file contains all the Java class files for the custom actions used in this book, oraclasses_3_0.jar contains the class files for beans and servlets used in the examples, struts.jar contains the Struts framework classes described in Chapter 19, and jdom.jar contains JDOM classes used for a validator example in Chapter 22. The other JAR files contain the JSTL Reference Implementation plus all the packages that the JSTL implementation depends on.

The classes directory contains the class for the JSPSourceServlet that displays the raw source code for the example JSP pages, so you can see what they look like before they are processed by the server. It also contains all .properties files with localized text for the example in Chapter 14 and a few test servlets described in Chapter 19.

If you want to try some of your own JSP pages, beans, and custom actions while reading this book, simply add the files to the example application structure: JSP pages in any directory except under WEB-INF, and Java class files in either the classes or the lib directory depending on if the classes are packaged in a JAR file or not. If you want to use the book's custom actions in another application, copy the orataglib_3_0.jar file to the WEB-INF/lib directory for the other application.

Installing the Book Examples

All JSP pages, HTML pages, Java source code, and class files for the examples can be downloaded from the O'Reilly site http://www.oreilly.com/catalog/jserverpages3/.

They can also be downloaded from the book web site that I maintain: http://www.TheJSPBook.com/.

On this site you find a Download page where you can download the file, called jspbook3.zip. Save the file on your hard drive, for instance in C:\JSPBook on a Windows platform, and unpack it:

C:\JSPBook> jar xvf jspbook3.zip
You can use the same command on a Unix platform.

Two new directories are created: ora and src. The first directory contains all examples described in this book, and the second contains the Java source files for the JavaBeans, custom actions, servlets, and utility classes used in the examples.

The examples directory structure complies with the standard Java web application format described in Chapter 2. You can therefore configure any JSP 2.0-compliant web container to run the examples.

If you like to use a container other than Tomcat, be sure to read the documentation for that container for instructions on how to install a web application.

To install the example application for Tomcat, simply copy the web application directory structure (the ora directory) to Tomcat's default directory for applications, called webapps. On a Windows platform, you can copy/paste the directory structure with the Windows Explorer tool, or use this command in a Command Prompt window:

C:\JSPBook> xcopy /s /i ora %CATALINA_HOME%\webapps\ora
On a Unix platform it looks like this:

[hans@gefion jspbook] cp -R ora $CATALINA_HOME/webapps
Recall from Chapter 2 that each web application in a server is associated with a unique URI prefix (the context path). When you install an application in Tomcat's webapps directory, the subdirectory name is assigned automatically as the URI prefix for the application (that is, /ora in this case).

At this point, you must shut down and restart the Tomcat server. After that, you can point your browser to the ora application with the following URL: http://localhost:8080/ora/.

You should see a start page, as in Figure 4-3, that contains links for all examples in this book.

Testing Tomcat

The Tomcat installation directory contains a number of subdirectories. All of them are described in the README.txt file, but the most important ones are:




bin

Scripts for starting and stopping the Tomcat server.




conf

Tomcat configuration files.




webapps

Default l ocation for web applications served by Tomcat.

Two more subdirectories under the Tomcat home directory are created the first time you start the server:




logs

Server log files. If something doesn't work as expected, look in the files in this directory for clues as to what's wrong.




work

A directory for temporary files created by the JSP container and other files. This directory is where the servlets generated from JSP pages are stored.

To test the server, run the startup script as described in the platform-specific sections, and (assuming you're running Tomcat on the same machine as the browser and that you're using the default 8080 port for Tomcat) open a browser and enter this URL in the Location/Address field: http://localhost:8080/.

The Tomcat main page is shown in the browser, as in Figure 4-2, and you can now run all servlet and JSP examples bundled with Tomcat to ensure everything works.





If you're trying this on a machine that sits behind a proxy, for instance on a corporate network, and instead of Tomcat's main page you see an error message about not being able to connect to localhost, you need to adjust your proxy settings. For Netscape 6 and Mozilla, you find the proxy settings under Edit Preferences Advanced Proxies, and for Internet Explorer 5, you find them under Tools Internet Options Connections LAN Settings. Make sure that the proxy isn't used for local addresses, such as localhost and 127.0.0.1.

When you're done testing Tomcat, you stop the server like this:

C:\Jakarta\jakarta-tomcat-5.0.12\bin> shutdown

Installing the Tomcat Server

Tomcat supports many features and configuration options. In this section, I only describe the basics that you must know to get Tomcat up and running. If you plan to use Tomcat extensively for development or as a production server, refer to Tomcat: The Definitive Guide by Jason Brittain and Ian Darwin (O'Reilly).

You can download the Tomcat server in binary format or as source code that you compile yourself. If you're primarily interested in learning about JSP, I recommend that you use the binary download for running the examples in this book and to develop your own applications. If you're a Java programmer and are interested in seeing how Tomcat is implemented, feel free to download the source as well and take a look at the internals.

The binary distribution is available at http://jakarta.apache.org/site/binindex.cgi.

On this page you find three types of builds: release builds, milestone builds, and nightly builds. Release builds are stable releases that have been tested extensively and verified to comply with the servlet and JSP specifications. Milestone builds are created as intermediary steps towards a release build. They often contain new features that aren't yet fully tested but are generally known to work. A nightly build, however, may be very unstable. It's actually a snapshot of the latest source code and may have been tested only by the person who made the latest change. You should use a nightly build only if you're involved in the development of Tomcat.

I recommend that you download the latest release build. All examples in this book were developed and tested using the 5.0.12 version, but any release later than 5.0.12 should work fine as well. When you click on the link for the latest release build and select the bin directory, you see a list of archive files in different formats, similar to Figure 4-1.

Figure 4-1. Release build packages

How to continue from here varies a bit depending on your platform.

4.2.1 Windows Platforms
For Windows, select jakarta-tomcat-5.0.12.zip[1] and save it to your hard drive, for instance in a directory named C:\Jakarta. You can unpack the package either with a ZIP utility program, such as WinZip, or by using the jar command that's included in the Java distribution. Use the Command Prompt window where you set the JAVA_HOME and PATH environment variables earlier, change to the directory in which you downloaded the ZIP file, and unpack it:

[1] There's also a file with an .exe extension in the list of downloads. This is a GUI installer for Windows. While it simplifies the installation, it makes it almost impossible to debug installation problems, and it doesn't work at all for older versions of Windows, e.g., Windows ME. I suggest that you use the command-line installation process described in this chapter, at least until you're familiar enough with Tomcat to handle the GUI installer issues.

C:\> cd Jakarta
C:\Jakarta> jar xvf jakarta-tomcat-5.0.12.zip
This creates a directory structure with a top directory named jakarta-tomcat-5.0.12 with a number of subdirectories. Like most software packages, the top directory contains a file named README.txt; do exactly that. Software distributions change and if, for instance, the instructions in this chapter no longer apply when you download the software, the README.txt file should contain information about how to get started. Additional details are found in the file named RUNNING.txt.

You should also set the CATALINA_HOME environment variable to point to the Tomcat installation directory:

C:\Jakarta> set CATALINA_HOME=C:\Jakarta\jakarta-tomcat-5.0.12
If you wonder about the variable name, Catalina is the name of the servlet container, and Jasper is the name of the JSP container; together they are known as the Tomcat server.

The Tomcat installation directory contains a number of subdirectories, described later. The bin directory contains Windows batch files for starting and stopping the server. The batch files are named startup.bat, shutdown.bat, and catalina.bat. The catalina.bat file is the main script for controlling the server; it's called by the two other scripts: startup.bat and shutdown.bat. To start the server in a separate window, change to the bin directory and run the startup.bat file:

C:\Jakarta> cd jakarta-tomcat-5.0.12\bin
C:\Jakarta\jakarta-tomcat-5.0.12\bin> startup
A new Command Prompt window pops up, and you see startup messages similar to this:

Aug 13, 2003 12:53:59 PM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on port 8080
Aug 13, 2003 12:53:59 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 2260 ms
...
INFO: Server startup in 7408 ms
Just leave this window open; this is where the server process is running.

If you're running this on a Windows 95/98/ME platform, you may see an error message "Out of environment space," when you try to start the server. That's because the default amount of space allocated for environment variables isn't enough. To be able to run Tomcat, run this command in the Command Prompt window before you run the startup.bat file again:

C:\Jakarta\jakarta-tomcat\bin> COMMAND.COM /E:4096 /P
This command sets the environment space to 4096 bytes (4 KB). That should be enough for running this batch file. If you still get the same message, use a higher value.

For some installations, this command may not work. If it doesn't, try this instead:

Close the Command Prompt window, and open a new one.

Click on the MS-DOS icon at the top left of the window.

Select the Properties option.

Click on the Memory tab.

Change the Initial Environment value from Auto to 4096.

Click on OK and try to start the server again.

At this point, the server may not start due to other problems. If so, the extra Command Prompt window may pop up and then disappear before you have a chance to read the error messages. If this happens, you can let the server run in the Command Prompt window with this command instead:

C:\Jakarta\jakarta-tomcat-5.0.12\bin> catalina run
On Windows NT/2000 and Windows XP, you should first make sure that the Command Prompt window has a large enough screen buffer so that you can scroll back in case the error messages don't fit on one screen. Open the Properties window for the Command Prompt window (right mouse button in the upper left corner), select Layout and set the screen buffer size height to a large value (for instance 999). Unfortunately, the Command Prompt screen buffer can't be enlarged for Windows 95/98/ME, so scrolling back isn't an option. If you run into problems on these platforms, double-check that you have installed the Java SDK correctly and that you have set the JAVA_HOME and PATH environment variables as described earlier.

4.2.2 Unix Platforms (Including Linux and Mac OS X)
For Unix platforms, you can download the jakarta-tomcat-5.0.12.tar.gz file, for instance to /usr/local, and use these commands to unpack it (assuming you have GNU tar installed):

[hans@gefion /] cd /usr/local
[hans@gefion local] tar xzvf jakarta-tomcat-5.0.12.tar.gz
If you don't have GNU tar installed on your system, use the following command:

[hans@gefion local] gunzip -c jakarta-tomcat-5.0.12.tar.gz | tar xvf -
As on Windows, this creates a directory structure with a top directory named jakarta-tomcat-5.0.12 with a number of subdirectories.

You should also set the CATALINA_HOME environment variable to point to the Tomcat installation directory:

[hans@gefion local] export CATALINA_HOME=/usr/local/jakarta-tomcat-5.0.12
If you wonder about the variable name, Catalina is the name of the servlet container and Jasper is the name of the JSP container; together they are known as the Tomcat server.

The Tomcat installation directory contains a number of subdirectories, described later. The bin directory contains Unix scripts for starting and stopping the server. The scripts area named startup.sh, shutdown.sh, and catalina.sh.

Start the server in the background with this command:

[hans@gefion jakarta-tomcat-5.0.12] ./startup.sh
If you want to have Tomcat start each time you boot the system, you can add the following commands to your /etc/rc.d/rc.local (or equivalent) startup script:

export JAVA_HOME=/usr/local/jdk1.4.2
export CATALINA_HOME=/usr/local/jakarta-tomcat-5.0.12
$CATALINA_HOME/bin/startup.sh

Installing the Java Software Development Kit

Tomcat 5 is a pure Java web server with support for the Servlet 2.4 and JSP 2.0 specifications. In order to use it, you must first install a Java runtime environment. If you don't already have one, you can download a Java runtime for Windows, Linux, and Solaris at http://java.sun.com/j2se/.

I recommend that you download and install the Java 2 SDK (a.k.a. JDK), as opposed to the slimmed-down Runtime Environment (JRE) distribution. The reason is that JSP requires a Java compiler, included in the SDK but not in the JRE.

Another alternative is to use the JRE plus the Jikes compiler from IBM (http://www10.software.ibm.com/developerworks/opensource/jikes/). Tomcat can be configured to use Jikes instead of the javac compiler available in the Java 2 SDK from Sun; read the Tomcat documentation if you would like to try this. To make things simple, though, I suggest installing the Java 2 SDK from Sun. The examples were developed and tested with Java 2 SDK, Standard Edition, v1.4.2. I suggest that you use the latest version of the SDK available for your platform.

If you need an SDK for a platform other than Windows, Linux, or Solaris, there's a partial list of ports made by other companies at: http://java.sun.com/cgi-bin/java-ports.cgi.

Also check your operating-system vendor's web site. Most operating-system vendors have their own SDK implementation available for free.

Installation of the SDK varies per platform but is typically easy to do. Just follow the instructions on the web site where you download the SDK.

Before you install and run Tomcat, make sure that the JAVA_HOME environment variable is set to the installation directory of your Java environment and that the Java bin directory is included in the PATH environment variable. On a Windows system, you can see if an environment variable is set by typing the following command in a Command Prompt window:

C:\> echo %JAVA_HOME%
C:\jdk1.4.2
If JAVA_HOME isn't set, you can set it and include the bin directory in the PATH on a Windows system like this (assuming Java is installed in C:\jdk1.4.2):

C:\> set JAVA_HOME=C:\jdk1.4.2
C:\> set PATH=%JAVA_HOME%\bin;%PATH%
On a Windows 95/98/ME system, add these commands to the C:\AUTOEXEC.BAT file to set them permanently. Just use a text editor, such as Notepad, and add lines with the set commands. The next time you boot the PC, the environment variables will be set automatically. For Windows NT, you can set them permanently from the Environment tab in the System Properties tool in the Control Panel, and for Windows 2000 and Windows XP, you can do the same with the Control Panel System tool by first selecting the Advanced tab and then Environment Variables.

If you use Linux, Mac OS X, or some other Unix-based platform, the exact commands depend on the shell you use. With bash, which is commonly the default for Linux, use the following commands (assuming Java is installed in /usr/local/jdk1.4.2):

[hans@gefion /] export JAVA_HOME=/usr/local/jdk1.4.2
[hans@gefion /] export PATH=$JAVA_HOME/bin:$PATH
[hans@gefion /] echo $PATH
/usr/local/jdk1.4.2/bin:/usr/local/bin:/bin:/usr/bin

Setting Up the JSP Environment

This book contains plenty of examples to illustrate all the JSP features. All examples were developed and tested with the JSP reference implementation, known as the Apache Tomcat server, which is developed by the Apache Jakarta project. In this chapter you will learn how to install the Tomcat server and add a web application containing all the examples used in this book. You can, of course, use any web server that supports JSP 2.0, but Tomcat is a good server for development and test purposes. You can learn more about the Jakarta project and Tomcat, as well as how you can participate in the development, at the Jakarta web site: http://jakarta.apache.org/.

THE continue STATEMENT

Introduction
The break statement breaks the entire loop, but a continue statement breaks the current iteration. After a continue statement, the control returns to top of the loop, that is, to the test conditions. Switch doesn't have a continue statement.

Program/Example
Suppose you want to print numbers 1 to 10 except 4 and 7. You can write:

for(i = 0, i < 11, i++)
{
if ((i == 4) || (i == 7)) continue;
printf(" the value of i is %d\n", i);
}

Explanation
If i is 1 then the if condition is not satisfied and continue is not executed. The value of i is printed as 1.

When i is 4 then the if condition is satisfied and continue is executed.

After executing the continue statement, the next statement, (printf), is not executed; instead, the updated part of the for statement (i++) is executed.

THE break STATEMENT

Introduction
Just like the switch statement, break is used to break any type of loop. Breaking a loop means terminating it. A break terminates the loop in which the loop body is written.

Program/Example
For example,

i = 0;
while (1)
{
i = i + 1;
printf(" the value of i is %d\n");
if (i>5) break;
}

Explanation
The while (1) here means the while condition is always true.

When i reaches 6, the if condition becomes true and break is executed, which terminates the loop.

THE for LOOP WITH A COMMA OPERATOR

Introduction
You may want to control the loop variables in the same for loop. You can use one for loop with a comma operator in such situations.

Program/Example
for (i = 0, j = 10; i < 3 && j > 8; i++, j-)
printf (" the value of i and j %d %d\n",i, j);

Explanation
First i is initialized to 0, and j is initialized to 10.

The conditions i<3 and j>8 are evaluated and the result is printed only if both conditions are true.

After executing the loop body, i is incremented by 1 and j is decremented by 1.

The comma operator also returns a value. It returns the value of the rightmost operand. The value of (i = 0, j = 10) is 10.

THE for LOOP

Introduction
The for loop is used only when the number of iterations is predetermined, for example, 10 iterations or 100 iterations.

Program/Example
The general format for the for loop is

for (initializing; continuation condition; update)
simple or compound statement
For example,
for (i = 0; i < 5; i++)
{
printf("value of i");
}

Explanation
The for loop has four components; three are given in parentheses and one in the loop body.

All three components between the parentheses are optional.

The initialization part is executed first and only once.

The condition is evaluated before the loop body is executed. If the condition is false then the loop body is not executed.

The update part is executed only after the loop body is executed and is generally used for updating the loop variables.

The absence of a condition is taken as true.

It is the responsibility of the programmer to make sure the condition is false after certain iterations.

THE do-while LOOP

THE do-while LOOP


Introduction

The do-while loop is used when you want to execute the loop body at least once. The do-while loop executes the loop body and then traces the condition.

Program/Example

The general format for a do-while loop is

do     simple or compound statement     while (condition)     For example, i = 0; do {     printf(" the value of i is %d\n", i);     i = i + 1; } while (i<5)>

Explanation

  1. The loop body is executed at least once.

  2. The condition is checked after executing the loop body once.

  3. If the condition is false then the loop is terminated.

  4. In this example, the last value of i is printed as 5.


THE while LOOP

Introduction

The while loop is used when you want to repeat the execution of a certain statement or a set of statements (compound statement).

Program/Example

The general format for a while loop is

    while (condition)
simple or compound statement (body of the loop)
For example,
i = 0;
while (i<5)
{
printf(" the value of i is %d\n", i);
i = i + 1;
}

Explanation

  1. Before entering into the loop, the while condition is evaluated. If it is true then only the loop body is executed.

  2. Before making an iteration, the while condition is checked. If it is true then the loop body is executed.

  3. It is the responsibility of the programmer to ensure that the condition is false after certain iterations; otherwise, the loop will make infinite iterations and it will not terminate.

  4. The programmer should be aware of the final value of the looping variable. For example, in this case, the final value of the looping variable is 5.

  5. While writing the loop body, you have to be careful to decide whether the loop variable is updated at the start of the body or at the end of the body.

THE switch STATEMENT

Introduction

You can use a switch statement when you want to check multiple conditions. It can also be done using an if statement but it will be too lengthy and difficult to debug.

Program/Example

The general format for a switch statement is

switch (expressions)
{
case constant expressions
}

Example of a case constant expression and column:

switch (i/10)
{
case 0: printf ("Number less than 10"); // A
break;
case 1: printf ("Number less than 20"); // B
break;
case 2: printf ("Number less than 30"); // C
break;
default: printf ("Number greater than or equal to 40"); // D
break; }

Explanation

  1. The switch expression should be an integer expression and, when evaluated, it must have an integer value.

  2. The case constant expression must represent a particular integer value and no two case expressions should have the same value.

  3. The value of the switch expression is compared with the case constant expression in the order specified, that is, from the top down.

  4. The execution begins from the case where the switch expression is matched and it flows downward.

  5. In the absence of a break statement, all statements that are followed by matched cases are executed. So, if you don't include a break statement and the number is 5, then all the statements A, B, C, and D are executed.

  6. If there is no matched case then the default is executed. You can have either zero or one default statement.

  7. In the case of a nested switch statement, the break statements break the inner switch statement.

Point to Remember

The switch statement is preferable to multiple if statements.

THE if-else if STATEMENT


Introduction

If you want to make many decisions, then you can use the if-else if statement.

Program

The general format for the if-else if statement is:

if (condition 1)
simple or compound statement // s1
else if (condition 2)
simple or compound statement // s2
else if ( condition 3)
simple or compound statement // s3
.....
else if ( conditon n )
simple or compound statement // sn

If condition 1 is true then s1 is executed. If condition 1 is false and condition 2 is true then s2 is executed.

The else clause is always associated with the nearest unresolved if statement.

if (a==5)         // A
if (a==7) // B
i = 10; // C
else // D
if (a == 7) // E
i = 15; // F
else // G
i = 20; // H

For the else statement at position D, the nearest if statement is specified at B. So, the else statement is associated with if at B and not at A.

For the else statement at G, the nearest if statement is specified at E. So, it is associated with the if statement at E and not at A.

if (a==5)          // A
if (a==7) // B
i = 10; // C
else // D
if (a == 7) // E
i = 15; // F1
j = 20; // F2
else // G
i = 20; // H

In this case, the else statement at G cannot be associated with the if statement at E because the if statement at E is already resolved. So, it is associated with the if statement at A.

Points to Remember

  1. You can use if-else if when you want to check several conditions but still execute one statement.

  2. When writing an if-else if statement, be careful to associate your else statement to the appropriate if statement.

  3. You must have parentheses around the condition.

  4. You must have a semicolon or right brace before the else statement.

THE if-else STATEMENT

Introduction

When you want to take actions based on the outcome of the conditions, (true or false), then you can use the if-else statement.

Program/Example

The general format for an if-else statement is

if (condition)
simple or compound statement // s1
else
simple or compound statement. // s2

If the condition is true then the s1 part is executed and if the condition is false then the s2 part is executed. For example,

if (a>b)
printf (" big number is %d", a); // s1
else
printf (" big number is %d", b); // s2

if a is greater than (b) then s1 is executed. Otherwise s2 is executed.

THE if STATEMENT

Introduction

The if statement is the first selection structure. if is used when a question requires a yes or no answer. If you want to choose an answer from several possibilities then use the switch statement.

Program/Example

The general format for an if statement is:

if ( condition )
simple or compound statement.

Following are the properties of an if statement:

  1. If the condition is true then the simple or compound statements are executed.

  2. If the condition is false it does not do anything.

  3. The condition is given in parentheses and must be evaluated as true (nonzero value) or false (zero value).

  4. If a compound statement is provided, it must be enclosed in opening and closing braces.

Following are the test conditions:

    (7)// a non-zero value returns True.
(0)// zero value returns False.
(i==0) // True if i=0 otherwise False.
(i = 0) // False because value of the expression is
zero.

SCOPE OF AN if CLAUSE

The scope of an if clause determines a range over which the result of the condition affects. The scope of an if clause is on the statement which immediately follows the if statement. It can be a simple statement or compound statement.

Case 1:

if (a>b)
i = i + 1; // s1
j = j + 1; // s2

Case 2:

if (a>b)
{
i = i + 1; // s1
j = j + 1; // s2
}

If in Case 1 the if condition is true, then s1 is executed because s1 is a simple statement.

If in Case 2 the if condition is true, then both statements s1 and s2 are executed because s1 and s2 are enclosed in a compound statement.




Sunday, February 14, 2010

JSP Application Design with MVC

Application Design with MVC
JSP technology can play a part in everything from the simplest web application, such as an online phone list or an employee vacation planner, to complex enterprise applications, such as a human resource application or a sophisticated online shopping site. How large a part JSP plays differs in each case, of course. In this section, I introduce a design model called Model-View-Controller (MVC), suitable for both simple and complex applications.

MVC was first described by Xerox in a number of papers published in the late 1980s. The key point of using MVC is to separate logic into three distinct units: the Model, the View, and the Controller. In a server application, we commonly classify the parts of the application as business logic, presentation, and request processing. Business logic is the term used for the manipulation of an application's data, such as customer, product, and order information. Presentation refers to how the application data is displayed to the user, for example, position, font, and size. And finally, request processing is what ties the business logic and presentation parts together. In MVC terms, the Model corresponds to business logic and data, the View to the presentation, and the Controller to the request processing.

Why use this design with JSP? The answer lies primarily in the first two elements. Remember that an application data structure and logic (the Model) is typically the most stable part of an application, while the presentation of that data (the View) changes fairly often. Just look at all the face-lifts many web sites go through to keep up with the latest fashion in web design. Yet, the data they present remains the same. Another common example of why presentation should be separated from the business logic is that you may want to present the data in different languages or present different subsets of the data to internal and external users. Access to the data through new types of devices, such as cell phones and personal digital assistants (PDAs), is the latest trend. Each client type requires its own presentation format. It should come as no surprise, then, that separating business logic from the presentation makes it easier to evolve an application as the requirements change; new presentation interfaces can be developed without touching the business logic.

This MVC model is used for most of the examples in this book. pages are used as both the Controller and the View, and JavaBeans components are used as the Model. The examples in Chapter 5 through Chapter 9 use a single JSP page that handles everything, while Chapter 10 through show how you can use separate pages for the Controller and the View to make the application easier to maintain. Many types of real-world applications can be developed this way, but what's more important is that this approach allows you to examine all the JSP features without getting distracted by other technologies. In Part III, we look at other possible role assignments when JSP is combined with servlets and Enterprise JavaBeans.

JSP Processing

3.3 JSP Processing

Just as a web server needs a servlet container to provide an interface to servlets, the server needs a JSP container to process JSP pages. The JSP container is responsible for intercepting requests for JSP pages. To process all JSP elements in the page, the container first turns the JSP page into a servlet (known as the JSP page implementation class). The conversion is pretty straightforward; all template text is converted to println( ) statements similar to the ones in the handcoded servlet shown in , and all JSP elements are converted to Java code that implements the corresponding dynamic behavior. The container then compiles the servlet class.

Converting the JSP page to a servlet and compiling the servlet form the translation phase. The JSP container initiates the translation phase for a page automatically when it receives the first request for the page. Since the translation phase takes a bit of time, the first user to request a JSP page notices a slight delay. The translation phase can also be initiated explicitly; this is referred to as precompilation of a JSP page. Precompiling a JSP page is a way to avoid hitting the first user with this delay.

The JSP container is also responsible for invoking the JSP page implementation class (the generated servlet) to process each request and generate the response. This is called the request processing phase.

JSP page translation and processing phases

As long as the JSP page remains unchanged, any subsequent request goes straight to the request processing phase (i.e., the container simply executes the class file). When the JSP page is modified, it goes through the translation phase again before entering the request processing phase.

The JSP container is often implemented as a servlet configured to handle all requests for JSP pages. In fact, these two containers—a servlet container and a JSP container—are often combined in one package under the name web container.

So in a way, a JSP page is really just another way to write a servlet without having to be a Java programming wiz. Except for the translation phase, a JSP page is handled exactly like a regular servlet; it's loaded once and called repeatedly, until the server is shut down. By virtue of being an automatically generated servlet, a JSP page inherits all the advantages of a servlet described platform and vendor independence, integration, efficiency, scalability, robustness, and security.

JSP Elements

There are three types of JSP elements you can use: directive, action, and scripting. A new construct added in JSP 2.0 is an Expression Language (EL) expression; let's call this a forth element type, even though it's a bit different than the other three.

Element

Description

<%@ page ... %>

Defines page-dependent attributes, such as session tracking, error page, and buffering requirements

<%@ include ... %>

Includes a file during the translation phase

<%@ taglib ... %>

Declares a tag library, containing custom actions, that is used in the page

Standard action elements

Action elements typically perform some action based on information that is required at the exact time the JSP page is requested by a browser. An action can, for instance, access parameters sent with the request to do a database lookup. It can also dynamically generate HTML, such as a table filled with information retrieved from an external system.

The JSP specification defines a few standard action elements, most of them listed in Table 3-2.[1]

[1] There are a few more action elements, used in combination with these standard actions or custom actions or in very special cases. They are introduced as they are used in the examples later in this book.

. Standard action elements

Action element

Description

Makes a JavaBeans component available in a page

Gets a property value from a JavaBeans component and adds it to the response

Sets a JavaBeans component property value

Includes the response from a servlet or JSP page during the request processing phase

Forwards the processing of a request to a servlet or JSP page

Adds a parameter value to a request handed off to another servlet or JSP page using or

Generates HTML that contains the appropriate browser-dependent elements (OBJECT or EMBED) needed to execute an applet with the Java Plugin software

Custom action elements and the JSP Standard Tag Library

In addition to the standard actions, the JSP specification defines how to develop custom actions to extend the JSP language, either as Java classes or as text files with JSP elements. The JSP Standard Tag Library (JSTL) is such an extension, with the special status of being defined by a formal specification from Sun and typically bundled with the JSP container. JSTL contains action elements for the type of processing needed in most JSP applications, such as conditional processing, database access, internationalization, and more. This book covers all the JSTL actions in detail.

If JSTL isn't enough, your team (or a third party) can use these extension mechanisms to develop additional custom actions, maybe to access application-specific resources or simplify application-specific processing. The examples in this book use a few custom actions in addition to the JSTL actions.

elements

Scripting elements, shown in Table , allow you to add small pieces of code (typically Java code) in a JSP page, such as an if statement to generate different HTML depending on a certain condition. Like actions, they are also executed when the page is requested. You should use scripting elements with extreme care: if you embed too much code in your JSP pages, you will end up with the same kind of maintenance problems as with servlets embedding HTML.

Table 3-3. Scripting elements

Element

Description

<% ... %>

Scriptlet, used to embed scripting code

<%= ... %>

Expression, used to embed scripting code expressions when the result shall be added to the response; also used as request-time action attribute values

<%! ... %>

Declaration, used to declare instance variables and methods in the JSP page implementation class

3.3.1.5 Expression Language expressions

A new feature in JSP 2.0 is the Expression Language (EL), originally developed as part of the JSTL specification. The EL is a simple language for accessing request data and data made available through application classes. EL expressions can be used directly in template text or to assign values to action element attributes. Its syntax is similar to JavaScript, but much more forgiving; it's constrained in terms of functionality, since it's not intended to be a full-fledged programming language. Rather, it is a glue for tying together action elements and other application components. There are way too many elements of the EL to list here, but they are all introduced in Chapter 5 and described in detail when used in examples.

3.3.1.6 JavaBeans components

JSP elements, such as action and scripting elements, are often used to work with JavaBeans components. Put succinctly, a JavaBeans component is a Java class that complies with certain coding conventions. JavaBeans components are typically used as containers for information that describes application entities, such as a customer or an order.



The Anatomy of a JSP Page

A JSP page is simply a regular web page with JSP elements for generating the parts that differ for each request, as shown in Figure

Everything in the page that isn't a JSP element is called template text. Template text can be any text: HTML, WML, XML, or even plain text. Since HTML is by far the most common web page language in use today, most of the descriptions and examples in this book use HTML, but keep in mind that JSP has no dependency on HTML; it can be used with any markup language. Template text is always passed straight through to the browser.

When a JSP page request is processed, the template text and dynamic content generated by the JSP elements are merged, and the result is sent as the response to the browser.

The Problem with Servlets

A typical servlet class
public class OrderServlet extends HttpServlet {

public void doGet((HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

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

if (isOrderInfoValid(request)) {
saveOrderInfo(request);
out.println("");
out.println(" ");
out.println(" Order Confirmation");
out.println(" ");
out.println(" ");
out.println("

Order Confirmation

");
renderOrderInfo(request);
out.println(" ");
out.println("");
}
...

If you're not a programmer, don't worry about all the details in this code. The point is that the servlet contains request processing and

business logic (implemented by methods such as isOrderInfoValid() and saveOrderInfo( )), and also generates the response HTML code, embedded directly in the servlet code using println( ) calls. A more structured servlet application isolates different pieces of the processing in various reusable utility classes and may also use a separate class library for generating the actual HTML elements in the response. Even so, the pure servlet-based approach still has a few problems:

  • Thorough Java programming know

    ledge is needed to develop and maintain all aspects of the application, since the processing code and the HTML elements are lumped together.

  • Changing the look and feel of the application, or adding support for a new type of client (such as a WML client), requires th

    e servlet code to be updated and reco

    mpiled.

  • It's hard to take advantage of web pa

    ge development tools when designing the application interface. If such tools are used to develop the web page layout, the generated HTML must then be manually embedded into the servlet code, a process which is time consuming, error prone, and extremely boring.

Adding JSP to the puzzle lets you solve these problems by separating the request processing and business logic code from the presentation, as illustrated in Figure 3-1. Instead of embedding HTML in the code, place all static HTML i

n a JSP page, just as in a regular web page, and add a few JSP elements to generate the dynamic parts of the page. The request processing can remain the domain of the servlet, and the business logic can be handled by JavaBeans and EJB components.

Separation of request processing, business logic, and presentation



As I mentioned before, separating the request processing and business logic from presentation makes it possible to divide the development tasks among people with different skills. Java programmers implement the request processing and business logic pieces, web page authors implement the user interface, and both groups can use best-of-breed development tools for the task at hand. The result is a much more productive development process. It also makes it possible to change different aspects of the application independently, such as changing the business rules without touching the user interface.

This model has clear benefits even for a web page author without programming skills, working alone. A page author can develop web applications with many dynamic features, using the JSP standard actions and the JSTL libraries, as well as Java components provided by open source projects and commercial companies.


JSP Overview

JSP is the latest Java technology for web application development and is based on the servlet technology introduced in the previous chapter. While servlets are great in many ways, they are generally reserved for programmers. In this chapter, we look at the problems that JSP technology solves, the anatomy of a JSP page, the relationship between servlets and JSP, and how the server processes a JSP page.

In any web application, a program on the server processes requests and generates responses. In a simple one-page application, such as an online bulletin board, you don't need to be overly concerned about the design of this piece of code; all logic can be lumped together in a single program. However, when the application grows into something bigger (spanning multiple pages, using external resources such as databases, with more options and support for more types of clients), it's a different story. The way your site is designed is critical to how well it can be adapted to new requirements and continue to evolve. The good news is that JSP technology can be used as an important part in all kinds of web applications, from the simplest to the most complex. Therefore, this chapter also introduces the primary concepts in the design model recommended for web applications and the different roles played by JSP and other Java technologies in this model.

Servlets

The JSP specification is based on the Java servlet specification. In fact, JSP pages are often combined with servlets in the same application. In this section, we take a brief look at what a servlet is, and then discuss the concepts shared by servlets and JSP pages.

Advantages over Other Server-Side Technologies

In simple terms, a servlet is a piece of code that adds new functionality to a server (typically a web server), just like CGI and proprietary server extensions such as NSAPI and ISAPI. But compared to other technologies, servlets have a number of advantages:

Platform and vendor independence

All the major web servers and application servers support servlets, so a servlet-based solution doesn't tie you to one specific vendor. Also, servlets are written in the Java programming language, so they can be used on any operating system with a Java runtime environment.


Integration

Servlets are developed in Java and can therefore take advantage of all other Java technologies, such as JDBC for database access, JNDI for directory access, RMI for remote resource access, etc. Starting with Version 2.2, the servlet specification is part of the Java 2 Enterprise Edition (J2EE), making servlets an important ingredient of any large-scale enterprise application, with formalized relationships to other server-side technologies such as Enterprise JavaBeans.


Efficiency

Servlets execute in a process that is running until the servlet-based application is shut down. Each servlet request is executed as a separate thread in this permanent process. This is far more efficient that the CGI model, where a new process is created for each request. First of all (and most obvious), a servlet doesn't have the overhead of creating the process and loading the CGI script and possibly its interpreter. But another timesaver is that servlets can also access resources that remain loaded in the process memory between requests, such as database connections and persistent state.


Scalability

By virtue of being written in Java and the broad support for servlets, a servlet-based application is extremely scalable. You can develop and test the application on a Windows PC using the standalone servlet reference implementation, and deploy it on anything from a more powerful server running Linux and Apache to a cluster of high-end servers with an application server that supports loadbalancing and failover.

Robustness and security

Java is a strongly typed programming language. This means that you catch a lot of mistakes in the compilation phase that you would only catch during runtime if you used a script language such as Perl. Java's error handling is also much more robust than C/C++, where an error such as division by zero typically brings down the whole server.

In addition, servlets use specialized interfaces to server resources that aren't vulnerable to the traditional security attacks. For instance, a CGI Perl script typically uses shell command strings composed of data received from the client to ask the server to do things such as send email. People with nothing better to do love to find ways to send data that will cause the server to crash, remove all files on the hard disk, or plant a virus or a backdoor when the server executes the command. While a CGI script programmer must be very careful to screen all input to avoid these threats, such problems are almost nonexistent with a servlet because it doesn't communicate with the server in the same insecure way.


Servlet Containers

A servlet container is the connection between a web server and the servlets. It provides the runtime environment for all the servlets on the server as defined by the servlet specification, and is responsible for loading and invoking those servlets when the time is right. The container typically loads a servlet class when it receives the first request for the servlet, gives it a chance to initialize itself, and then asks it to process the request. Subsequent requests use the same, initialized servlet until the server is shut down. The container then gives the servlet a chance to release resources and save its state (for instance, information accumulated during its lifetime).

There are many different types of servlet containers. Some containers are called add-ons, or plug-ins, and are used to add servlet support to web servers without native servlet support (such as Apache and IIS). They can run in the same operating-system process as the web server or in a separate process. Other containers are standalone servers. A standalone server includes web server functionality to provide full support for HTTP in addition to the servlet runtime environment. Containers can also be embedded in other servers, such as a climate-control system, to offer a web-based interface to the system. A container bundled as part of an application server can distribute the execution of servlets over multiple hosts. The server can balance the load evenly over all containers, and some servers can even provide failover capabilities in case a host crashes.

No matter what type it is, the servlet container is responsible for mapping an incoming request to a servlet registered to handle the resource identified by the URI and passing the request message to that servlet. After the request is processed, it's the container's responsibility to convert the response created by the servlet into an HTTP response message and send it back to the client.

Servlet Contexts and Web Applications

A Java web application is typically made up by a combination of several different types of resources: JSP pages, servlets, applets, static HTML pages, custom tag libraries and other Java class files. Containers compliant with the Servlet 2.2 specification (or later), support a standard, portable way to package all these resources, along with a web application deployment descriptor containing information about how all the resources fit together. The deployment descriptor and all the other web application files are arranged in a well-defined hierarchy within an archive file, called a web application archive (WAR). All compliant containers provide tools for installing a WAR file or a special directory where a WAR file is automatically picked up (such as the webapps directory in Tomcat). Most containers also support web applications deployed directly in a filesystem using the same file structure as is defined for the WAR file, which can be convenient during development.

Within the container, each web application is represented by a servlet context. The servlet context is associated with a unique URI path prefix called the context path, as shown in . For instance, your human resources application can be associated with the context path /hr and your sales tracking system with the context path /sales. This allows one servlet container to distinguish between the different applications it serves and dispatch requests like /sales/report?month=Jan to the sales tracking application and /hr/emplist to the human resources application.

The remaining URI path is then used within the selected context to decide how to process the request by comparing it to path-mapping rules defined by the application's deployment descriptor. Rules can be defined to send all requests starting with /report to one servlet and requests starting with /forecast to another. Another type of mapping rule can say that one servlet handles all requests with paths ending with a specific file extension, such as .jsp. This is how JSP page requests are handled. shows how the different parts of the URI paths are used to direct the request processing to the right resource through the container and context.

Each context is self-contained and doesn't know anything about other applications running in the same container. References between the servlets and JSP pages in the application are commonly relative to the context path and, therefore, are referred to as context-relative paths. By using context-relative paths within the application, a web application can be deployed using any context path.

Finally, a context can hold objects shared by all components of the application,[3] such as database connections and other shared resources needed by multiple servlets and JSP pages.




The HTTP Request/Response Model

HTTP and all extended protocols based on HTTP are based on a very simple communications model. Here's how it works: a client, typically a web browser, sends a request for a resource to a server, and the server sends back a response corresponding to the resource (or a response with an error message if it can't process the request for some reason). A resource can be a number of things, such as a simple HTML file returned verbatim to the browser or a program that generates the response dynamically.

This simple model implies three important facts you need to be aware of:

  • HTTP is a stateless protocol. This means that the server doesn't keep any information about the client after it sends its response, and therefore it can't recognize that multiple requests from the same client may be related.

  • Web applications can't easily provide the kind of immediate feedback typically found in standalone GUI applications such as word processors or traditional client/server applications. Every interaction between the client and the server requires a request/response exchange. Performing a request/response exchange when a user selects an item in a list box or fills out a form element is usually too taxing on the bandwidth available to most Internet users.

  • There's nothing in the protocol that tells the server how a request is made; consequently, the server can't distinguish between various methods of triggering the request on the client. For example, HTTP doesn't allow a web server to differentiate between an explicit request caused by clicking a link or submitting a form and an implicit request caused by resizing the browser window or using the browser's Back button. In addition, HTTP doesn't contain any means for the server to invoke client specific functions, such as going back in the browser history list or sending the response to a certain frame. Also, the server can't detect when the user closes the browser.

Over the years, people have developed various tricks to overcome the first problem; HTTP's stateless nature. We'll look at them in . The other two problems—no immediate feedback and no details about how the request is made—are harder to deal with, but some amount of interactivity can be achieved by generating a response that includes client-side code (code executed by the browser), such as JavaScript or a Java applet.

Requests in Detail

Let's take a closer look at requests. A user sends a request to the server by clicking a link on a web page, submitting a form, or typing in a web page address in the browser's address field. To send a request, the browser needs to know which server to talk to and which resource to ask for. This information is specified by an HTTP Uniform Resource Locator (URL):

http://www.gefionsoftware.com/index.html

The first part of the URL shown specifies that the request is made using the HTTP protocol. This is followed by the name of the server, in this case www.gefionsoftware.com. The web server waits for requests to come in on a specific TCP/IP port. Port number 80 is the standard port for HTTP requests. If the web server uses another port, the URL must specify the port number in addition to the server name. For example:

http://www.gefionsoftware.com:8080/index.html

This request is sent to a server that uses port 8080 instead of 80. The last part of the URL, /index.html, identifies the resource that the client is requesting.

A URL is actually a specialization of a Uniform Resource Identifier (URI, defined in the RFC-2396[1] specification). A URL identifies a resource partly by its location, for instance the server that contains the resource. Another type of URI is a Uniform Resource Name (URN), which is a globally unique identifier that is valid no matter where the resource is located. HTTP deals only with the URL variety. The terms URI and URL are often used interchangeable, and unfortunately, they have slightly different definitions in different specifications. I'm trying to use the terms as defined by the HTTP/1.1 specification (RFC-2616), which is pretty close to how they are also used in the servlet and JSP specifications. Hence, I use the term URL only when the URI must start with http (or https, for HTTP over an encrypted connection) followed by a server name and possibly a port number, as in the previous examples. I use URI as a generic term for any string that identifies a resource, where the location can be deduced from the context and isn't necessarily part of the URI. For example, when the request has been delivered to the server, the location is a given, and only the resource identifier is important.

The browser uses the URL information to create the request message it sends to the specified server using the specified protocol. An HTTP request message consists of three things: a request line, request headers, and possibly a request body.

The request line starts with the request method name, followed by a resource identifier and the protocol version used by the browser:

GET /index.html HTTP/1.1

The most commonly used request method is named GET. As the name implies, a GET request is used to retrieve a resource from the server. It's the default request method, so if you type a URL in the browser's address field, or click on a link, the request is sent as a GET request to the server.

The request headers provide additional information the server may use to process the request. The message body is included only in some types of requests, like the POST request discussed later.

Here's an example of a valid HTTP request message:

GET /index.html HTTP/1.1

Host: www.gefionsoftware.com
User-Agent: Mozilla/5.0 (Windows; U; Win 9x 4.90; en-US; rv: 1.0.2)
Accept: image/gif, image/jpeg, image/pjpeg, image/png, */*
Accept-Language : en
Accept-Charset : iso-8859-1,*,utf-8

The request line specifies the GET method and asks for the resource named /index.html to be returned using the HTTP/1.1 protocol version. The various headers provide additional information.

The Host header tells the server the hostname used in the URL. A server may have multiple names, so this information is used to distinguish between multiple virtual web servers sharing the same web server process.

The User-Agent header contains information about the type of browser making the request. The server can use this to send different types of responses to different types of browsers. For instance, if the server knows whether Internet Explorer or Netscape Navigator is used, it can send a response that takes advantage of each browser's unique features. It can also tell if a client other than an HTML browser is used, such as a Wireless Markup Language (WML) browser on a cell phone or a PDA device, and generate an appropriate response.

The Accept headers provide information about the languages and file formats the browser accepts. These headers can be used to adjust the response to the capabilities of the browser and the user's preferences, such as use a supported image format and the preferred language. These are just a few of the headers that can be included in a request message.

The resource identifier (URI) doesn't necessarily correspond to a static file on the server. It can identify an executable program, a record in a database, or pretty much anything the web server knows about. That's why the generic term resource is used. In fact, there's no way to tell if the /index.html URI corresponds to a file or something else; it's just a name that means something to the server. The web server is configured to map these unique names to the real resources.

2.1.2 Responses in Detail

When the web server receives the request, it looks at the URI and decides, based on configuration information, how to handle it. It may handle it internally by simply reading an HTML file from the filesystem, or it can forward the request to some component that is responsible for the resource corresponding to the URI. This can be a program that uses database information, for instance, to dynamically generate an appropriate response. To the browser it makes no difference how the request is handled; all it cares about is getting a response.

The response message looks similar to the request message. It consists of three things: a status line, response headers, and an optional response body. Here's an example:

HTTP/1.1 200 OK

Last-Modified: Mon, 20 Dec 2002 23:26:42 GMT
Date: Tue, 11 Jan 2003 20:52:40 GMT
Status: 200
Content-Type: text/html
Servlet-Engine: Tomcat Web Server/5.0
Content-Length: 59



Hello World!



The status line starts with the name of the protocol, followed by a status code and a short description of the status code. Here the status code is 200, meaning the request was executed successfully. The response message has headers just like the request message. In this example, the Last-Modified header gives the date and time for when the resource was last modified. The browser can use this information as a timestamp in a local cache; the next time the user asks for this resource, he can ask the server to send it only if it's been updated since the last time it was requested. The Content-Type header tells the browser what type of response data the body contains and the Content-Length header how large it is. The other headers are self-explanatory. A blank line separates the headers from the message body. Here the body is a simple HTML page:




Hello World!



Of course, the body can contain a more complex HTML page or any other type of content. For example, the request may return an HTML page with elements. When the browser reads the first response and finds the elements, it sends a new request for the resource identified by each element, often in parallel. The server returns one response for each image request, with a Content-Type header telling what type of image it is (for instance image/gif) and the body containing the bytes that make up the image. The browser then combines all responses to render the complete page.

Request Parameters

Besides the URI and headers, a request message can contain additional information in the form of parameters. If the URI identifies a server-side program for displaying weather information, for example, request parameters can provide information about the city the user wants to see a forecast for. In an e-commerce application, the URI may identify a program that processes orders, with the user's customer number and the list of items to be purchased transferred as parameters.

Parameters can be sent in one of two ways: tacked on to the URI in the form of a query string or sent as part of the request message body. This is an example of a URL with a query string:

http://www.weather.com/forecast?city=Hermosa+Beach&state=CA

The query string starts with a question mark (?) and consists of name/value pairs separated by ampersands (&). These names and values must be URL-encoded, meaning that special characters, such as whitespace, question marks, ampersands, and all other nonalphanumeric characters are encoded so that they don't get confused with characters used to separate name/value pairs and other parts of the URI. In this example, the space between Hermosa and Beach is encoded as a plus sign. Other special characters are encoded as their corresponding hexadecimal ASCII value; for instance, a question mark is encoded as %3F. When parameters are sent as part of the request body, they follow the same syntax; URL encoded name/value pairs separated by ampersands.

Request Methods

As described earlier, GET is the most commonly used request method, intended to retrieve a resource without causing anything else to happen on the server. The POST method is almost as common as GET; it requests some kind of processing on the server, for instance, updating a database or processing a purchase order.

The way parameters are transferred is one of the most obvious differences between the GET and POST request methods. A GET request always uses a query string to send parameter values, while a POST request always sends them as part of the body (additionally, it can send some parameters as a query string, just to make life interesting). If you insert a link in an HTML page using an element, clicking on the link results in a GET request being sent to the server. Since the GET request uses a query string to pass parameters, you can include hardcoded parameter values in the link URI:



Hermosa Beach weather forecast

When you use a form to send user input to the server, you can specify whether to use the GET or POST method with the method attribute, as shown here:


City:
State:



If the user enters "Hermosa Beach" and "CA" in the form fields and clicks on the Submit button, the browser sends a request message like this to the server:

POST /forecast HTTP/1.1

Host: www.gefionsoftware.com
User-Agent: Mozilla/5.0 (Windows; U; Win 9x 4.90; en-US; rv: 1.0.2)
Accept: image/gif, image/jpeg, image/pjpeg, image/png, */*
Accept-language: en-US
Accept-charset: iso-8859-1,*,utf-8

city=Hermosa+Beach&state=CA

Due to the differences in how parameters are sent by GET and POST requests, as well as the differences in their intended purpose, browsers handle the requests in different ways. A GET request, parameters and all, can easily be saved as a bookmark, hardcoded as a link, and the response cached by the browser. Also, the browser knows that no damage is done if it needs to send a GET request again automatically, for instance if the user clicks the Reload button.

A POST request, on the other hand, can't be bookmarked as easily; the browser would have to save both the URI and the request message body. Since a POST request is intended to perform some possibly irreversible action on the server, the browser must also ask the user if it's okay to send the request again.

Besides the GET and POST methods, HTTP specifies the following methods:


OPTIONS

The OPTIONS method is used to find out what options (e.g., methods) a server or a resource offers.


HEAD

The HEAD method is used to get a response with all headers generated by a GET request but without the body. It can make sure a link is valid or to see when a resource was last modified.


PUT

The PUT method is used to store the message body content on the server as a resource identified by the URI.


DELETE

The DELETE method is used to delete the resource identified by the URI.


TRACE

The TRACE method is used for testing the communication between the client and the server. The server sends back the request message, exactly as it received it, as the body of the response.

These methods aren't normally used in a web application.