You are on page 1of 283

J2EE

COURSE MATERIALS

CONTENTS
SL.NO.
1. 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 2.

CHAPTER
CORE JAVA REVIEW
Object oriented principle Programming structures Object and classes Inheritance Package and Interface Exception handling Threading Input and Output

PAGE NO.
4

INTRODUCTION TO J2EE
2.1 Introduction 2.2 J2EE architecture 2.3 Component technologies 2.4 Service technologies 2.5 Communication technologies 2.6 Servers

29

3.

JDBC
3.1 Introduction to JDBC 3.2 Types of drivers 3.3 Steps to connect with database 3.4 ResultSetMetaData 3.5 Scrollable ResultSet 3.6 PreparedStatement 3.7 CallableStaement 3.8 Batch Statement 3.9 Connection pooling

40

4.

SERVLETS
4.1 Introduction to servlets and alternatives 4.2 Directory structure and Web Application Deployment Descriptor 4.3 Life-cycle of Servlet and Servlet APIstructure 4.4 Request and Response 4.5 ServletConfig, ServletContext, Servlet Collaboration 4.6 Session tracking 4.7 Applet-servlet communication

52

5.

JAVA SERVER PAGES [ JSP ]


5.1 Introduction 5.2 Directives 5.3 Scripting elements 5.4 Implicit Objects

80

5.5 Standard Action and Java Bean

6.

REMOTE METHOD INVOCATION [ RMI ]


6.1 Introduction. 6.2 Defining the RMI contract 6.3 RMI Client 6.4 RMI Server 6.5 Deploying RMI across a Network

97

7.

ENTERPRISE JAVA BEAN [ EJB ]


7.1 Introduction 7.2 EJB and Java Bean 7.3 Session Bean 7.4 Entity Bean 7.5 Message Driven Bean

103

8.

STRUTS
8.1 Introduction to struts 8.2 A simple application 8.3 Controller 8.4 Views

127

9.

XML
9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 9.10 9.11 Introduction to XML XML Syntax XML Elements XML Attributes XML Validation XML with CSS XML with XSL XML Namespace Introduction to DTD DTD XML Building blocks XML Schema

164

10.

SUPPORTING TECHNOLOGIES
10.1 Introduction to SQL queries 10.2 Intoduction to HTML 10.3 Introduction to CSS 10.4 Introduction to javascript 10.5 UML

196

CHAPTER 1 CORE JAVA REVIEW


1.1 Object oriented principle
OBJECT
Basic building block for Object-Oriented Programming (OOP). Usually correspond to real-life entities. An object is a unit of software comprising of : a) State / Attribute b) Behavior c) Identity : Defines the properties of the object & the current values of each of these properties. : Defines the response of an object reacts in terms of its state changes & message passing. : Defines an unique name.

EXAMPLE:
Car, Mobile phone, An invoice, John Object : John
IDENTITY NAME OF THE PERSON

STATE / ATTRIBUTES AGE ADDRESS PHONE BODY PARTS BEHAVIORS JUMP WALK MOVE ARMS

CLASS
User-defined data type. Used to represent a template for several similar type of objects. Describes how the objects are structured internally. Objects of the same class have the same definition both for their state & behavior. 4

Example:
CLASS : PERSON
STATE / ATTRIBUTES AGE ADDRESS PHONE BODY PARTS

BEHAVIORS JUMP WALK MOVE ARMS

INSTANCE
Creation of an object for a particular class. Attributes & behavior are described by the class. Each instance has a unique identity. Several different instances can be created from the same class. Each instance will have different internal states depending upon the different sequences of operations performed.
CLASS : PERSON

Instance of
ATTRIBUTES AGE ADDRESS PHONE BODY PARTS

BEHAVIORS JUMP WALK MOVE ARMS

Neh a

Instance of Vivek

Instance of Smith

INHERITANCE
A property which allows a class to inherit the properties from another class. Supports the concept of hierarchical classification. The parent class is known as base class and the descendent class is known as derived class. The base class serves as a pattern for the derived class.

Advantages
Core idea for reuse in the software industry. Useful for easy modification of models. Useful for avoiding redundancy , leading to smaller models that are easier to understand.

Types of Inheritance
a) Single Inheritance : If the derived class inherits from a single parent, the inheritance is said to be single inheritance. If the derived class inherits from two or more parents, the inheritance is said to be multiple inheritance.

b) Multiple Inheritance :

POLYMORPHISM
Ability to take more than one form The same operation may exhibit different behavior in different instances. Behavior depends upon the types of data used in the operation. EXAMPLE Operation to be performed : Addition Input Data Type Result Integer Sum Character Concatenated String

Advantages
Extensively used in implementing inheritance. Allows objects having different internal structures to share the same external interface.

TYPES OF POLYMORPHISM
(a) Compile-time Polymorphism
Achieved with static binding. The procedure call is replaced with memory address statically at compile-time. Polymorphism is achieved with function overloading. Function Overloading means that in a program more than one functions can be defined with the same name & return type. The type & number of parameters can vary.

(b) Run-time Polymorphism


Achieved with dynamic binding. At run-time the procedure call matching the object under current reference will be called. This gives objects the ability to respond to messages from routines when the objects exact type is not known till the run-time.

DATA ABSTRACTION
Refers to the act of representing essential features without including the background details or explanations. Controls the visibility of information. Focuses upon the essential characteristics of some object, relative to the perspective of the viewer.

ENCAPSULATION
The method of combining the data member & member functions of an object into a single structure / unit (called class). Isolates the functional details of the object from outside the class. Helps in data hiding.

1.2 PROGRAMMING STRUCTURES


A Simple Java Program Comments Data Types Variables Assignments and Initializations Operators Arrays

Before we get into the details of the language, a brief overview would be of benefit. This section gives a very quick look at the main features of the language, without going too far into the details or showing us any actual syntax, to give us a feel for the main concepts behind Object-Oriented programming in Java. A Java program is a collection of classes. Some of these we write; some are provided as a part of the java language.

A Simple Java Program


Let's look more closely at about the simplest Java program we can haveone that simply prints a message to the console window:
public class FirstSample { public static void main(String[] args) { System.out.println("We will not use 'Hello, World!'");

}}

Now let's look at this source code line by line. The keyword public is called an access modifier; these modifiers control what other parts of a program can use this code. The keyword class is there to remind us that everything in a Java program lives inside a class. Classes are the uilding blocks with which all Java applications and applets are built. Everything in a Java program must be inside a class. Following the keyword class is the name of the class. The rules for class names in Java are quite generous. Names must begin with a letter, and after that, they can have any combination of letters and digits. The length is essentially unlimited. We cannot use a Java reserved word (such as public or if) for a class name.

COMMENTS
Comments in Java, like comments in most programming languages, do not show up in the executable program. Java has three ways of showing comments. The most common method is a //. We use this for a comment that will run from the // to the end of the line. System.out.println("We will not use 'Hello world!'"); // is this too cute? When longer comments are needed, we can mark each line with a //. Or we can use the /* and */ comment delimiters that let we block off a longer comment. /* This is the first sample program in Core Java Chapter 3 Copyright (C) 1996...2000 Cay Horstmann and Gary Cornell */

DATA TYPES
Java is a strongly typed language. This means that every variable must have a declared type. There are eight primitive types in Java. Four of them are integer types; two are floating-point number types; one is the character type char, used for characters in the Unicode encoding and one is a boolean type for truth values.

INTEGERS
The integer types are for numbers without fractional parts. Negative values are allowed. Java provides the four integer types JAVA INTEGER TYPES Type
Int short Long

Storage
4 bytes 2 bytes 8 bytes

Requirement Range (inclusive)


2,147,483,648 to 2,147,483, 647 (just over 2 billion) -32,768 to 32,767 9,223,372,036,854,775,808L to 9,223,372,036,854,775,807L

Byte

1 byte

-128 to 127

FLOATING-POINT TYPES
The floating-point types denote numbers with fractional parts. There are two floating-point Types

Type Float
double

Storage
4 bytes 8 bytes

Requirement Range (inclusive) 3.40282347E+38F (67 significant decimal digits) 1.79769313486231570E+308 (15 significant decimal digits)

THE CHARACTER TYPE


First, single quotes are used to denote char constants. For example, 'H' is a character. It is different from "H", a string containing a single character. Second, the char type denotes characters in the Unicode encoding scheme. Escape \b \t \n \r \ \ \\ Special characters Sequence Name Unicode Value Backspace \u0008 Tab \u0009 Linefeed \u000a Carriage return \u000d Double quote \u0022 Single quote \u0027 Backslash \u005c

THE BOOLEAN TYPE


The boolean type has two values, false and true. It is used for evaluating logical conditions. We cannot convert between integers and boolean values.

VARIABLES
In Java, every variable has a type. We declare a variable by placing the type first, followed by the name of the variable. Here are some examples: double salary; int vacationDays; long earthPopulation; char yesChar; boolean done; Notice the semicolon at the end of each declaration. The semicolon is necessary because a declaration is a complete Java statement.

OPERATORS
An operator takes one or more arguments and produces a new value. The arguments are in a different form than ordinary method calls, but the effect is the same. There are different types of operators are there. They are Arithmetic Operators Assignment Operators Unary minus and plus Operators Auto increment and Decrement Operators Relational Operators Logical Operators Bitwise Operators Ternary Operators

Arithmetic Operators
The following are the arithmetic operators : addition (+), subtraction (-), division (/), multiplication (*) and modulus (%, which produces the remainder from integer division). Integer division truncates, rather than rounds, the result.

Assignment Operators
Assignment is performed with the operator =. It means take the value of the right-hand side (often called the rvalue) and copy it into the left-hand side (often called the lvalue). An rvalue is any constant, variable or expression that can produce a value, but an lvalue must be a distinct, named variable.

For instance; A = 5; Java also uses a shorthand notation to perform an operation and an assignment at the same time. This is denoted by an operator followed by an equal sign, and is consistent with all the operators in the language Instead of writing x = x + 4; we can write x+=4;

Unary minus and plus Operators


The unary minus (-) and unary plus (+) are the same operators as binary minus and plus. The compiler figures out which use is intended by the way we write the expression. For instance, the statement x = -a; has an obvious meaning. The compiler is able to figure out: x = a * -b; but the reader might get confused, so it is clearer to say: 10

AUTO INCREMENT AND DECREMENT OPERATORS


The increment and decrement operators are the two of the nicer shortcuts. The decrement operator is -- and means decrease by one unit. The increment operator is ++ and means increase by one unit. If a is an int, for example, the expression ++a is equivalent to (a = a + 1). Increment and decrement operators produce the value of the variable as a result. There are two versions of each type of operator, often called the prefix and postfix versions. Pre-increment means the ++ operator appears before the variable or expression, and post-increment means the ++ operator appears after the variable or expression. Similarly, predecrement means the -- operator appears before the variable or expression, and post-decrement means the -- operator appears after the variable or expression. For pre-increment and predecrement, (i.e., ++a or --a), the operation is performed and the value is produced. For postincrement and post-decrement (i.e. a++ or a--), the value is produced, then the operation is performed.

Relational Operators
Relational operators generate a boolean result. They evaluate the relationship between the values of the operands. A relational expression produces true if the relationship is true, and false if the relationship is untrue. The relational operators are less than (<), greater than (>), less than or equal to (<=), greater than or equal to (>=), equivalent (==) and not equivalent (!=). Equivalence and nonequivalence works with all built-in data types, but the other comparisons wont work with type boolean. The relational operators == and != also work with all objects, but their meaning often confuses the first-time Java programmer.

Logical Operators
The logical operators AND (&&), OR (||) and NOT (!) produce a boolean value of true or false based on the logical relationship of its arguments.

Bitwise Operators
The bitwise operators allow us to manipulate individual bits in an integral primitive data type. Bitwise operators perform boolean algebra on the corresponding bits in the two arguments to produce the result. The bitwise AND operator (&) produces a one in the output bit if both input bits are one; otherwise it produces a zero. The bitwise OR operator (|) produces a one in the output bit if either input bit is a one and produces a zero only if both input bits are zero. The bitwise EXCLUSIVE OR, or XOR (^), produces a one in the output bit if one or the other input bit is a one, but not both. The bitwise NOT (~, also called the ones complement operator) is a unary operator; it takes only one argument. (All other bitwise operators are binary operators.) Bitwise NOT produces the opposite of the input bita one if the input bit is zero, a zero if the input bit is one.

11

Ternary operators
This operator is unusual because it has three operands. The expression is of the form: booleanexp ? value0 : value1 If boolean-exp evaluates to true, value0 is evaluated and its result becomes the value produced by the operator. If boolean-exp is false, value1 is evaluated and its result becomes the value produced by the operator. The conditional operator can be used for its side effects or for the value it produces, but in general we want the value since thats what makes the operator distinct from the if-else. Heres an example:
static int ternary(int i) { return i < 10 ? i * 100 : i * 10; }

We can see that this code is more compact than what wed need to write without the ternary operator:
static int alternative(int i) { if (i < 10) return i * 100; else return i * 10; }

Control flow
Java, like any programming language, supports both conditional statements and loops to determine control flow. We start with the conditional statements and then move on to loops. We end with the somewhat cumbersome switch statement that we can use when we have to test for many values of a single expression.

CONDITIONAL STATEMENTS
The conditional statement in Java has the form

if statement
if ( condition ) statement In Java, as in most programming languages, we will often want to execute multiple statements when a single condition is true. For example:
if (ourSales >= target) { performance = "Satisfactory"; bonus = 100; }

12

if/else statement
if ( condition ) statement 1 else statement 2;

For example:
if (ourSales >= target) { performance = "Satisfactory"; bonus = 100 + 0.01 * (ourSales - target); } else { performance = "Unsatisfactory"; bonus = 0; }

if / elseif (multiple branches) statement


Repeated if . . . else if . . . alternatives are very common For example:
if (ourSales >= 2 * target) { performance = "Excellent"; bonus = 1000; } else if (ourSales >= 1.5 * target) { performance = "Fine"; bonus = 500; } else if (ourSales >= target) { performance = "Satisfactory"; bonus = 100; } else { System.out.println("We're fired"); }

Indeterminate Loops
In Java, as in all programming languages, there are control structures that let us repeat statements. There are two forms for repeating loops that are best when we do not know how many times a loop should be processed (these are indeterminate loops). First, there is the while loop that only executes the body of the loop while a condition is true . The general form is:
while ( condition ) statement

The while loop will never execute if the condition is false at the outset see Figure 3-10). For example:
while (balance < goal) { balance += payment; double interest = balance * interestRate / 100; balance += interest; years++; }

A while loop tests at the top. Therefore, the code in the block may never be executed. If we want to make sure a block is executed at least once, we will need to move the test to the bottom. This is done with the do / while loop. Its syntax looks like this:

13

do statement while ( condition ); do { balance += payment; double interest = balance * interestRate / 100; balance += interest; year++; // print current balance . . . // ask if ready to retire and get input . . . } while (input.equals("N"));

DETERMINATE LOOPS
The for loop is a very general construct to support iteration that is controlled by a counter or similar variable that is updated after every iteration. The following is the syntax :
for ( statement 1; expression 1; expression 2) statement 2;

The following loop prints the numbers from 1 to 10 on the screen.


for (int i = 1; i <= 10; i++) System.out.println(i);

Multiple Selectionsthe switch Statement


The if/else construct can be cumbersome when we have to deal with multiple selections with many alternatives. Java has a switch statement that is exactly like the switch statement. The syntax,
switch (choice) { case 1: . . . break; case 2: . . . break; case 3: . . . break; case 4: . . . break; default: // bad input . . . break; }

Arrays
An array is a data structure that stores a collection of values of the same type. We access each individual value through an integer index. For example, if a is an array of integers, then a[i] is the ith integer in the array. We declare an array variable by specifying the array typewhich is the element type followed by []and the array variable name. For example, here is the declaration of an array a of integers: int[] a;

14

However, this statement only declares the variable a. It does not yet initialize a with an actual array. We use the new operator to create the array. int[] a = new int[100]; This statement sets up an array that can hold 100 integers. The array entries are numbered from 0 to 99 (and not 1 to 100). Once the array is created, we can fill the entries in an array, for example, by using a loop:
int[] a = new int[100]; for (int i = 0; i < 100; i++) a[i] = i; // fills the array with 0 to 99

We can define an array variable either as


int[] a; or as int a[];

Most Java programmers prefer the former style because it neatly separates the type int[] (integer array) from the variable name.

Array Initializers and Anonymous Arrays


Java has a shorthand to create an array object and supply initial values at the same time. Here's an example of the syntax at work:
int[] smallPrimes = { 2, 3, 5, 7, 11, 13 }; Array Inititalization with new operator. The syntax is Datatype arrayname[] = new datatype[arraysize];
For Example: int[] a = new int[10]; . . . Program //To get string values from the command prompt and to display the values public class array1 { public static void main(String arg[]) { int size = arg.length; System.out.println(The Elements are); for(int i=0;i<size;i++) System.out.println(arg[i]); } } output: c:\>javac array1.java

15

c:\>java array1 C C++ PASCAL COBOL JAVA

The Elements are C C++ PASCAL COBOL JAVA

Multidimensional Arrays
Multidimensional arrays use more than one index to access array elements. They are used for tables and other more complex arrangements. Declaring a matrix in Java is simple enough. For example: double[][] matrix; As always, we cannot use the array until we initialize it with a call to new . In this case, we can do the initialization as follows: matrix = new double[5][5]; In other cases, if we know the array elements, we can use a shorthand notion for initializing multidimensional arrays without needing a call to new . For example;
int[][] magicSquare = { {16, 3, 2, 13}, {5, 10, 11, 8}, {9, 6, 7, 12}, {4, 15, 14, 1} }; program // To print a multidimensional arrays public class array2 { public static void main(String arg[]) { int[][] matrix = { {16, 3, 2, 13}, {5, 10, 11, 8}, {9, 6, 7, 12}, {4, 15, 14, 1} }; System.out.println("The given matrix is\n\n"); for(int i=0;i<4;i++) { for(int j=0;j<4;j++) { System.out.print(matrix[i][j]+"\t"); } System.out.println("\n"); } } }

16

output c:\>javac array2.java c:\>java array2 The given matrix is 16 5 9 4 3 10 6 15 2 11 7 14 13 8 12 1

1.3 OBJECT AND CLASSES


Introduction to Object-Oriented Programming
Object-oriented programming (or OOP for short) is the dominant programming paradigm these days, having replaced the structured, procedure-based programming techniques that were developed in the early '70s. Java is totally object oriented, and it is impossible to program it in the procedural style that we may be most comfortable with. We need to understand some of the terminology of OOP to go further. The most important term is the class, A class is the template or blueprint from which objects are actually made. This leads to the standard way of thinking about classes: as cookie cutters. Objects are the cookies themselves. When we construct an object from a class, we are said to have created an instance of the class. apply a method to an object, its state may change. manipulate the data, no other object will know or care. As we have seen, all code that we write in Java is inside a class. Encapsulation (sometimes called data hiding) is a key concept in working with objects. Formally, encapsulation is nothing more than combining data and behavior in one package and hiding the implementation of the data from the user of the object. The data in an object are called its instance fields, and the functions and procedures that operate on the data are called its methods. A specific object that is an instance of a class will have specific values for its instance fields. The set of those values is the current state of the object. Whenever we apply a method to an object, its state may change. When we extend an existing class, the new class has all the properties and methods of the class that we extend. We supply new methods and data fields that apply to our new class only. The concept of extending a class to obtain another class is called inheritance. The syntax for creating a class is
class classname { variable declarations method definitions }

Here the class, is the keyword which should be prefixed in a class definition. All the data and methods are enclosed inside the class. We can place more than one class in a file, in that case 17

only one class can have the main method and it should be public. This file should be saved as the name of the main method class. The following program consists of two classes and saved as a math.java ( main method class name ).
Program class methodclass { int x,y; int add(int m, int n) { return m+n; } int sub(int m, int n) { return m-n; } int mul(int m, int n) { return m*n; } int div(int m, int n) { return m/n; } } public class math { public static void main(String arg[]) { if(arg.length==2) { methodclass m = new methodclass(); int a = Integer.parseInt(arg[0]); int b = Integer.parseInt(arg[1]); System.out.println("Arithmetic Operations\n"); System.out.println("The given numbers are "+a+", "+b); System.out.println("Addition : "+m.add(a,b)); System.out.println("Subtraction : "+m.sub(a,b)); System.out.println("Multiplication : "+m.mul(a,b)); System.out.println("Division : "+m.div(a,b)); } else { System.out.println("Invalid input, Usage : java math number1 } } } output c:\>javac math.java c:\>java math 22 6 The given numbers are 22, 6 Addition :28 Subtraction :16 Multiplication :132 Division :3

number2");

18

C:\>java math Invalid input, Usage : java math number1 C:\>java math 44 5 7 Invalid input, Usage : java math number1

number2 number2

Objects and Object Variables


To work with objects, we first construct them and specify their initial state. Then we apply methods to the objects. In the Java programming language, we use constructors to construct new instances. A Constructor is a special method whose purpose is to construct and initialize objects. Constructor always have the same name as the class name. Thus, the constructor for the Date class is called Date . To construct a Date object, we combine the constructor with the new operator, as follows: new Date() While writing a constructor, keep the following in our mind A constructor has the same name as the class. A class can have more than one constructor. A constructor may take zero, one, or more parameters. A constructor has no return value. A constructor is always called with the new operator.

Syntax for creating an object for a class classname objectname = new classname(); For Example: Date Birthday = new Date(); Through an object we can access any method of the particular class, For this we use a special kind of operator called Dot operator .. int d = Birthday.get(Calendar.DAY_OF_MONTH); int m = Birthday.get(Calendar.MONTH);

1.4 INHERITANCE
Inheritance, another fundamental concept of object-oriented programming. The idea behind inheritance is that we can create new classes that are built upon existing classes. When we inherit from an existing class, we reuse (or inherit) methods and fields, and we add new methods and fields to adapt our new class to new situations.

19

Base

Derived

(The arrow in the above UML diagram points from the derived class to the base class. As we will see, there can be more than one derived class.) We have two ways to differentiate our new derived class from the original base class. The first is: We simply add new functions to the derived class. These new functions are not part of the base class interface. The second and more important way to differentiate our new class is to change the behavior of an existing base-class function. This is referred to as overriding that function.

Here is how we define a Derived class that inherits from the Base class. We use the Java keyword extends to denote inheritance.
class Derived extends Base { added methods and fields }

1.5 PACKAGE AND INTERFACE


PACKAGE:There is a large set of predefined classes, grouped into packages. The full name of one of these predefined classes includes the name of the package as prefix. For example, the library class java.util.Random is in package java.util, and a program may use the class with code like this: java.util.Random r = new java.util.Random();

20

The import statement allows we to omit the package name from one of these classes. A Java program that includes the line import java.util.Random; can abbreviate the use of Random to Random r = new Random(); We can import all the classes in a package at once with a notation like import java.util.*; The package java.lang is special; every program behaves as if it started with import java.lang.*; whether it does or not. We can define our own packages, but defining packages is an advanced topic beyond the scope of what's required for this course. The import statement doesn't really "import" anything. It just introduces a convenient abbreviation for a fully-qualified class name. When a class needs to use another class, all it has to do is use it. The Java compiler will know that it is supposed to be a class by the way it is used, will import the appropriate .class file, and will even compile a .java file if necessary. (That's why it's important for the name of the file to match the name of the class). For example, here is a simple program that uses two classes:
public class HelloTest { public static void main(String[] args) { Hello greeter = new Hello(); greeter.speak(); } } public class Hello { void speak() { System.out.println("Hello World!"); } }

Put each class in a separate file (HelloTest.java and Hello.java). Then try this: javac HelloTest.java java HelloTest We should see a cheery greeting. If we type ls we will see that we have both HelloTest.class and Hello.class even though we only asked to compile HelloTest.java. The Java compiler figured out that class HelloTest uses class Hello and automatically compiled it. Try this to learn more about what's going on: rm -f *.class javac -verbose HelloTest.java java HelloTest

INTERFACE
The interface keyword takes the abstract concept one step further. We could think of it as a pure abstract class. It allows the creator to establish the form for a class: method names, argument lists, and return types, but no method bodies. An interface can also contain fields, but these are implicitly static and final. An interface provides only a form, but no implementation. 21

To create an interface, use the interface keyword instead of the class keyword. Like a class, we can add the public keyword before the interface keyword (but only if that interface is defined in a file of the same name) or leave it off to give friendly status so that it is only usable within the same package. To make a class that conforms to a particular interface (or group of interfaces) use the implements keyword. Once weve implemented an interface, that implementation becomes an ordinary class that can be extended in the regular way. A simple example is as follows:
interface Area{ float pi=3.14f; float compute (float x, float y); } class rect implements Area{ public float compute(float x, float y){ return x*y; } } class cir implements Area{ public float compute(float x, float y){ return pi*x*y; } intfacetest { public static void main(String arg[]) [ rect r=new rect(); cir c=new cir(); System.out.println(Rect= +r.compute(10.20)); System.out.println(Cir= +c.compute(10.20));

} class

} }

1.6 EXCEPTION HANDLING EXCEPTIONS


A Java program should never "core dump," no matter how buggy it is. If the compiler excepts it and something goes wrong at run time, Java throws an exception. By default, an exception causes the program to terminate with an error message, but we can also catch an exception. try {
// ... foo.bar(); // ... a[i] = 17; // ...

} catch (IndexOutOfBoundsException e) {err.println("Oops: " + e); }

22

The try statement says we're interested in catching exceptions. The catch clause (which can only appear after a try) says what to do if an IndexOutOfBoundsException occurs anywhere in the try clause. In this case, we print an error message. The toString() method of an exception generates a string containing information about what went wrong, as well as a call trace. WARNING Never write an empty catch clause. If we do, we will regret it. Maybe not today, but tomorrow and for the rest of our life. Because we caught this exception, it will not terminate the program. If some other kind of exception occurs (such as divide by zero), the exception will be thrown back to the caller of this function and if that function doesn't catch it, it will be thrown to that function's caller, and so on back to the main function, where it will terminate the program if it isn't caught. Similarly, if the function foo.bar throws an IndexOutOfBoundsException and doesn't catch it, we will catch it here. The catch clause actually catches IndexOutOfBoundsException or any of its subclasses, including ArrayIndexOutOfBoundsException , StringIndexOutOfBoundsException , and others. An Exception is just another kind of object, and the same rules for inheritance hold for exceptions as any other king of class. We can define and throw our own exceptions.
class SytaxError extends Exception { int lineNumber; SytaxError(String reason, int line) { super(reason); lineNumber = line; } public String toString() { return "Syntax error on line " + lineNumber + ": " + getMessage(); } } class SomeOtherClass { public void parse(String line) throws SyntaxError { // ... if (...) throw new SyntaxError("missing comma", currentLine); //... } public void parseFile(String fname) { //... try { // ... nextLine = in.readLine(); parse(nextLine); // ... } catch (SyntaxError e) { err.println(e); } }}

23

Each function must declare in its header (with the keyword throws) all the exceptions that may be thrown by it or any function it calls. It doesn't have to declare exceptions it catches. Some exceptions, such as IndexOutOfBoundsException, are so common that Java makes an exception for them (sorry about that pun) and doesn't require that they be declared. This rule applies to RuntimeException and its subclasses. We should never define new subclasses of RuntimeException. There can be several catch clauses at the end of a try statement, to catch various kinds of exceptions. The first one that "matches" the exception (i.e., is a super class of it) is executed. We can also add a finally clause, which will always be executed, no matter how the program leaves the try clause (whether by falling through the bottom, executing a return, break, or continue, or throwing an exception).

1.7 THREADING
Java lets we do several things at once by using threads. If our computer has more than one CPU, it may actually run two or more threads simultaneously. Otherwise, it will switch back and forth among the threads at times that are unpredictable unless we take special precautions to control it. There are two different ways to create threads. I will only describe one of them here.
Thread t = new Thread(command); // t.start(); // t start running command, but we don't wait for it to finish // ... do something else (perhaps start other threads?) // ... later: t.join(); // wait for t to finish running command

The constructor for the built-in class Thread takes one argument, which is any object that has a method called run. This requirement is specified by requiring that command implement the Runnable interface described earlier. (More precisely, command must be an instance of a class that implements Runnable). The way a thread "runs" a command is simply by calling its run() method. It's as simple as that! In project 1, we are supposed to run each command in a separate thread. Thus we might declare something like this:
class Command implements Runnable { String commandLine; Command(String commandLine) { this.commandLine = commandLine; } public void run() { // Do what commandLine says to do } }

24

We can parse the command string either in the constructor or at the start of the run() method. The main program loop reads a command line, breaks it up into commands, runs all of the commands concurrently (each in a separate thread), and waits for them to all finish before issuing the next prompt. In outline, it may look like this.
for (;;) { out.print("% "); out.flush(); String line = inputStream.readLine(); int numberOfCommands = // count how many commands there are on the Thread t[] = new Thread[numberOfCommands]; for (int i=0; i<numberOfCommands; i++) { String c = // next command on the line t[i] = new Thread(new Command(c)); t[i].start(); } for (int i=0; i<numberOfCommands; i++) { t[i].join(); }

line

This main loop is in the main() method of our main class. It is not necessary for that class to implement Runnable. Although we won't need it for project 1, the next project will require to to synchronize threads with each other. There are two reasons why we need to do this: to prevent threads from interfering with each other, and to allow them to cooperate. We use synchronized methods to prevent interference, and the built-in methods Object.wait() , Object.notify() , Object.notifyAll() , and Thread.yield() to support cooperation. Any method can be preceded by the word synchronized (as well as public, static, etc.). The rule is: No two threads may be executing synchronized methods of the same object at the same time. The Java system enforces this rule by associating a monitor lock with each object. When a thread calls a synchronized method of an object, it tries to grab the object's monitor lock. If another thread is holding the lock, it waits until that thread releases it. A thread releases the monitor lock when it leaves the synchronized method. If one synchronized method of a calls contains a call to another, a thread may have the same lock "multiple times." Java keeps track of that correctly. For example,
class C { public synchronized void f() { // ... g(); // ... } public synchronized void g() { /* ... */ } }

If a thread calls C.g() "from the outside", it grabs the lock before executing the body of g() and releases it when done. If it calls C.f(), it grabs the lock on entry to f(), calls g() without waiting, and only releases the lock on returning from f(). 25

Sometimes a thread needs to wait for another thread to do something before it can continue. The methods wait() and notify(), which are defined in class Object and thus inherited by all classes, are made for this purpose. They can only be called from within synchronized methods. A call to wait() releases the monitor lock and puts the calling thread to sleep (i.e., it stops running). A subsequent call to notify on the same object wakes up a sleeping thread and lets it start running again. If more than one thread is sleeping, one is chosen arbitrarily 2 and if no threads are sleeping in this object, notify() does nothing. The awakened thread has to wait for the monitor lock before it starts; it competes on an equal basis with other threads trying to get into the monitor. The method notifyAll is similar, but wakes up all threads sleeping in the object.
class Buffer { private List queue = new ArrayList(); public synchronized void put(Object o) { queue.add(o); notify(); } public synchronized Object get() { while (queue.isEmpty()) { wait(); } return queue.remove(0); } }

This class solves the so-call "producer-consumer" problem. (The class ArrayList and interface List are part of the java.util package.) "Producer" threads somehow create objects and put them into the buffer by calling Buffer.put(), while "consumer" threads remove objects from the buffer (using Buffer.get()) and do something with them. The problem is that a consumer thread may call Buffer.get() only to discover that the queue is empty. By calling wait() it releases the monitor lock and goes to sleep so that producer threads can call put() to add more objects. Each time a producer adds an object, it calls notify() just in case there is some consumer waiting for an object. This example is not correct as it stands (and the Java compiler will reject it). The wait() method can throw an InterruptedException exception, so the get() method must either catch it or declare that it throws InterruptedException as well. The simplest solution is just to catch the exception and print it:
class Buffer { private List queue = new ArrayList(); public synchronized void put(Object o) { queue.add(o); notify(); } public synchronized Object get() { while (queue.isEmpty()) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); }

26

} return queue.remove(0); } }

The method printStackTrace() prints some information about the exception, including the line number where it happened. It is a handy thing to put in a catch clause if we don't know what else to put there. Never use an empty catch clause. If we violate this rule, we will live to regret it! There is also a version of Object.wait() that takes an integer parameter. The call wait(n) will return after n milliseconds if nobody wakes up the thread with notify or notifyAll sooner. We may wonder why Buffer.get() uses while (queue.isEmpty()) rather than if (queue.isEmpty()). In this particular case, either would work. However, in more complicated situations, a sleeping thread might be awakened for the "wrong" reason. Thus it is always a good idea when we wake up to recheck the condition that made to decide to go to sleep before we continue.

1.8 INPUT AND OUTPUT


Input/Output is not as complicated as it looks. We can get pretty far just writing to System.out (which is of type PrintStream ) with methods print , println , and printf . The method print simply writes converts its argument to a String and writes it to the output stream. The method println is similar, but adds a newline so that following output starts on a new line. The method printf is new in Java 1.5. It expects a String as its first argument and zero or more additional arguments. Each '%' in the first argument indicates a request to print one of the other arguments. The details are spelled out by one or more characters following the '%'. For example, out.printf("pair(%d, %d)%n", pair.x, pair.y); produces exactly the same thing as out.println("pair(" + pair.x + "," + pair.y + ")"); but is much easier to read, and to write. The characters %d are replaced by the result of converting the next argument to a decimal integer. Similarly, "%f" looks for a float or double, "%x" looks for an integer and prints it in hexadecimal, and "%s" looks for a string. Fancier formatting is supported; for example, "%6.2f" prints a float or double with exactly two digits following the decimal point, padding with leading spaces as necessary to make the result at least 6 character long. For input, we probably want to wrap the standard input System.in in a BufferedReader , which provides the handy method readLine()
BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); for(;;) { String line = input.readLine(); if (line == null) { break; } // do something with the next line }

27

If We want to read from a file, rather than from the keyboard (standard input), we can use FileReader, probably wrapped in a BufferedReader.
BufferedReader input = new BufferedReader(new FileReader("somefile")); for (;;) { String line = input.readLine(); if (line == null) { break; } // do something with the next line }

Similarly, we can use new PrintWriter(new FileOutputStream("whatever")) to write to a file.

28

CHAPTER II INTRODUCTION TO J2EE

Today, Java is one of the most mature and commonly used programming languages for building enterprise software. The evolution of Java from a means of developing applets to be run in browsers, to a programming module capable of driving today is enterprise applications has been remarkable. Over the years, java has evolved into three different platform editions, each addressing a distinct set of programming needs;

The Java 2 Platform , Standard Edition (J2SE) :


This is most commonly used of these java platforms, consisting of a runtime environment and a set of APIs for building a wide variety of applications ranging from applets, through stand alone applications that run on over various platforms, to client applications for various enterprise applications.

The Java 2 Platform , Enterprise Edition (J2EE) :


J2EE is a platform for building server-side applications.

The Java 2 Platform, Micro Edition (J2ME):


The latest addition to the java family, this edition enables the building of java applications for Micro devices.

The J2EE Platform


J2EE specifies both the infrastructure for managing our applications, and the service APIs for building our applications. The J2EE Platform is essentially distributed application-server environment - a java environment that provides the following; A set of java extension APIs to build applications. These APIs define a programming model for J2EE applications. A run-time infrastructure for hosting and managing applications. This is the server runtime in which our application reside. The applications that we could develop with the above may be programs to drive web pages, or components to implement complex data base transactions, or even java applets, all distributed across the network.

29

The J2EE APIs


Distributed applications require access to a set of enterprise services. Typical services include transaction processing, database access, multithreading, etc. The J2EE architecture unifies access to such services in its enterprise service APIs. However, instead of having to access these service through proprietary or non-standard interfaces, application programs in J2EE can across these APIs via the container. A typical commercial J2EE platform (or J2EE application server) includes one or more containers, and access to the enterprise APIs is specifies by the J2EE. The specification of the J2EE platform includes a set of Java standard extensions that each J2EE platform must support:

JDBC
More specifically, the JDBC optional package. This API improves the standard JDBC API by adding more efficient means of obtaining connections, connection pooling, distributed transaction, etc.

Enterprise JavaBeans (EJB)


This specifies a component framework for multi-tier distributed applications. This provides a standard means of defining server-side components, and specifies a rich run-time infrastructure for hosting components on the server side.

Java Servlets
The Java Servlets API provides object-oriented abstractions for building dynamic web applications.

JavaServer Pages
This extension further enhances J2EE web applications by providing for template-driven web application development.

Java Message Service


JMS provides a Java API for message queuing, and publish and subscribe types of messageoriented middleware services.

Java Transaction API (JTA)


This API is for implementing distributed transactional applications.

30

Java Mail
This API provides a platform-independent and protocol-independent framework to build Java based email applications.

JavaBeans Activation Framework


This API is required for the Java Mail API. The Java Mail API uses JAF to determine the contents of a MIME (Multipurpose Internet Mail Extension) message and determine what appropriate operations can be done on different parts of a mail message.

Java API for XML Parsing (JAXP)


This API provides abstractions for XML parsers and transformation APIs. JAXP helps to isolate specific XML parsers, or XML Document Object Model (DOM) implementations, or XSLT transformation APIs from J2EE application code.

The Java Connector Architecture (JCA)


This API has recently been included in J2EE, and provides a means to integrate J2EE application components to legacy information systems.

Java Authentication and Authorization Service (JAAS)


This API provides authentication and authorization mechanisms to J2EE applications. Most of these API are specifications, independent of implementation. That is, one should be able to access services provided by these APIs in a standard way, irrespective of how they are implemented. The J2EE-specific APIs mentioned above are in addition to the following J2SE APIs:

Java Interface Definition Language (IDL) API


This API allows J2EE application components to invoke CORBA objects via IIOP

JDBC Core API


This API provides the basic database programming facilities.

RMI-IIOP API
This provides on implementation of the usual Java Remote Method Invocation (RMI) API over the Internet Inter-ORB protocol (IIOP). This bridges the gap between RMI and CORBA applications. This is the standardized communication protocol to be used between J2EE containers.

31

JNDI API
The Java Naming and Directory Interface (JNDI) API standardized access to different types of naming and directory services available today. This API is designed to be independent of any specific naming or directory service implementations. J2SE also specifies a JNDI service provider interface (SPI), for naming and directory service providers to implement.

2.2 J2EE ARCHITECTURE


A typical commercial J2EE, platform includes one or more containers. But what exactly is a container? A J2EE container is a runtime to manage application components developed according to the API specifications, and to provide access to the J2EE APIs. Beyond the Identity associated with the runtime, J2EE does not specify any identity for containers. This gives a great amount of flexibility to achieve a variety of features within the container runtime. The following figure shows the architecture of J2EE in terms of its containers and APIs:

This architecture shows four containers : A web container for hosting Java servlets and JSP pages. An EJB container for hosting Enterprise JavaBeans components. An applet container for hosting Java applets. An application client container for hosting standard Java applications. 32

Each of these containers provides a run-time environment for the respective components. J2EE components are also called managed objects, as these objects are created and managed within the container runtime. In this architecture, there are primarily two types of clients:

Web clients normally run in web browsers.


For these clients, the user interface is generated on the server side as HTML or XML, and its downloaded and then rendered by the browsers. These clients use HTTP to communicate with web containers. Application components in web containers include Java servlets and JSP pages. These components implement the functionality required for the clients. Web containers are responsible for accepting requests from web clients, and generating responses with the help of the application components.

EJB clients are applications that access EJB components in EJB container.
There are three possible types of EJB clients. First categories application clients. Application clients are standalone applications accessing the EJB components using RMI-IIOP protocol. The second category of application clients are components in the web container. That is, Java servlets and JSP pages can also access the EJB components via the RMI-IIOP protocol in the same way as the application clients. The final category is other EJBs running within the EJB container. These communicate via standard Java method calls through a local interface.

J2EE Technologies
J2EE technologies that provide the mechanics we need to build large, distributed enterprise applications. This large collection, of quite disparate technologies, can be divided according to use:

The component technologies


These technologies are used to hold the most important part of the application-the business logic. There are three types of components: JSP pages, servlets and Enterprise JavaBeans.

The service technologies


These technologies provide the applications components with supported services to function efficiently.

The communication technologies


These technologies, which are mostly transparent to the application programmer, provide the mechanisms for communication among different parts of the application, whether they are local or remote.

33

2.3 COMPONENT TECHNOLOGIES


These components will be dependent upon the container for many services, such as life cycle management, threading, and security. These allows us to concentrate on providing the requisite business functionality without getting into details of low-level (container-level) semantics.

Web components
These can be categorized as any component that response to an HTTP request. A further distinction can be drawn is based on the hosting container for the application components.

Servlets
Servlets are server side programs that allow application logic to be embedded in the HTTP request-response process. Servlets provide a means to extends the functionality of the web server to enable dynamic content in HTML, XML, or other web languages.

JavaServer Pages
JavaServer Pages (JSP) provides a way to embed components in a page, and to have them

do their work to generate the page is eventually send to the client. A JSP page can contain HTML, Java code, and JavaBean components. JSP pages are infact an extension of the servlets programming model. When a user requests a JSP page, a web container compiles the JSP page into a servlets. The web container then invokes the servlets and returns the resulting content to the web browser. Thus, JSP pages provide a powerful and dynamic page assembly mechanism that benefits from the many advantages of the Java platform.

Enterprise JavaBean components


(EJB) is a distributed component model for developing secure, scalable, transactional, and multi-user components. To put it simply, EJBs are reusable software units containing business logic. Just as JSP pages allow the separation of application and presentation logic, EJBs allow separation of application logic from system-level services thus allowing the developer to concentrate on the business domain issues and not system programming. These enterprise bean business objects take three basic forms again, It is not necessary to implement them all session beans, entity beans, and message driven beans. Enterprise JavaBeans

Session Beans
Session beans themselves come in two types. A stateful session bean is a transient object used to represent a clients interaction with the system it performs the clients request in the application, accessing a database etc., and when the clients operations are compleate and it is destroyed. The alternative, a stateless session bean, maintains no state between client requests. Generally this type of session bean is used to implement a specific service that does not require client state.

34

Entity Beans
An entity bean on the other hand is a persistent object that models the data held within the data store , that is, it is an object wrapper for the data. Compared to session beans that can be used by any client, entity beans can be accessed concurrently by many clients but must maintain a unique identity through a primary key.

Message-Driven Beans
Message-driven beans are a special class of EJBs that are not meant for direct client invocation. The purpose of message-driven beans is to process messages received via JMS. Message-driven beans complement the asynchronous nature of JMS by providing a means of processing messages within the EJB container. When an application client or an application sends a message via JMS, the container invokes the appropriate message-driven bean to process the message.

2.4 SERVICE TECHNOLOGIES


Some of the J2EE services for application components are managed by the containers themselves, thus allowing the developer to concentrate on the business logic. However, there will be times when developers find it necessary to programmatically invoke some services themselves using some of the various service technologies.

JDBC
Although all data access should be accessible through the single standard API of the Connector architecture in the future, database connectivity is probably one of the key services that developers implement in their application component. The JDBC API provides the developer with the ability to connect to relational database systems. It allows the transactional querying, retrieval, and manipulation of data from a JDBC-complaint database.

Java transaction API and service


The Java Transaction API (JTA) is a means for working with transactions and especially distributed transactions independent of the transaction managers implementation.

JNDI
The Java Naming and Directory Interface (JNDI) API standardized access to different types of naming and directory services available today. This API is designed to be independent of any specific naming or directory service implementations. J2SE also specifies a JNDI service provider interface (SPI), for naming and directory service providers to implement.

35

Java Message Service (JMS)


JMS provides a Java API for message queuing, and publish and subscribe types of messageoriented middleware (MOM) services.

Java Mail
This API provides a platform-independent and protocol-independent framework to build Java based email applications

The Java Connector Architecture (JCA)


This API has recently been included in J2EE, and provides a means to integrate J2EE application components to legacy information systems.

Java Authentication and Authorization Service (JAAS)


This API provides authentication and authorization mechanisms to J2EE applications. It provides a means to grant permissions based on who is executing the code.

2.5 COMMUNICATION TECHNOLOGIES


The final technology grouping is those technologies that provide the means for the various components and services within a J2EE application to communicate with each other a distributed application would be pretty ineffectual if these technologies didnt provide the glue to hold it all together.

Internet Protocols
A client request and the servers responses are communicated over three main protocols.

HTTP
HTTP or Hypertext Transfer Protocol is a generic, stateless, application-level protocol, which has many uses beyond simply hypertext capabilities. It works on a request/response basis. A client sends a request to a server in the form of a request method, URI (Uniform Resource Identifier), and protocol version, followed a MIME-like message containing request modifiers, client information, and possible body content over a connection with a server. The server in turn responds with a ststus line followed by a MIME-like message containing server information, entity-meta information, and possible entity-body content.

TCP/IP
TCP(Transmission Control Protocol) over IP(Internet Protocol) is actually two separate protocols, which are typically combined into a single entity. IP is a protocol that takes care of

36

making sure that data is received by both endpoints in communication over the Internet. When we type the address of the website into our browser, IP is what ensures that our request and the fulfillment of those requests make it to the proper destinations. TCP is the protocol that keeps track of the packets and make sure they are assembled in the same order as they were dispatched and are error free. Therefore, TCP and IP work together to move data around on the Internet.

SSL
Secure Sockets Layer (SSL) uses cryptography to encrypt the flow of information between the client and the server. This also provides a means for both parties to authenticate each other. Secure HTTP (HTTPs) is usually distinguished from regular unencrypted HTTP by being served on a different port number.

Remote object Protocols


In applications where the components are often distributed across many tiers and servers, some mechanism for using the components remotely I srequired, preferably leaving the client unaware that the component is not local to itself.

RMI and RMI-IIOP


Remote Method Invocation (RMI) is one of the primary mechanism in distributed object applications. It allows us to use interface to define remote objects. We can then call methods on these remote objects as if they were local. The exact wire-level transportation mechanism is implementation-specific. RMI-IIOP is an extension of RMI but over IIOP (Inter-ORB Protocol) , which allows us to define a remote interface to any remote object that can be implemented in any language that supports OMG mapping and ORB.

2.6 SERVERS
The J2EE platform is a large collection of APIs, all working together to provide a unified platform for enterprise development. The J2EE platform consists of various components and services that are available and operate in containers. However, J2EE itself does not actually implement these components but relies on third-party vendors to provide the actual implementation. That implementation is called J2EE application servers.

Features of an application server


The following are the features that an application server should provide: Scalability Client agnosticism Server management Development

37

The term application server as we know it today is assigned to a product that implements the J2EE standard and offers a web container and EJB container, as a minimum, packaged as server software. This product must comply with a version of J2EE standards, preferably the latest and be able to provide:

Web and EJB container


An environment for component based applications to map easily to the functionality desired from the application.

Component behavior
To enable assembly and deploy-time behaviors. Components can expect the availability of services in run-time environment, and can be connected to other components providing a set of well-defined interfaces. As a result, components can be configured for a certain type of behavior at application assembly or deployment time without any recoding required.

Scalability
J2EE containers must provide a mechanism that supports simplified scaling of distributed applications, without requiring any effort on the part of the application development team. Clustering is one of the features used to fulfill this standard requirement.

Integration with existing enterprise systems


This can be done with a number of standard APIs that have to be supported in a J2EE implementation: JDBC APIs for accessing relational data from Java. Java Transaction API (JTA) for managing and coordinating transactions across heterogenous enterprise information systems. Java Naming and Directory Interface (JNDI) API for accessing information in enterprise name and directory services. Java Messaging Service (JMS) API for sending and receiving messages via enterprise messaging systems like IBM MQ Series, or TIBCO Rendezvous. JavaMail APIs for sending and receiving e-mails. Java IDL APIs for calling CORBA services. Security services like the Java Authentication and Authorization Service (JAAS).

While the J2EE specification defines the component containers that must be supported and the APIs that should be available. It does not try to specify or restrict the configuration of these containers, and the layout of the services. Thus, both container types can run either on a single platform or on a distributed environment.

Examining Full J2EE Implementations


The available application servers that fully support the J2EE platform. They implement what is effectively a one-stop shop for our J2EE needs. Even though the J2EE platform is middleware

38

and we may opt for one J2EE component, we are not tied to its whole implementation; we are still free to swap in third-party implementations to replace specific layers. The following are the application servers that fully support the J2EE platform. BEA WebLogic Borland Enterprise Server IBM WebSphere JBoss Oracle 9iAS Orion Application Server Sun ONE

Examining Partial J2EE Implementations Without a doubt, the J2EE platform is large, Many developers will only ever use servlets and JSP; the requirement to install the full J2EE server is overkill for them. The Servlet API is one of the oldest and best-established APIs of the J2EE platform. Many servlets engines on the market provide support for the full Servlet API and JSP specifications, and these are some of the more popular ones: Apache Tomcat Resin ServletExec

39

CHAPTER III JDBC


3.1 Introduction to JDBC
JDBC provides a standard library for accessing relational databases. Using the JDBC API, we can access a wide variety of different SQL databases with exactly the same Java syntax. It is important to note that although JDBC standardizes the mechanism for connecting to databases, the syntax for sending queries and committing transactions, and the data structure representing the result, it does not attempt to standardize the SQL syntax. So, we can use any SQL extensions our database vendor supports. However, since most queries follow standard SQL syntax, using JDBC lets us change database hosts, ports, and even database vendors with minimal changes in our code. Officially, JDBC is not an acronym and thus does not stand for anything. Unofficially, Java Database Connectivity is commonly used as the long form of the name.

The JDBC API versus ODBC


Prior to the development of the JDBC API, Microsoft's ODBC (Open DataBase Connectivity) API was the most widely used programming interface for accessing relational databases. It offers the ability to connect to almost all databases on almost all platforms. So why not just use ODBC from the Java programming language? 1. A literal translation of the ODBC C API into a Java API would not be desirable. For example, Java has no pointers (address variables), and ODBC makes copious use of them, including the notoriously error-prone generic pointer void *. We can think of JDBC as ODBC translated into a high-level object-oriented interface that is natural for programmers using the Java programming language. 2. ODBC is hard to learn. It mixes simple and advanced features together, and it has complex options even for simple queries. The JDBC API, on the other hand, was designed to keep simple things simple while allowing more advanced capabilities where required. The JDBC API is also easier to use simply because it is a Java API, which means that a programmer does not need to worry about either memory management or data byte alignment. 3. A Java API like JDBC is needed in order to enable a "pure Java" solution, that is, a solution that uses only Java API. When ODBC is used, the ODBC driver manager and drivers must be manually installed on every client machine. When the JDBC driver is written completely in Java, however, JDBC code is automatically installable, portable, and secure on all Java platforms, from network computers to mainframes. 4. The JDBC API includes functionality that is not available with ODBC. For example, ODBC does not support SQL99 data types, auto-generated keys, or savepoints. JDBC comes in two parts: the portable JDBC API provided with Java, and the database-specific driver usually provided by the DBMS vendor or a third party. These drivers have to conform to a particular interface (called Driver) and map from the generic calls into something the existing database code can understand. JDBC API comes in two packages java.sql and javax.sql. 40

3.2 TYPES OF DRIVERS


JDBC drivers are divided into four types or levels. Each type defines a JDBC driver implementation with increasingly higher levels of platform independence, performance, and deployment administration. The four types are:

Type 1: JDBC-ODBC Bridge Type 2: Part Java Part Native Driver Type 3: The Network Protocol Driver Type 4: Pure Java driver

Type 1: JDBC-ODBC Bridge


Java program Data source

JDBC API

JDBCODBC Bridge

ODBC API

ODBC Layer

Type 2: Part Java Part Native Driver Java program

Data source

JDBC API

JDBC Driver

Vendor Specifi c API

Type 2 driver use a mixture of java implementation and vendor specific native APIs to provide data access. JDBC database calls are translated into vendor-specific API calls. The database will process the request and send the result back through the API ,which will turn forward back to 41

the JDBC driver. The JDBC driver will translate the result and return to java program. Part Java Part Native Driver and the vendor specific native language API must be installed on every client that runs the java program.

Type 3: The Network Protocol Driver


Java program

Data source

JDBC API

JDBC Driver

JDBC Driver Server

Native Driver

Type-3 drivers use an intermediate database server that has the ability to connect multiple java clients to multiple database servers. Client connects to database servers via an intermediate server component that acts as a gateway for multiple database servers. The java client application sends a jdbc call through a jdbc driver to the intermediate data access server, which completes the request to the datasource using another driver.

Type 4: Pure Java driver


Java program

Data source

JDBC API

Java program

JDBC driver type 4 converts JDBC calls into the vendor-specific database management system (DBMS) protocol so that client applications can communicate directly with the database server. Level 4 drivers are completely implemented in Java to achieve platform independence and eliminate deployment administration issues.

42

3.3 STEPS TO CONNECT WITH DATABASE


There are seven standard steps in querying databases: 1. Load the JDBC driver. 2. Establish the connection. 3. Create a statement object. 4. Execute a query or update. 5. Process the results. 6. Close the connection.

1. Load the JDBC driver


Loading the driver or drivers we want to use is very simple and involves just one line of code. If, for example, we want to use the JDBCODBC Bridge driver, the following code will load it: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

3. Establish the connection


The second step in establishing a connection is to have the appropriate driver connect to the DBMS. The following line of code illustrates the general idea: Connection con = DriverManager.getConnection(url, "myLogin", "myPassword"); This step is also simple, the hardest part being what to supply for url. If we are using the JDBCODBC Bridge driver, the JDBC URL will start with jdbc:odbc:. The rest of the URL is generally our data source name or database system. So, if we are using ODBC to access an ODBC data source called "Fred", for example, our JDBC URL could be jdbc:odbc:Fred. In place of "myLogin" we put the name we use to log in to the DBMS; in place of "myPassword" we put our password for the DBMS. So if we log in to our DBMS with a login name of "Fernanda" and a password of "J8", just these two lines of code will establish a connection:
String url = "jdbc:odbc:Fred"; Connection con = DriverManager.getConnection(url, "Fernanda", "J8");

3. Create a statement object


A Statement object is used to send queries and commands to the database and is created from the Connection as follows: Statement statement = con.createStatement();

43

4. Execute a query or update


Once we have a Statement object, we can use it to send SQL queries by using the executeQuery method, which returns an object of type Result-Set. Here is an example: String query = "SELECT col1, col2, col3 FROM sometable"; ResultSet resultSet = statement.executeQuery(query); To modify the database, use executeUpdate instead of executeQuery, and supply a string that uses UPDATE, INSERT, or DELETE. Other useful method in the Statement class include execute (execute an arbitrary command).

5. Process the results


The simplest way to handle the results is to process them one row at a time, using the ResultSets next method to move through the table a row at a time. Within a row, ResultSet provides various getXxx methods that take a column index or column name as an argument and return the result as a variety of different Java types. For instance, use getInt if the value should be an integer, getString for a String, and so on for most other data types. If we just want to display the results, we can use getString regardless of the actual column type. However, if we use the version that takes a column index, note that columns are indexed starting at 1 (following the SQL convention), not at 0 as with arrays, vectors, and most other data structures in the Java programming language. Here is an example that prints the values of the first three columns in all rows of a ResultSet. while(resultSet.next()) { System.out.println(results.getString(1) + " " + results.getString(2) + " " + results.getString(3)); }

6. Close the connection


To close the connection explicitly, we would do: con.close(); Complete program :-import java.sql.*; public class jdbc_type1 { public static void main(String a[]) throws Exception { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection con=DriverManager.getConnection("jdbc:odbc:TEST"); Statement st=con.createStatement(); ResultSet rs=st.executeQuery("select * from test"); while(rs.next()){ System.out.println(rs.getString(1));

44

} rs.close(); st.close(); con.close(); } }

3.4 RESULTSETMETADATA
JDBC enables us to process a result set even if the database table columns are not specified in the SQL query. Imagine that we need to write a program that will accept any SQL select statement and display the retrieved data. The java.sql.ResultSetMetaData class can dynamically find out the structure of the underlying database table how many columns it contains, and the types and names of the columns. Heres an example:
import java.sql.*; public class jdbc_type1_meta { public static void main(String a[]) throws Exception { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection con=DriverManager.getConnection("jdbc:odbc:TEST"); Statement st=con.createStatement(); ResultSet rs=st.executeQuery("select * from emp"); ResultSetMetaData rsm=rs.getMetaData(); int count=rsm.getColumnCount(); System.out.println(count); int i=1; while(i<=count){ System.out.println(rsm.getColumnName(i)+" : "+ rsm.getColumnTypeName(i)); i++; } rs.close(); st.close(); con.close(); } }

Output

45

3.5 SCROLLABLE RESULTSET


So far we ve been navigating JDBC result sets using the next() method, which enables us to move forward only. Another option is to create a Scrollable result set, so the cursor can navigate the result set both backward and forward. A two-argument version of the createStatement() method exists. The first argument specifies the type of scrolling (TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, TYEP_SCROLL_SENSITIVE), and the second enables us to make the result set either read-only or updateable (CONCUR_READ_ONLY or CONCUR_UPDATABLE, respectively), as in the following example:
import java.sql.*; public class jdbc_type1_scroll { public static void main(String a[]) throws Exception { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection con=DriverManager.getConnection("jdbc:odbc:TEST"); Statement st=con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet rs=st.executeQuery("select * from Emp"); rs.next(); System.out.println(rs.getString(3)); rs.last(); System.out.println(rs.getString(3)); rs.previous(); System.out.println(rs.getString(3)); rs.absolute(3); System.out.println(rs.getString(3)); rs.first(); rs.close(); st.close(); con.close(); } }

Table ename eage ecity esalary epin ---------- ----------- ---------- ----------------------------------------------------- ----------shimith 23 banglore 9000.0 3222 emp5 30 pune 2345.0 1221 ved 30 allahabad 2345.0 12345 bill 30 texsas 2345.0 4321 Output

46

3.6 PREPAREDSTATEMENT
This is a subclass of the statement class: It compiles the SQL statement before execution and can also take parameters. Lets say we need to execute the same query for example select * from student where id= - multiple times. The user IDs come from the userid[] array. If we use the Statement class, this SQL query will be compiled in each iteration of the loop, But in Prepared Statement the SQL statement is compiled only once and parameters are provided by the appropriate setXXX() method, depending on the data type of the underlying column. For example: Table ename city ---------- ---------Raj bangalo Output

Table, After Execution ename city ---------- ---------Raj bangalo raj chennai

3.7 CALLABLESTAEMENT
A CallableStatement object provides a way to call stored procedures in a standard way for all RDBMS. A stored procedure is stored in a database; the call to the stored procedure is what a CallableStatement object contains. This call is written in an escape syntax that may take one of two forms: one form with a result parameter and the other without one. A result parameter, a kind of OUT parameter, is the return value for the stored procedure. Both forms may have a variable number of parameters used for input (IN parameters), output (OUT parameters), or both (INOUT parameters). A question mark (?) serves as a placeholder for a parameter. The syntax for invoking a stored procedure using the JDBC API is shown here.

Calling a stored procedure with no parameters: {call procedure_name} Calling a stored procedure with one or more IN, OUT, or INOUT parameters: {call procedure_name(?, ?, ...)} 47

Calling a procedure that returns a result parameter and may or may not take any IN, OUT, or INOUT parameters: (Note that the square brackets indicate that what is between them is optional; they are not themselves part of the syntax.) {? = call procedure_name[(?, ?, ...)]}

IN Parameters
Passing in any IN parameter values to a CallableStatement object is done using setter methods. These methods include both the setter methods inherited from the PreparedStatement interface and those defined in the CallableStatement interface. The type of the value being passed in determines which setter method to use (setFloat to pass in a float value, setBoolean to pass in a boolean, and so on). The following code fragment uses the setter methods that take the parameter number to indicate which parameter is to be set. String sql = "{call updateStats(?, ?)}"; CallableStatement cstmt = con.prepareCall(sql); cstmt.setInt(1, 398); cstmt.setDoublel(2, 0.04395);

OUT Parameters
If the stored procedure returns OUT parameters, the data type of each OUT parameter must be registered before the CallableStatement object can be executed. This is necessary because some DBMSs require the SQL type (which the JDBC type represents); the JDBC API itself does not require that the SQL type be registered. JDBC types, a set of generic SQL type identifiers that represent the most commonly used SQL types. Registering the JDBC type is done with the method registerOutParameter. Then after the statement has been executed, the CallableStatement interface's getter methods can be used to retrieve OUT parameter values. The correct getter method to use is the type in the Java programming language that corresponds to the JDBC type registered for that parameter. CallableStatement cstmt = con.prepareCall( "{call getTestData(?, ?)}"); cstmt.registerOutParameter(1, java.sql.Types.TINYINT); cstmt.registerOutParameter(2, java.sql.Types.DECIMAL); ResultSet rs = cstmt.executeQuery();

INOUT Parameters
A parameter that supplies input as well as accepts output (an INOUT parameter) requires a call to the appropriate setter method in addition to a call to the method registerOutParameter. The setter method sets a parameter's value as an input parameter, and the method

48

registerOutParameter registers its JDBC type as an output parameter. The setter method provides a Java value that the driver converts to a JDBC value before sending it to the database. The JDBC type of this IN value and the JDBC type supplied to the method registerOutParameter should be the same. If they are not the same, they should at least be types that are compatible, that is, types that can be mapped to each other. Then, to retrieve the output value, a corresponding getter method is used.
CallableStatement cstmt = con.prepareCall( "{call reviseTotal(?)}"); cstmt.setByte(1, (byte)25); cstmt.registerOutParameter(1, java.sql.Types.TINYINT); cstmt.executeUpdate(); byte x = cstmt.getByte(1);

for example
import java.sql.*; public class calldemo { public static void main(String a[]) throws Exception { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection con=DriverManager.getConnection("jdbc:odbc:TEST"); CallableStatement ps=con.prepareCall("{ call pdemo(?,?)}"); ps.setInt(1,2); ps.registerOutParameter(2,java.sql.Types.VARCHAR); ps.executeUpdate(); String s=ps.getString(2); System.out.println(s); } } Stored procedure CREATE PROCEDURE pdemo (@empid int,@empname varchar(10) out) AS set @empname=(select ename from employee where eid=@empid) Table ename ---------emp1 emp2 emp3 output city ---------city1 city2 city3 eid ----------1 2 3

49

3.8 BATCH STATEMENT


A batch update is a set of multiple update statements that is submitted to the database for processing as a batch. Sending batch updates can, in some situations, be much more efficient than sending update statements separately. This ability to send updates as a unit, referred to as the batch update facility, is one of the features provided with the JDBC API. We can add SQL commands to this list with the method addBatch and empty it with the method clearBatch.When we have finished adding statements to the list, we call the method executeBatch to send them all to the database to be executed as a unit, or batch For example
import java.sql.*; public class batchdemo { public static void main(String args[])throws Exception { Class.forName("weblogic.jdbc.sqlserver.SQLServerDriver"); Connection con=DriverManager.getConnection ("jdbc:bea:sqlserver://localhost:1433","java","java"); Statement st=con.createStatement(); con.setAutoCommit(false); st.addBatch("insert into book values(04,'J2SE')"); st.addBatch("insert into book values(05,'J2EE')"); st.addBatch("insert into book values(06,'J2ME')"); st.executeBatch(); System.out.println("\nRecords Inserted"); con.commit(); con.setAutoCommit(true); st.close(); con.close(); } } Table bid ----------1 2 3 Output bname --------------Pascal Cobol Fortran

50

Table, After Execution bid ----------1 2 3 4 5 6 bname --------------Pascal Cobol Fortran J2SE J2EE J2ME

3.9 Connection pooling


DataSource are currently the preferred method for obtaining database connections. The data source interface provides a more flexible architecture than using DriverManager for creating & using Database connections. By using a datasource object to obtain a connection, we can access different databases without a single change in our client code. The data source hides the connection details as that we, as the Client programmer, never need to worry about the connection URL, host, port & soon. A connection pool provides a pool of precreated database connections. This avoids the time consuming activity of creating a new connection to a database. On the client side, there is little to do difference in how the connection is used. The difference lies in how connections are created, handed out and returned to the pool. Next listing uses a datasource and pool that is configured on weblogic server
import import import import java.sql.*; javax.sql.*; javax.naming.*; java.util.*;

public class PoolDemo{ public static void main(String a[]) throws Exception { Properties p=new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory" ); p.put(Context.PROVIDER_URL,"t3://localhost:7001"); Context ctx=new InitialContext(p); DataSource ds=(DataSource)ctx.lookup("jm_ds_jndi"); Connection con=ds.getConnection(); Statement st=con.createStatement(); ResultSet rs=st.executeQuery("select * from EMP"); while(rs.next()) { System.out.println("NAME "+rs.getString(1)+"ID "+rs.getInt(2)); } } }

51

CHAPTER-IV SERVLETS
4.1 Introduction to servlet and alternatives
The evolution of internet has led to the development of the java language. It serves as a complete client/server solution where programs are dynamically downloaded on to the client. Till date, the focus has been on the client-side development of applets and GUI components, which is incomplete as far as client/server computing is concerned. Therefore we will be introduced to the other side of the client/server computing- the Servlets. Java Servlets are more efficient, easier to use, more powerful, more portable, safer, and cheaper than traditional CGI and many alternative CGI-like technologies. They are programs that run on a server, acting as a middle layer between a request coming from a Web browser or other HTTP client and databases or applications on the HTTP server. Their job is to: 1. Read any data sent by the user. This data is usually entered in a form on a Web page, but could also come from a Java applet or a custom HTTP client program. 2. Look up any other information about the request that is embedded in the HTTP

request.
This information includes details about browser capabilities, cookies, the host name of the requesting client, and so forth.

3. Generate the results. This process may require talking to a database, executing an RMI or CORBA call, invoking a legacy application, or computing the response directly.

52

4. Format the results inside a document. In most cases, this involves embedding the information inside an HTML page. 5. Set the appropriate HTTP response parameters. This means telling the browser what type of document is being returned (e.g., HTML), setting cookies and caching parameters, and other such tasks. 6. Send the document back to the client. This document may be sent in text format (HTML), binary format (GIF images), or even in a compressed format like zip that is layered on top of some other underlying format. Many client requests can be satisfied by returning pre-built documents, and these requests would be handled by the server without invoking servlets. In many cases, however, a static result is not sufficient, and a page needs to be generated for each request. There are a number of reasons why Web pages need to be built on-the-fly like this: The Web page is based on data submitted by the user. For instance, the results page from search engines and order-confirmation pages at on-line stores are specific to particular user requests. The Web page is derived from data that changes frequently. For example, a weather report or news headlines page might build the page dynamically, perhaps returning a previously built page if it is still up to date. The Web page uses information from corporate databases or other server-side

sources.
For example, an e-commerce site could use a servlet to build a Web page that lists the current price and availability of each item that is for sale. In principle, servlets are not restricted to Web or application servers that handle HTTP requests, but can be used for other types of servers as well. For example, servlets could be embedded in mail or FTP servers to extend their functionality. In practice, however, this use o f servlets has not caught on, and Ill only be discussing HTTP servlets.

Advantages of Servlets Over CGI


Java servlets are more efficient, easier to use, more powerful, more portable, safer, and cheaper than traditional CGI and many alternative CGI-like technologies.

53

Efficient
With traditional CGI, a new process is started for each HTTP request. If the CGI program itself is relatively short, the overhead of starting the process can dominate the execution time. With servlets, the Java Virtual Machine stays running and handles each request using a lightweight Java thread, not a heavyweight operating system process. Similarly, in traditional CGI, if there are N simultaneous requests to the same CGI program, the code for the CGI program is loaded into memory N times. With servlets, however, there would be N threads but only a single copy of the servlet class. Finally, when a CGI program finishes handling a request, the program terminates. This makes it difficult to cache computations, keep database connections open, and perform other optimizations that rely on persistent data. Servlets, however, remain in memory even after they complete a response, so it is straightforward to store arbitrarily complex data between requests.

Convenient
Servlets have an extensive infrastructure for automatically parsing and decoding HTML form data, reading and setting HTTP headers, handling cookies, tracking sessions, and many other such high-level utilities. Besides, we already know the Java programming language. Why learn Perl too? Were already convinced that Java technology makes for more reliable and reusable code than does C++. Why go back to C++ for server-side programming?

Powerful
Servlets support several capabilities that are difficult or impossible to accomplish with regular CGI. Servlets can talk directly to the Web server, whereas regular CGI programs cannot, at least not without using a server-specific API. Communicating with the Web server makes it easier to translate relative URLs into concrete path names, for instance. Multiple servlets can also share data, making it easy to implement database connection pooling and similar resource-sharing optimizations. Servlets can also maintain information from request to request, simplifying techniques like session tracking and caching of previous computations.

Portable
Servlets are written in the Java programming language and follow a standard API. Consequently, servlets written for, say, I-Planet Enterprise Server can run virtually unchanged on Apache, Microsoft Internet Information Server (IIS), IBM WebSphere, or StarNine WebStar. For example, virtually all of the servlets and JSP pages in this book were executed on Suns Java Web Server, Apache Tomcat and Suns JavaServer Web Development Kit (JSWDK) with no changes whatsoever in the code. Many were tested on BEA WebLogic and IBM WebSphere as well. In fact, servlets are supported directly or by a plug-in on virtually every major Web server. They are now part of the Java 2 Platform, Enterprise Edition (J2EE; see http://java.sun.com/j2ee/), so industry support for servlets is becoming even more pervasive.

54

Secure
One of the main sources of vulnerabilities in traditional CGI programs stems from the fact that they are often executed by general-purpose operating system shells. So the CGI programmer has to be very careful to filter out characters such as backquotes and semicolons that are treated specially by the shell. This is harder than one might think, and weaknesses stemming from this problem are constantly being uncovered in widely used CGI libraries. A second source of problems is the fact that some CGI programs are processed by languages that do not automatically check array or string bounds. For example, in C and C++ it is perfectly legal to allocate a 100-element array then write into the 999th element, which is really some random part of program memory. So programmers who forget to do this check themselves open their system up to deliberate or accidental buffer overflow attacks. Servlets suffer from neither of these problems. Even if a servlet executes a remote system call to invoke a program on the local operating system, it does not use a shell to do so. And of course array bounds checking and other memory protection features are a central part of the Java programming language. Inexpensive There are a number of free or very inexpensive Web servers available that are good for personal use or low-volume Web sites. However, with the major exception of Apache, which is free, most commercial-quality Web servers are relatively expensive. Nevertheless, once we have a Web server, no matter its cost, adding servlet support to it (if it doesnt come preconfigured to support servlets) costs very little extra. This is in contrast to many of the other CGI alternatives, which require a significant initial investment to purchase a proprietary package.

4.2 DIRECTORY STRUCTURE AND WEB APPLICATION DEPLOYMENT DESCRIPTOR


The Directory Structure
All Web applications are packed into a common directory structure, and this directory structure is the container that holds the components of a Web application. The first step in creating a Web application is to create this structure. A sample Web application named webdemo, and list of contents of each of its directories are as follows: Directory /webdemo /webdemo /WEB-INF Contains This is the root directory of the Web application. All JSP and HTML files are stored here. This directory contains all resources related to the application that are not in the document root of the application. This is where our Web application deployment descriptor is located. We should note that the WEB-INF directory is not part of the public document. No files contained in this directory can be served directly to a client. 55

/webdemo/WEB-INF/classes This directory is where servlet and utility classes are located. /webdemo/WEB-INF/lib This directory contains Java Archive (JAR) files that the Web application is dependent on.

Note:- Web applications allow compiled classes to be stored in both the /WEB-INF/classes and /WEB-INF/lib directories. Of these two directories, the class loader will load classes from the /classes directory first, followed by the JARs in the /lib directory. If we have duplicate classes in both the /classes and /lib directories, the classes in the /classes directory will take precedence.

The Web Application Deployment Descriptor


The backbone of all Web applications is its deployment descriptor. The Web application deployment descriptor is an XML file named web.xml that is located in the /<SERVER_ROOT>/applicationname/WEB-INF/ directory. The web.xml file describes all of the components in the Web application. If we use the previous Web application name, wileyapp, then the web.xml file would be located in the /<SERVER_ROOT>/wileyapp /WEB-INF/ directory. The information that can be described in the deployment descriptor includes the following elements: ServletContext init parameters Localized content Session configuration Servlet/JSP definitions Servlet/JSP mappings Tag library references MIME type mappings Welcome file list Error pages Security information

Packaging a Web Application The standard packaging format for a Web application is a Web Archive file (WAR). A WAR file is simply a JAR file with the extension .war, as opposed to .jar. We can create a WAR file by using jar, Javas archiving tool. To create a WAR file, we simply need to change to the root directory of our Web application and type the following command: jar cvf wileyapp.war

56

This command will produce an archive file named wileyapp.war that contains the entire wileyapp Web application. Now we can deploy our Web application by simply distributing this file.

4.3 LIFE-CYCLE OF SERVLET AND SERVLET API STRUCTURE


The Life Cycle of a Servlet
The life cycle of a Java servlet follows a very logical sequence. The interface that declares the life-cycle methods is the javax.servlet.Servlet interface. These methods are the init(), the service(), and the destroy() methods. This sequence can be described in a simple three-step process: 1. A servlet is loaded and initialized using the init() method. This method will be called when a servlet is preloaded or upon the first request to this servlet. 2. The servlet then services zero or more requests. The servlet services each request using the service() method. 3. The servlet is then destroyed and garbage collected when the Web application containing the servlet shuts down. The method that is called upon shutdown is the destroy() method.

init() Method
The init() method is where the servlet begins its life. This method is called immediately after the servlet is instantiated. It is called only once. The init() method should be used to create and initialize the resources that it will be using while handling requests. The init() methods signature is defined as follows: public void init(ServletConfig config) throws ServletException; The init() method takes a ServletConfig object as a parameter. This reference should be stored in a member variable so that it can be used later. A common way of doing this is to have the init() method call super.init() and pass it the ServletConfig object. The init() method also declares that it can throw a ServletException. If for some reason the servlet cannot initialize the resources necessary to handle requests, it should throw a ServletException with an error message signifying the problem.

service() Method
The service() method services all requests received from a client using a simple request/response pattern. The service() methods signature is shown here: public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; 57

The service() method takes two parameters: A ServletRequest object, which contains information about the service request and encapsulates information provided by the client. A ServletResponse object, which contains the information returned to the client. We will not usually implement this method directly, unless we extend the GenericServlet abstract class. The most common implementation of the service() method is in the HttpServlet class. The HttpServlet class implements the Servlet interface by extending GenericServlet. Its service() method supports standard HTTP/1.1 requests by determining the request type and calling the appropriate method.

destroy() Method
This method signifies the end of a servlets life. When a Web application is shut down, the servlets destroy() method is called. This is where all resources that were created in the init() method should be cleaned up. The following code snippet contains the signature of the destroy() method: public void destroy(); A Simple Servlet Generating Plain Text:LifeCycleDemo.java import java.io.*; import javax.servlet.*; public class LifeCycleDemo extends GenericServlet{ String name=null; public void init() { name=" Hello World"; } public void service(ServletRequest req,ServletResponse res) throws ServletException,IOException{ res.setContentType("text/html"); PrintWriter out=res.getWriter(); out.println(name); } public void destroy() { name=null; } } Output:Hello World

58

The Servlet API structure


The Servlet API is specified in two Java extension packages: javax.servlet and javax.servlet.http. The classes and interfaces in the javax.servlet package are protocol-independent, while the second package, javax.servlet.http, contains classes and interfaces that are specific to HTTP.

Interfaces of package javax.servlet :-RequestDispatcherServletServletConfigServletContextDefines an object that receives requests from the client and sends them to any resource (such as a servlet, HTML file, or JSP file) on the server. Defines methods that all servlets must implement. A servlet configuration object used by a servlet container used to pass information to a servlet during initialization. Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file. Defines an object to provide client request information to a servlet. Defines an object to assist a servlet in sending a response to the client.

ServletRequestServletResponse-

Classes of package javax.servlet :-GenericServletDefines a generic, protocol-independent servlet.

ServletInputStream- Provides an input stream for reading binary data from a client request, including an efficient readLine method for reading data one line at a time. ServletOutputStream- Provides an output stream for sending binary data to the client.

Interfaces of package javax.servlet.http:-HttpServletRequestExtends the ServletRequest interface to provide request information for HTTP servlets.

HttpServletResponse- Extends the ServletResponse interface to provide HTTP-specific functionality in sending a response. HttpSessionProvides a way to identify a user across more than one page request or visit to a Web site and to store information about that user.

59

Classes of package javax.servlet.http :-CookieHttpServletCreates a cookie, a small amount of information sent by a servlet to a Web browser, saved by the browser, and later sent back to the server. Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site.

A Simple HttpServlet Generating Html Page:import import import public java.io.*; javax.servlet.*; javax.servlet.http.*; class htmldemo extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException,IOException{ res.setContentType ("text/html"); PrintWriter out=res.getWriter (); out.println ("<html><body><center>"); out.println ("<table border=\"1\">"); out.println("<tr><td>Name</td><td>city</td></tr>"); out.println("<tr><td>X</td><td>bangalore</td></tr>"); out.println("<tr><td>y</td><td>pune</td></tr>"); out.println("</table></center</body></html>"); }

} Output:-

4.4 Request and Response


Request One of the main motivations for building Web pages dynamically is so that the result can be based upon user input. javax.servlet.ServletRequest and javax.servlet.http.HttpServletRequest interface provides different methods to access user input. Reading Form Data from Servlets:One of the nice features of servlets is that all of this form parsing is handled automatically. We simply call the getParameter method of the HttpServletRequest, supplying the case-sensitive parameter name as an argument. We use getParameter exactly the same way when the data is sent by GET as we do when it is sent by POST. The servlet knows which request method was used and automatically does the right thing behind the scenes. The return value is a String 60

corresponding to the URL-decoded value of the first occurrence of that parameter name. An empty String is returned if the parameter exists but has no value, and null is returned if there was no such parameter. If the parameter could potentially have more than one value, we should call getParameterValues (which returns an array of strings) instead of getParameter (which returns a single string). The return value of getParameterValues is null for nonexistent parameter names and is a one-element array when the parameter has only a single value. Parameter names are case sensitive so, for example, request.getParameter("Param1") and request.getParameter("param1") are not interchangeable. Finally, although most real servlets look for a specific set of parameter names, for debugging purposes it is sometimes useful to get a full list. Use getParameterNames to get this list in the form of an Enumeration, each entry of which can be cast to a String and used in a getParameter or get ParameterValues call. Just note that the HttpServletRequest API does not specify the order in which the names appear within that Enumeration. A simple servlet called ThreeParams that reads form data parameters named param1, param2, and param3 and print their values:ThreeParamsForm.html
<HTML> <HEAD> <TITLE>Collecting Three Parameters</TITLE> </HEAD> <BODY > <H1 ALIGN="CENTER">Collecting Three Parameters</H1> <FORM ACTION="ThreeParams"> First Parameter: <INPUT TYPE="TEXT" NAME="param1"><BR> Second Parameter: <INPUT TYPE="TEXT" NAME="param2"><BR> Third Parameter: <INPUT TYPE="TEXT" NAME="param3"><BR> <CENTER> <INPUT TYPE="SUBMIT"> </CENTER> </FORM> </BODY> </HTML> Output:-

61

ThreeParams.java import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ThreeParams extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Reading Three Request Parameters"; out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<UL>\n" + " <LI><B>param1</B>: " + request.getParameter("param1") + "\n" + " <LI><B>param2</B>: " + request.getParameter("param2") + "\n" + " <LI><B>param3</B>: " + request.getParameter("param3") + "\n" + "</UL>\n" + "</BODY></HTML>"); } } Output:-

One of the keys to creating effective servlets is understanding how to manipulate the HyperText Transfer Protocol (HTTP). We need to discuss HTTP information that is sent from the browser to the server in the form of request headers. Note that HTTP request headers are distinct from the form data discussed in the previous chapter. Form data results directly from user input and is sent as part of the URL for GET requests and on a separate line for POST requests. Request headers, on the other hand, are indirectly set by the browser.

62

Reading Request Headers from Servlets:Reading headers is straightforward; just call the getHeader method of HttpServletRequest, which returns a String if the specified header was supplied on this request, null otherwise. Header names are not case sensitive. So, for example, request.getHeader("Connection") and request.getHeader("connection") are interchangeable. There are a couple of headers that are so commonly used that they have special access methods in HttpServletRequest. getCookies The getCookies method returns the contents of the Cookien header, parsed and stored in an array of Cookie objects. getContentLength The getContentLength method returns the value of the Content-Length header (as an int). getContentType The getContentType method returns the value of the Content-Type header (as a String). getHeaderNames Rather than looking up one particular header, we can use the getHeaderNames method to get an Enumeration of all header names received on this particular request. getMethod The getMethod method returns the main request method (normally GET or POST, but things like HEAD, PUT, and DELETE are possible). getRequestURI The getRequestURI method returns the part of the URL that comes after the host and port but before the form data. For example, for a URL of http://randomhost.com/servlet/search.BookSearch, getRequestURI would return /servlet/search.BookSearch. Next example shows a servlet that simply creates a table of all the headers it receives, along with their associated values.
ShowRequestHeaders.java import import import import java.io.*; javax.servlet.*; javax.servlet.http.*; java.util.*;

63

/** Shows all the request headers sent on this * particular request. */ public class ShowRequestHeaders extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Servlet Example: Showing Request Headers"; out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<B>Request Method: </B>" + request.getMethod() + "<BR>\n" + "<B>Request URI: </B>" + request.getRequestURI() + "<BR>\n" + "<B>Request Protocol: </B>" + request.getProtocol() + "<BR><BR>\n" + "<TABLE BORDER=1 ALIGN=CENTER>\n" + "<TR BGCOLOR=\"#FFAD00\">\n" + "<TH>Header Name<TH>Header Value"); Enumeration headerNames = request.getHeaderNames(); while(headerNames.hasMoreElements()) { String headerName = (String)headerNames.nextElement(); out.println("<TR><TD>" + headerName); out.println(" <TD>" + request.getHeader(headerName)); } out.println("</TABLE>\n</BODY></HTML>"); } /** Let the same servlet handle both GET and POST. */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } Output:-

64

Response Response is an object to assist a servlet in sending a response to the client. javax.servlet.ServletRequest and javax.servlet.http.HttpServletRequest provides different methods to add data in response object. Common method of javax.servlet.ServletRequest are:void flushBuffer()

Forces any content in the buffer to be written to the client.


int

getBufferSize() Returns the actual buffer size used for the response.

String getContentType() Returns the content type used for the MIME body sent in this response. ServletOutputStream getOutputStream() Returns a ServletOutputStream suitable for writing binary data in the response. PrintWriter getWriter() Returns a PrintWriter object that can send character text to the client.

65

void reset() Clears any data that exists in the buffer as well as the status code and headers. void setBufferSize(int size) Sets the preferred buffer size for the body of the response. void setContentLength(int len) Sets the length of the content body in the response In HTTP servlets, this method sets the HTTP Content-Length header. void setContentType(String type) Sets the content type of the response being sent to the client, if the response has not been committed yet. Next example send response in the form of Microsoft Excel file format. For this content type should be application/vnd.ms-excel. ContentTypeDemo.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ContentTypeDemo extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException { res.setContentType("application/vnd.ms-excel"); PrintWriter out=res.getWriter(); Enumeration e=req.getHeaderNames(); out.println("\tName\tCity\tAdd"); out.println("\tsandeep1\tbang1\tbang1"); out.println("\tsandeep2\tbang2\tbang2"); } } Output:

66

Common method of javax.servlet.http.HttpServletRequest are:void addCookie(Cookie cookie) Adds the specified cookie to the response. void addHeader(String name, String value) Adds a response header with the given name and value. String encodeURL(String url) Encodes the specified URL by including the session ID in it, or, if encoding is not needed, returns the URL unchanged. void sendError(int sc) Sends an error response to the client using the specified status code and clearing the buffer. void sendRedirect(String location) Sends a temporary redirect response to the client using the specified redirect location URL. void setHeader(String name, String value) Sets a response header with the given name and value. In next example sendError() is used to send 500(Internal Server Error) using program code-import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class errordemo extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response)

67

throws ServletException,IOException { response.setContentType("text/html"); PrintWriter out=response.getWriter(); response.sendError(500); }

Output:

4.5 SERVLETCONFIG, SERVLETCONTEXT, URL REDIRECTION


THE SERVLETCONTEXT
A ServletContext is an object that is defined in the javax.servlet package. It defines a set of methods that are used by server-side components of a Web application to communicate with the servlet container. The ServletContext is most frequently used as a storage area for objects that need to be available to all of the server-side components in a Web application. We can think of the ServletContext as a shared memory segment for Web applications. When an object is placed in the ServletContext, it exists for the life of a Web application, unless it is explicitly removed or replaced. Four methods defined by the ServletContext are leveraged to provide this shared memory functionality. These methods are

68

setAttribute() -Binds an object to a given name, and stores the object in the current ServletContext. If the name specified is already in use, this method will remove the old object binding and bind the name to the new object. getAttribute()- Returns the object referenced by the given name, or returns null if there is no attribute bind to the given key. removeAttribute()- Removes the attribute with the given name from the ServletContext. getAttributeNames()-Returns an enumeration of strings containing the object names stored in the current ServletContext. In next example ContextDemo1 servlet set a message in ServletContext object
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ContextDemo1 extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out=res.getWriter(); ServletContext context=getServletContext(); context.setAttribute("msg","Hello, This is first servlet!"); out.println("Message has sent"); } }

Output:

In next example ContextDemo2 servlet read a message from ServletContext object


import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ContextDemo2 extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html");

69

PrintWriter out=res.getWriter(); ServletContext context=getServletContext(); String msg=(String)context.getAttribute("msg"); out.println(msg); } }

Output:

The ServletConfig
A servlet configuration object used by a servlet container used to pass information to a servlet during initialization. The configuration information contains initialization parameters, a name of the servlet. The initialization parameters and the name of a servlet can be specified in the deployment descriptor. For example
<web-app> <servlet> <servlet-name>configdemo</servlet-name> <servlet-class>configdemo</servlet-class> <init-param> <param-name>email</param-name> <param-value>admin@admin.com</param-value> </init-param> </servlet> </web-app>

Methods of ServletConfig are:String getInitParameter(String name) Returns a String containing the value of the named initialization parameter, or null if the parameter does not exist. Enumeration getInitParameterNames() Returns the names of the servlet's initialization parameters as an Enumeration of String objects, or an empty Enumeration if the servlet has no initialization parameters. ServletContext getServletContext() Returns a reference to the ServletContext in which the caller is executing. 70

String getServletName() Returns the name of this servlet instance. In next example ServletConfig object retrives data from web.xml file ConfigDemo.java
import java.io.*; import javax.servlet.*; public class ConfigDemo extends GenericServlet { public void service(ServletRequest req,ServletResponse res) throws IOException,ServletException { res.setContentType("text/html"); PrintWriter out=res.getWriter(); ServletConfig sc=getServletConfig(); String s=sc.getInitParameter("email"); out.println(s); } }

Output: admin@admin.com

SERVLET COLLABORATION
There are two ways to forward control from one page to another.

1.Using RequestDispatcher
Defines an object that receives requests from the client and sends them to any resource (such as a servlet, HTML file, or JSP file) on the server. The servlet container creates the RequestDispatcher object, which is used as a wrapper around a server resource located at a particular path or given by a particular name. Method Summary:

void forward(ServletRequest request, ServletResponse response)


Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server.

void include(ServletRequest request, ServletResponse response)


Includes the content of a resource (servlet, JSP page, HTML file) in the response. In next example Dispacher1 servlet forward request to Dispacher2 servlet--

71

Dispacher1.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Dispacher1 extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out=res.getWriter(); RequestDispatcher rd=req.getRequestDispatcher("Dispacher2"); rd.include(req,res); }

Dispacher2.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Dispacher2 extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out=res.getWriter(); out.println(I am output of Dispatcher2.java); } } Output: I am output of Dispatcher2.java 2.Using sendRedirect() import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class RedirectDemo1 extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException { res.sendRedirect("http://localhost:7001/servletdemo/ RedirectDemo2"); } }

72

4.6 SESSION TRACKING


HTTP is a stateless protocol: each time a client retrieves a Web page, it opens a separate connection to the Web server, and the server does not automatically maintain contextual information about a client. Even with servers that support persistent (keep-alive) HTTP connections and keep a socket open for multiple client requests that occur close together in time there is no built-in support for maintaining contextual information. This lack of context causes a number of difficulties. For example, when clients at an on-line store add an item to their shopping carts, how does the server know whats already in them? Similarly, when clients decide to proceed to checkout, how can the server determine which previously created shopping carts are theirs? There are three typical solutions to this problem: cookies, URL-rewriting, and hidden form fields.

Cookies
Cookies are small bits of textual information that a server sends to a browser and that the browser returns unchanged when later visiting the same Web site or domain. By letting the server read information it sent the client previously, the site can provide visitors with a number of conveniences such as presenting the site the way the visitor previously customized it or letting identifiable visitors in without their having to enter a password. To
javax.servlet.http.Cookie class

handle

cookies

servlet

api

provides

Cookie

class.

Method

summary

of

Cookie(String name, String value) Constructs a cookie with a specified name and value. String getName() Returns the name of the cookie. String getValue() Returns the value of the cookie. void setMaxAge(int expiry) Sets the maximum age of the cookie in seconds. To send cookies to the client, a servlet should create one or more cookies with designated names and values with new Cookie(name, value), set any optional attributes with cookie.setXxx (readable later by cookie.getXxx), and insert the cookies into the response headers with response.addCookie(cookie). To read incoming cookies, a servlet should call request.getCookies, which returns an array of Cookie objects corresponding to the cookies the browser has associated with our site (this is null if there are no cookies in the request). In most cases, the servlet loops down this array until it finds the one whose name (getName) matches the name it had in mind, then calls getValue on that Cookie to see the value associated with that name. 73

A simple example using cookies to identify new client and old client
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class CookieDemo extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException { response.setContentType("text/html"); PrintWriter out=response.getWriter(); Cookie c[]=request.getCookies(); if(c==null) { out.println("New Client"); Cookie c1=new Cookie("key1","value1"); c1.setMaxAge(60); response.addCookie(c1); } else { out.println("Old Client"); Cookie d=c[0]; out.println(d.getName()); out.println(d.getValue()); } }

Output: 1st request -2nd request -New Client Old Client key1 value1

URL-Rewriting
With this approach, the client appends some extra data on the end of each URL that identifies the session, and the server associates that identifier with data it has stored about that session. For example, with http://host/path/file.html;jsessionid=1234, the session information is attached as jsessionid=1234. This is also an excellent solution, and even has the advantage that it works when browsers dont support cookies or when the user has disabled them. However, it has most of the same problems as cookies, namely, that the server-side program has a lot of straightforward but tedious processing to do. In addition, we have to be very careful that every URL that references our site and is returned to the user (even by indirect means like Location fields in server redirects) has the extra information appended. And, if the user leaves the session and comes back via a bookmark or link, the session information can be lost.

Hidden Form Fields


HTML forms can have an entry that looks like the following: <INPUT TYPE="HIDDEN" NAME="session" VALUE="..."> This entry means that, when the form is submitted, the specified name and value are included in the GET or POST data. This hidden field can be used to

74

store information about the session but it has the major disadvantage that it only works if every page is dynamically generated.

Session Tracking in Servlets


Servlets provide an outstanding technical solution: the HttpSession API. This high-level interface is built on top of cookies or URL-rewriting. In fact, most servers use cookies if the browser supports them, but automatically revert to URL-rewriting when cookies are unsupported or explicitly disabled.

HttpSession Methods
Object getValue(String name) Object getAttribute(String name) Extracts a previously stored value from a session object. Returns null if no value is associated with given name. void putValue(String name, Object value) void setAttribute(String name, Object value) Associates a value with a name. If value implements HttpSessionBindingListener, its valueBound method is called. If previous value implements HttpSessionBindingListener, its valueUnbound method is called. void removeValue(String name) void removeAttribute(String name) Removes any values associated with designated name. If value beingremoved implements HttpSessionBindingListener, its valueUnbound method is called. String[] getValueNames() Enumeration getAttributeNames() Returns the names of all attributes in the session. String getId() Returns the unique identifier generated for each session. boolean isNew() Returns true if the client (browser) has never seen the session; false otherwise. getCreationTime() Returns time at which session was first created (in milliseconds since 1970). To get a value useful for printing, pass value to Date constructor or the setTimeInMillis method of GregorianCalendar. long getLastAccessedTime() Returns time at which the session was last sent from the client. int getMaxInactiveInterval() 75

void setMaxInactiveInterval(int seconds) Gets or sets the amount of time, in seconds, that a session should go without access before being automatically invalidated. A negative value indicates that session should never time out. Not the same as cookie expiration date. public void invalidate() Invalidates the session and unbinds all objects associated with it. A simple servlet that shows basic information about the clients session. When the client connects, the servlet uses request.getSession( true) to either retrieve the existing session or, if there was no session, to create a new one. The servlet then looks for an attribute of type Integer called accessCount. If it cannot find such an attribute, it uses 0 as the number of previous accesses. This value is then incremented and associated with the session by putValue. Finally, the servlet prints a small HTML table showing information about the session. Figures show the servlet on the initial visit and after the page was reloaded several times.
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.net.*; import java.util.*; /** Simple example of session tracking. See the shopping * cart example for a more detailed one. */ public class ShowSession extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Session Tracking Example"; HttpSession session = request.getSession(true); String heading; // Use getAttribute instead of getValue in version 2.2. Integer accessCount = (Integer)session.getValue("accessCount"); if (accessCount == null) { accessCount = new Integer(0); heading = "Welcome, Newcomer"; } else { heading = "Welcome Back"; accessCount = new Integer(accessCount.intValue() + 1); } // Use setAttribute instead of putValue in version 2.2. session.putValue("accessCount", accessCount); out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=\"CENTER\">" + heading + "</H1>\n" + "<H2>Information on our Session:</H2>\n" + "<TABLE BORDER=1 ALIGN=\"CENTER\">\n" + "<TR BGCOLOR=\"#FFAD00\">\n" + " <TH>Info Type<TH>Value\n" +

76

"<TR>\n" + " <TD>ID\n" + " <TD>" + session.getId() + "\n" + "<TR>\n" + " <TD>Creation Time\n" + " <TD>" + new Date(session.getCreationTime()) + "\n" + "<TR>\n" + " <TD>Time of Last Access\n" + " <TD>" + new Date(session.getLastAccessedTime()) + "\n" + "<TR>\n" + " <TD>Number of Previous Accesses\n" + " <TD>" + accessCount + "\n" + "</TABLE>\n" + "</BODY></HTML>"); } /** Handle GET and POST requests identically. */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

Output:

77

4.7 Applet-Servlet communication


Through Http-Tunneling applets and servlets can communicate. Tunneling is process through which a sub-protocol of HTTP is created, which performs some specific tasks, the sub-protocol that is created for applet servlet communication contains all the information necessary to create an object on the web server. Invoke methods on that object and return the result back to the client. One advantage of using HTTP tunneling is that we do not need to be concerned about transporting the data packets between the client and the server and concentrate more on the specifics of the sub-protocol. This program open an HTTP connection.
import import import import import java.awt.*; java.applet.*; java.awt.event.*; java.net.*; java.io.*;

public class myapplet extends Applet implements ActionListener { TextField tf,tf1; Button b; URL url; URLConnection uc; public void init() { tf= new TextField(20); b= new Button("Send"); add(tf); add(b); add(tf1);b.addActionListener(this); } public void actionPerformed(ActionEvent ae) { try {

78

url=new URL("http://localhost:8080/mycontext2/myservlet1"); uc=url.openConnection(); uc=setDOOutput(true); uc=setDOInput(true); DataOutputStream (uc.getOutputStream()); dout.writeUTF(tf.getText()); dout.flush(); DataInputStream din= new DataInputStream(uc.getInputStream()); String data=din.readUTF(); tf1.setText(data); } catch (Exception e) { System.out.println("error"+e); } } }

Writing servlets program


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

public class myservlet extends HttpServlet { public void service (HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException { try { ServletInputStream sin = req.getInputStream(; DataInputStream din = new DataInputStream(sin); ServletOutputStream sout= res.getOutputStream(); DataOutputStream dout = new DataOutputtStream(sout); dout.writeUTF("Message from servlet - "+data); dout.flush(); } catch (Exception e) { System.out.println("error"+e); } } } HTML file <HTML><BODY> <applet code="myapplet" height="500" width="300"></applet> </BODY></HTML>

79

CHAPTER V JAVA SERVER PAGES [ JSP ]


5.1 INTRODUCTION
JavaServer Pages, or JSPs, are a simple but powerful technology used most often to generate dynamic HTML on the server side. It is used to simplify the creation and management of the dynamic web pages by providing a more convenient authoring framework than servlet. JSPs are a direct extension of Java servlets designed to let the developer embed Java logic directly into a requested document. JSP pages combines static markup like HTML and XML, with special scripting tags. JSP pages resembles markup documents, but each JSP page is translated into a servlet the first time it is invoked. A JSP document must end with the extension .jsp. JSP pages designed and developed less like programs and more like web pages. JSP pages are ideal when we need to display markup with embedded dynamic content. However, although generating HTML is much easier than with a servlet, JSP pages are less suited to handling processing logic. JSP pages can use JavaBeans to achieve a clean seperation of static content and the java code that produce dynamic web applications. This allows JSP pages to be created and maintained by designers with presentation skills, they do not need to know java. While there is an overlap between their capabilities, think of servlets as controller objects, and JSP pages as view objects. Dont think that we need to make a choice between using servlets and JSP pages in a web application; they are complementary technologies, and a complex web application will use both. A simple JSP page that display current date in an HTML page would like this:
<%@ page import=java.util.Date %> <html> <body> The current time is <%= (new Date()).toString() %> </body> </html>

Save this file as DateDemo.jsp in root directory like Webdemo and make request like http://localhost:7001/Webdemo/DateDemo.jsp The first time a JSP is loaded by the JSP container, the servlet code necessary to implement the JSP tags is automatically generated, compiled, and loaded into the servlet container. This occurs at translation time. It is important to note that this occurs only the first time a JSP page is requested. There will be a slow response the first time a JSP page is accessed, but on subsequent requests the previously compiled servlet simply processes the requests. This occurs at run time. If we modify the source code for the JSP, it is automatically recompiled and reloaded the next time that page s requested.

80

This figure summaries the process from request to response: Request received

Jsp_servlet exist? Ye s Jsp_servlet loaded No Yes Load into memory

No

Parse jsp page

Translate into servlet

Complie servlet

Generate response

Send response

There are three categories of JSP tags:-1. Directives : These affects the overall structure of the servlet that results from translation, but produce no output themselves. JSP scripting elements let we insert code into the servlet that will be generated from the JSP page.

2. Scripting Elements: 3. Standard Actions :

These are special tags available to affect the runtime behavior of the JSP page. JSP standard actions are predefined custom tags that can be used to encapsulate common actions easily. There are two types of JSP standard actions: the first type is related to JavaBean functionality, and the second type consists of all other standard actions. 81

5.2 DIRECTIVES
JSP directives are JSP elements that provide global information about a JSP page. An example would be a directive that included a list of Java classes to be imported into a JSP. Three possible directives are currently defined by the JSP specification page, include, and taglib.

The page Directive


The page directive defines information that will globally affect the JSP containing the directive. The syntax of a JSP page directive is <%@ page attribute="value" %> Note Because all mandatory attributes are defaulted, we are not required to specify any page directives. Attributes for the page Directive are language=scriptingLanguage Tells the server which language will be used to compile the JSP file. Java is currently the only available JSP language, but we hope there will be other language support in the not-toodistant future. extends=className Defines the parent class from which the JSP will extend. While we can extend JSP from other servlets, doing so will limit the optimizations performed by the JSP/servlet engine and is therefore not recommended. import=importList Defines the list of Java packages that will be imported into this JSP. It will be a commaseparated list of package names and fully qualified Java classes. session=true|false Determines whether the session data will be available to this page. The default is true. If our JSP is not planning on using the session, then this attribute should be set to false for better performance. buffer=none|size in kb Determines whether the output stream is buffered.The default value is 8KB.

82

autoFlush=true|false Determines whether the output buffer will be flushed automatically, or whether it will throw an exception when the buffer is full. The default is true. isThreadSafe=true|false Tells the JSP engine that this page can service multiple requests at one time. By default, this value is true. If this attribute is set to false, the SingleThreadModel is used. info=text Represents information about the JSP page that can be accessed by invoking the pages Servlet.getServletInfo() method. errorPage=error_url Represents the relative URL to a JSP that will handle JSP exceptions. isErrorPage=true|false States whether the JSP is an errorPage. The default is false. contentType=ctinfo Represents the MIME type and character set of the response sent to the client. Example Next listing presents a page that uses a class not in the standard JSP import list: java.util.Date
<%@ page import=java.util.Date %> <html> <body> The current time is <%= (new Date()).toString() %> </body> </html>

Output: Current date Next listing presents a page that uses contentType attribute to generating excel spreadsheets. <%@ page contentType="application/vnd.ms-excel" %> <%-- Note that there are tabs, not spaces, between columns. --%> 1997 1998 1999 2000 2001 12.3 13.4 14.5 15.6 16.7 83

Output:

Use of error Page and isErrorPage attribute:Error1.jsp : generate an arithmetic exception


<%@ page language="java" <html> <body> <center> <% out.println(0/0); %> </center> </body> </html> Error2.jsp <%@ page language="java" isErrorPage="true" %> <html> <body> <center>This is a error page<hr><br><br> <%=exception%> </center> </body> </html> Output: ErrorPage="Error2.jsp" %>

84

The include Directive


The include directive is used to insert text and/or code at JSP translation time. The syntax of the include directive is shown in the following code snippet: <%@ include file="relativeURLspec" %> The file attribute can reference a normal text HTML file or a JSP file, which will be evaluated at translation time. This resource referenced by the file attribute must be local to the Web application that contains the include directive. Heres a sample include directive: <%@ include file="header.jsp" %> Note: Because the include directive is evaluated at translation time, this included text will be evaluated only once. Thus, if the included resource changes, these changes will not be reflected until the JSP/servlet container is restarted or the modification date of the JSP that includes that file is changed.

The taglib Directive


The taglib directive states that the including page uses a custom tag library, uniquely identified by a URI and associated with a prefix that will distinguish each set of custom tags to be used in the page. JSP introduced an extremely valuable new capability, the ability to define our own JSP tags. We define how the tag, its attributes, and its body are interpreted. In order to use custom JSP tags, we need to define three separate components: the tag handler class that defines the tags behavior, the tag library descriptor file that maps the XML element names to the tag implementations, and the JSP file that uses the tag library.

The Tag Handler Class


When defining a new tag, our first task is to define a Java class that tells the system what to do when it sees the tag. This class must implement the javax.servlet.jsp.tagext.Tag interface. This is usually accomplished by extending the TagSupport or BodyTagSupport class. Next listing is an 85

example of a simple tag that just convert a numeric value in String. Save CustomTag.java in WEB-INF/classes/beanpack.
package beanpack; import java.io.IOException; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; public class CustomTag extends TagSupport { private String number; public void setNumber(String number) { this.number=number; } public int doStartTag() throws JspTagException { String temp=null; if(number.equals("10")) { try{ pageContext.getOut().write("TEN"); }catch(IOException e) { throw new JspTagException("tag could out"); } } return EVAL_BODY_INCLUDE; } }

not

write

to

jsp

The Tag Library Descriptor File


Once we have defined a tag handler, our next task is to identify the class to the server and to associate it with a particular XML tag name. This task is accomplished by means of a tag library descriptor file. This file contains some fixed information, an arbitrary short name for our library, a short description, and a series of tag descriptions. Save this next file as CustomTag.tld in WEB-INF.
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>joshna</short-name> <description>Simple Tag example</description> <tag> <name>convert</name> <tag-class>beanpack.CustomTag</tag-class> <body-content>JSP</body-content> <description>Simple</description> <attribute> <name>number</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> Tag Library

86

</taglib>

The JSP File


Once we have a tag handler implementation and a tag library description, we are ready to write a JSP file that makes use of the tag. Next listing gives an example. Somewhere before the first use of our tag, we need to use the taglib directive. This directive has the following form: <%@ taglib uri="..." prefix="..." %> The required uri attribute can be either an absolute or relative URL referring to a tag library descriptor file. We use web.xml file that maps an absolute URL for a tag library descriptor to a file on the local system.
<taglib> <taglib-uri>MANU</taglib-uri> <taglib-location>/WEB-INF/CustomTag.tld</taglib-location> </taglib>

The prefix attribute, also required, specifies a prefix that will be used in front of whatever tag name the tag library descriptor defined. For example, if the TLD file defines a tag named tag1 and the prefix attribute has a value of test, the actual tag name would be test:tag1. CustomDemo.jsp
<%@ taglib uri="MANU" prefix="josna" %> <josna:convert1 number="10" > </josna:convert1>

Output: TEN

5.3 SCRIPTING ELEMENTS


Scripting is a JSP mechanism for directly embedding Java code fragments into an HTML page. Three scripting language components are involved in JSP scripting. Each component has its appropriate location in the generated servlet.

Declarations
JSP declarations are used to define Java variables and methods in a JSP. A JSP declaration must be a complete declarative statement. JSP declarations are initialized when the JSP page is first loaded. After the declarations have been initialized, they are available to other declarations, expressions, and scriptlets within the same JSP. The syntax for a JSP declaration is as follows: <%! declaration %> A sample variable declaration using this syntax is shown here: 87

<%! String name = new String("BOB"); %> A sample method declaration using the same syntax is as follows: <%! public String getName() { return name; } %> To get a better understanding of declarations, lets take the previous string declaration and embed it into a JSP document. The sample document would look similar to the following code snippet:
<HTML> <BODY> <%! String name = new String("BOB"); %> </BODY> </HTML>

When this document is initially loaded, the JSP code is converted to servlet code and the name declaration is placed in the declaration section of the generated servlet. It is now available to all other JSP components in the JSP. Note It should be noted that all JSP declarations are defined at the class level, in the servlet generated from the JSP, and will therefore be evaluated prior to all JSP expressions and scriptlet code.

Expressions
JSP expressions are JSP components whose text, upon evaluation by the container, is replaced with the resulting value of the container evaluation. JSP expressions are evaluated at request time, and the result is inserted at the expressions referenced position in the JSP file. If the resulting expression cannot be converted to a string, then a translation-time error will occur. If the onversion to a string cannot be detected during translation, a ClassCastException will be thrown at request time. The syntax of a JSP expression is as follows: <%= expression %> A code snippet containing a JSP expression is shown here: Hello <B><%= getName() %></B> Here is a sample JSP document containing a JSP expression:
<HTML> <BODY> <%! public String getName() { return "Bob"; } %> Hello <B><%= getName() %></B> </BODY> </HTML>

88

Scriptlets
Scriptlets are the JSP components that bring all the JSP elements together. They can contain almost any coding statements that are valid for the language referenced in the language directive. They are executed at request time, and they can make use of all the JSP components. The syntax for a scriptlet is as follows: <% scriptlet source %> When JSP scriptlet code is converted into servlet code, it is placed into the generated servlets service() method. The following code snippet contains a simple JSP that uses a scripting element to print the text Hello Bob to the requesting client:
<HTML> <BODY> <% out.println("Hello Bob"); %> </BODY> </HTML>

We should note that while JSP scriplet code can be very powerful, composing all our JSP logic using scriptlet code can make our application difficult to manage. This problem led to the creation of custom tag libraries.

5.4 IMPLICIT OBJECTS


We have implicit access to certain objects that are available for use in all JSP documents. These objects are parsed by the JSP engine and inserted into the generated servlet as if we defined them ourself.

out
The implicit out object represents a JspWriter (derived from a java.io.Writer) that provides a stream back to the requesting client. The most common method of this object is out.println(), which prints text that will be displayed in the clients browser. Next Listing provides an example using the implicit out object.
<%@ page errorPage="errorpage.jsp" %> <html> <head> <title>Use Out</title> </head> <body> <% // Print a simple message using the implicit out object. out.println("<center><b>Hello Wiley" + " Reader!</b></center>"); %> </body>

89

</html>

request
The implicit request object represents the javax.servlet.http.HttpServletRequest interface, discussed later in this chapter. The request object is associated with every HTTP request. One of the more common uses for the request object is to access request parameters. We can do this by calling the request objects getParameter() method with the parameter name we are seeking. It will return a string with the value matching the named parameter. An example using the implicit request object appears in Listing
<%@ page errorPage="errorpage.jsp" %> <html> <head> <title>UseRequest</title> </head> <body> <% out.println("<b>Welcome: " + request.getParameter("user") + "</b>"); %> </body> </html>

This JSP calls the request.getParameter() method, passing it the parameter user. This method looks for the key user in the parameter list and returns the value, if it is found.

response
The implicit response object represents the javax.servlet.http.HttpServletResponse object. The response object is used to pass data back to the requesting client. This implicit object provides all the functionality of the HttpServletRequest, just as if we were executing in a servlet. One of the more common uses for the response object is writing HTML output back to the client browser; however, the JSP API already provides access to a stream back to the client using the implicit out object, as described in the previous implicit out discussion.

pageContext
The pageContext object provides access to the namespaces associated with a JSP page. It also provides accessors to several other JSP implicit objects. A common use for the pageContext is setting and retrieving objects using the setAttribute() and getAttribute() methods.

session
The implicit session object represents the javax.servlet.http.HttpSession object. Its used to store objects between client requests, thus providing an almost stateful HTTP interactivity. An example of using the session object

90

<%@ page errorPage="errorpage.jsp" %> <html> <head> <title>Session Example</title> </head> <body> <% // get a reference to the current count from the session Integer count = (Integer)session.getAttribute("COUNT"); if ( count == null ) { // If the count was not found create one count = new Integer(1); // and add it to the HttpSession session.setAttribute("COUNT", count); } else { // Otherwise increment the value count = new Integer(count.intValue() + 1); session.setAttribute("COUNT", count); } out.println("<b>We have accessed this page: " + count + " times.</b>"); %> </body> </html>

Output: It will display the number of time accessed the page.

application
The application object represents the javax.servlet.ServletContext, discussed earlier in this chapter. The application object is most often used to access objects stored in the ServletContext to be shared between Web components in a global scope. It is a great place to share objects between JSPs and servlets. An example using the application object can be found earlier in this chapter, in the section The ServletContext.

config
The implicit config object holds a reference to the ServletConfig, which contains configuration information about the JSP/servlet engine containing the Web application where this JSP resides.

page
The page object contains a reference to the current instance of the JSP being accessed. The page object is used just like this object, to reference the current instance of the generated servlet representing this JSP. exception

91

The implicit exception object provides access to an uncaught exception thrown by a JSP. It is available only in the attribute isErrorPage set to true.

5.5 STANDARD ACTION AND JAVA BEAN


JSP standard actions are predefined custom tags that can be used to encapsulate common actions easily. There are two types of JSP standard actions: the first type is related to JavaBeans functionality, and the second type consists of all other standard actions. Three predefined standard actions relate to using JavaBeans in a JSP: <useBean>, <setProperty>, and <getProperty>. All We need to know about beans are three simple points:

1. A bean class must have a zero-argument (empty) constructor.


We can satisfy this requirement either by explicitly defining such a constructor or by omitting all constructors, which results in an empty constructor being created automatically. The empty constructor will be called when JSP elements create beans.

2. A bean class should have no public instance variables (fields). 3. Persistent values should be accessed through methods called getXxx and setXxx.
For example, if our Car class stores the current number of passengers, we might have methods named getNumPassengers (which takes no arguments and returns an int) and setNumPassengers (which takes an int and has a void return type).
First we will define these tags, we will create a simple example that uses them.

<jsp:useBean>
The <jsp:useBean> JavaBean standard action creates or looks up an instance of a JavaBean with a given ID and scope. The syntax of the <jsp:useBean> action is as follows: <jsp:useBean id="name" class=className scope="page|request|session|application" > body </jsp:useBean>

id

The key associated with the instance of the object in the specified scope. This key is case-sensitive. The id attribute is the same key as used in the page.getAttribute() method. The life of the referenced object. The scope options are page, request, session, and application.

scope :

92

class

The fully qualified class name that defines the implementation of the object. The class name is case-sensitive.

<jsp:setProperty>
The <jsp:setProperty> standard action sets the value of a beans property. Its name attribute represents an object that must already be defined and in scope. The syntax for the <jsp:setProperty> action is as follows: <jsp:setProperty name="beanName" propexpr /> In the preceding syntax, the name attribute represents the name of the bean whose property we are setting, and propexpr can be represented by any of the following expressions: property="*" | property="propertyName" | property="propertyName" param="parameterName" | property="propertyName" value="propertyValue"
name : The name of the bean instance defined by a <jsp:useBean> action or some other action.

property the value matched an unmodified. param

The bean property for which we want to set a value. If we set propertyName to an asterisk (*), then the action will iterate over current ServletRequest parameters, matching parameter names and types to property names and setter method types, and setting each property to the value of the matching parameter. If a parameter has empty string for a value, the corresponding property is left The name of the request parameter whose value we want to set the named property to. A <jsp:setProperty> action cannot have both param and value attributes referenced in the same action. The value assigned to the named beans property.

value

<jsp:getProperty>
The last standard action that relates to integrating JavaBeans into JSPs is <jsp:getProperty>. It takes the value of the referenced beans instance property, converts it to a java.lang.String, and places it on the output stream. The referenced bean instance must be defined and in scope before this action can be used. The syntax for the <jsp:getProperty> action is as follows: <jsp:getProperty name="name" property="propertyName" /> name : The name of the bean instance from which the property is obtained, defined by a <jsp:useBean> action or some other action.

93

property

The bean property for which we want to get a value.

A JavaBean Standard Action Example


To learn how to use the JavaBean standard actions, lets create an example. This example uses a simple JavaBean that acts as a counter. The Counter bean has a single int property, count, that holds the current number of times the beans property has been accessed. It also contains the appropriate methods for getting and setting this property.
package chapter; public class Counter { int count = 0; public Counter() { } public int getCount() { count++; return count; } public void setCount(int count) { this.count = count; } }

Integrate this sample JavaBean into a JSP, using the JavaBean standard actions.
<!-- Set the scripting language to java --> <%@ page language="java" %> <HTML> <HEAD> <TITLE>Bean Example</TITLE> </HEAD> <BODY> <!-- Instantiate the Counter bean with an id of "counter" --> <jsp:useBean id="counter" scope="session" class="chapter.Counter" /> <% // write the current value of the property count out.println("Count from scriptlet code : " + counter.getCount() + "<BR>"); %> <!-- Get the the beans count property, --> <!-- using the jsp:getProperty action. --> Count from jsp:getProperty : <jsp:getProperty name="counter" property="count" /><BR> </BODY> </HTML>

Compile the Counter class, move it to the /WEB-INF/classes/chapter/ directory, and copy the Counter.jsp file to the root directory and make request:--

<jsp:param>

94

The <jsp:param> action provides parameters and values to the JSP standard actions <jsp:include>, <jsp:forward>, and <jsp:plugin>. The syntax of the <jsp:param> action is as follows: <jsp:param name="name" value="value"/>

<jsp:include>
The <jsp:include> standard action provides a method for including additional static and dynamic Web components in a JSP. The syntax for this action is as follows: <jsp:include page="urlSpec" flush="true"> <jsp:param ... /> </jsp:include> Note It is important to note the difference between the include directive and the include standard action. The directive is evaluated only once, at translation time, whereas the standard action is evaluated with every request.

<jsp:forward>
The <jsp:forward> standard action enables the JSP engine to execute a runtime dispatch of the current request to another resource existing in the current Web application, including static resources, servlets, or JSPs. The appearance of <jsp:forward> effectively terminates the execution of the current JSP. Note A <jsp:forward> action can contain <jsp:param> subattributes. These subattributes act as parameters that will be forwarded to the targeted resource. The syntax of the <jsp:forward> action is as follows: <jsp:forward page="relativeURL"> <jsp:param .../> </jsp:forward>

<jsp:plugin>
The last standard action we will discuss is <jsp:plugin>. This action enables a JSP author to generate the required HTML, using the appropriate client-browser independent constructs, to result in the download and subsequent execution of the specified applet or JavaBeans component. The <jsp:plugin> tag, once evaluated, will be replaced by either an <object> or <embed> tag, as appropriate for the requesting user agent. The attributes of the <jsp:plugin> action provide configuration data for the presentation of the embedded element. The syntax of the <jsp:plugin> action is as follows:
<jsp:plugin type="pluginType" code="classFile" codebase="relativeURLpath"> <jsp:params>

95

</jsp:params> </jsp:plugin>

type code codebase

: : :

The type of plug-in to include (an applet, for example) The name of the class that will be executed by the plug-in The base or relative path where the code attribute can be found

Examples:-- Using plugin tag


<%@ page language="java" %> <jsp:plugin type="applet" code="myapplet" codebase="." width="300" height="300" > </jsp:plugin> myapplet.java import java.awt.*; import java.applet.*; public class myapplet extends Applet { public void paint(Graphics g) { g.drawString("HELLO",100,100); } }

96

CHAPTER - VI REMOTE METHOD INVOCATION [ RMI ]


6.1 INTRODUCTION
A distributed system is a program or set of programs that runs using more than one computing resource. Distributed computing covers a wide spectrum, from intra-process distributed applications , through intrasystem applications (such as a network client and server on the same machine), to applications where a client program and a server program run on machines far apart (such as a web application). Distributed computing was around for a long time before Java. Some traditional distributed mechanisms include RPC (remote procedure call) and CORBA. Java adds RMI (Remote Method Invocation), its own CORBA support, and EJB (Enterprise JavaBeans) to the mix. At its simplest level, remote procedure call is the ability to run code on another machine and have it behave as much as possible like a local method call. Most versions of Unix use remote procedure calls extensively: Sun's NFS, YP/NIS, and NIS+ are all built on top of Sun's RPC. Windows NT implements large parts of the Unix DCE Remote Procedure Call and can interoperate with it. Each of these defines its own slightly ad hoc method of specifying the interface to the remote call. Sun's RPC uses a program called rpcgen, which reads a protocol specification and writes both the client and server network code. These are both Unix-specific; they have their place, but aren't as portable as Java. Java Remote Methods Invocation (RMI) is a type of remote procedure call that is network independent, lightweight, and totally portable, as it's written in pure Java. CORBA is the Object Management Group's (OMG) Common Object Request Broker Architecture, a sort of remote procedure call for programs written in C, C++, Java, Ada, Smalltalk, and others to call methods in objects written in any of those languages. It provides a transport service called the Internet Inter-Orb Protocol (IIOP) that allows object implementations from different vendors to interoperate. There is now a version of RMI over IIOP, making it possible to claim that RMI is CORBA-compliant. Enterprise JavaBeans (EJB) is a distributed object mechanism used primarily for building reusable distributed objects that provide both business logic and database storage. There are several types of EJBs, including session beans, which do something (a shopping cart bean is a good example) and entity beans, which represent something (usually the things stored in a database; in our shopping cart example, the entity beans would be the objects available for purchase).

Basic Steps: RMI


1. Define (or locate) the remote interface in agreement with the server. 2. Write server program. 3. Run rmic (Java RMI stub compiler) to generate the network glue.

97

4. Write the client. 5. Ensure that the RMI registry is running. 6. Start the server. 7. Run one or more clients.

6.2 Defining the RMI Contract


RMI procedures are defined using an existing Java mechanism: interfaces. An interface is similar to an abstract class, but a class can implement more than one interface. RMI remote interfaces must be subclassed from java.rmi.Remote and both the client and server must be in the same Java package. All parameters and return values must be either primitives (int, double, etc.), or implement Serializable (as do most of the standard types like String). Or they can also be Remote. Figure shows the relationships between the important classes involved in an RMI implementation. The developer need only write the interface and two classes, the client application and the server object implementation. The RMI stub or proxy and the RMI skeleton or adapter are generated for us by the rmic program while the RMI Registry and other RMI classes at the bottom of the figure are provided as part of RMI itself. Next example is a simple RemoteDate getter interface, which lets us find out the date and time on a remote machine.

Example RemoteDate.java
package darwinsys.distdate; import java.rmi.*; import java.util.Date; /** A statement of what the client & server must agree upon. */ public interface RemoteDate extends java.rmi.Remote { /** The method used to get the current date on the remote */ public Date getRemoteDate( ) throws java.rmi.RemoteException; /** The name used in the RMI registry service. */ public final static String LOOKUPNAME = "RemoteDate"; }

98

It's necessary for this file to list all the methods that will be callable from the server by the client. The lookup name is an arbitrary name that is registered by the server and looked up by the client to establish communications between the two processes.

6.3 RMI Client


Assume for now that the server object is running remotely. To locate it, we use Naming.lookup( ) , passing in the lookup name. This gives us a reference to a proxy object an object that, like the real server object, implements the remote interface but runs in the same Java Virtual Machine as our client application. Here we see the beauty of interfaces: the proxy object implements the interface, so our code can use it just as it would use a local object providing the given service. And the remote object also implements the interface, so the proxy object's remote counterpart can use it exactly as the proxy is used. Next Example shows the client for the RemoteDate service. Example DateClient.java package darwinsys.distdate; import java.rmi.*; import java.util.*; /* A very simple client for the RemoteDate service. */ public class DateClient { /** The local proxy for the service. */ protected static RemoteDate netConn = null; public static void main(String[] args) { try { netConn = (RemoteDate)Naming.lookup(RemoteDate.LOOKUPNAME); Date today = netConn.getRemoteDate( ); System.out.println(today.toString( )); // XX use a DateFormat... } catch (Exception e) { System.err.println("RemoteDate exception: " + e.getMessage()); e.printStackTrace( ); } } }

99

6.4 RMI SERVER


Basic Steps: RMI Server
1. 2. 3. 4. 5. 6. 7. Define (or locate) the remote interface in agreement with the client. Specify the remote interface being implemented. Define the constructor for the remote object. Provide implementations for the methods that can be invoked remotely. Create and install a security manager. Create one or more instances of a remote object. Register at least one of the remote objects with the RMI remote object registry.

This implementation divides the server into the traditional two parts, a main program and an implementation class. It is just as feasible to combine these in a single class. The main program shown in next example simply constructs an instance of the implementation and registers it with the lookup service.
Example DateServer.java package darwinsys.distdate; import java.rmi.*; public class DateServer { public static void main(String[] args) { // we may want a SecurityManager for downloading of classes: // System.setSecurityManager(new RMISecurityManager( )); try { // Create an instance of the server object RemoteDateImpl im = new RemoteDateImpl( ); System.out.println("DateServer starting..."); // Locate it in the RMI registry. Naming.rebind(RemoteDate.LOOKUPNAME, im); System.out.println("DateServer ready."); } catch (Exception e) { System.err.println(e); System.exit(1); } } }

The Naming.bind( ) method creates an association between the lookup name and the instance of the server object. This method will fail if the server already has an instance of the given name, requiring we to call rebind( ) to overwrite it. But since that's exactly where we'll find ourself if the server crashes (or we kill it while debugging) and we restart it, many people just use rebind( ) all the time.

100

The implementation class must implement the given remote interface. Example RemoteDateImpl.java
package darwinsys.distdate; import java.rmi.*; import java.rmi.server.*; import java.util.*; public class RemoteDateImpl extends UnicastRemoteObject implements RemoteDate { /** Construct the object that implements the remote server. * Called from main, after it has the SecurityManager in place. */ public RemoteDateImpl( ) throws RemoteException { super( ); // sets up networking } /** The remote method that "does all the work". This won't get * called until the client starts up. */ public Date getRemoteDate( ) throws RemoteException { return new Date( ); } }

Using the server


Once compiled the implementation class, we can run rmic (RMI compiler) to build some glue files and install them in the client's CLASSPATH: $ jikes -d . RemoteDateImpl.java $ ls darwinsys/distdate DateApplet$1.class DateClient.class RemoteDate.class DateApplet.class DateServer.class RemoteDateImpl.class $ rmic -d . darwinsys.distdate.RemoteDateImpl $ ls darwinsys/distdate DateApplet$1.class DateServer.class RemoteDateImpl_Skel.class DateApplet.class RemoteDate.class RemoteDateImpl_Stub.class DateClient.class RemoteDateImpl.class $ We must also ensure that TCP/IP networking is running, and then start the RMI registry program. If we're doing this by hand, just type the command rmiregistry in a separate window, or start or background it on systems that support this.

101

6.5 Deploying RMI Across a Network


As shown so far, the server and the client must be on the same machine -- some distributed System. Get the RMI registry to dish out the client stubs on demand. RMI does not provide true location transparency, which means that we must at some point know the network name of the machine the server is running on. The server machine must be running the RMI registry program as well, though there's no need for the RMI registry to be running on the client side. Now the RMI registry needs to send the client stubs to the client. The best way to do this is to provide an HTTP URL and ensure that the stub files can be loaded from our web server. This can be done by passing the HTTP URL into the RMI server's startup by defining it in the system properties: java -Djava.rmi.server.codebase=http://serverhost/stubsdir/ ServerMain In this example, serverhostis the TCP/IP network name of the host where the RMI server and registry are running, and stubsdir is some directory relative to the web server from which the stub files can be downloaded. Be careful to start the RMI registry in its own directory, away from where we are storing (or building!) the RMI stubs. If RMI can find the stubs in its own CLASSPATH, it will assume they are universally available and won't download them! The only other thing to do is to change the client's view of the RMI lookup name to something like rmi://serverhost/foo_bar_name. And for security reasons, the installation of the RMI Security Manager, which was optional before, is now a requirement. Exercise: 1. Write a rmi application to provide arithmetic operation(addition, subtraction, multiplication and division) from client program. 2. Write a rmi application for user login module and in this module client program should be applet based.

102

CHAPTER - VII ENTERPRISE JAVA BEAN [ EJB ]


7.1 INTRODUCTION
An enterprise bean is a server-side component that encapsulates the business logic of an application. The business logic is the code that fulfills the purpose of the application. In an inventory control application, for example, the enterprise beans might implement the business logic in methods called checkInventoryLevel and orderProduct. By invoking these methods, remote clients can access the inventory services provided by the application Enterprise beans run in the EJB container, a runtime environment within the J2EE server. Although transparent to the application developer, the EJB container provides system-level services such as transactions to its enterpriseeans. These services enable we to quickly build and deploy enterprise beans, which form the core of transactional J2EE applications.

Benefits of Enterprise Beans


For several reasons, enterprise beans simplify the development of large, distributed applications. First, because the EJB container provides system-level services to enterprise beans, the bean developer can concentrate on solving business problems. The EJB container--not the bean developer--is responsible for system-level services such as transaction management and security authorization. Second, because the beans--and not the clients--contain the application's business logic, the client developer can focus on the presentation of the client. The client developer does not have to code the routines that implement business rules or access databases. As a result, the clients are thinner, a benefit that is particularly important for clients that run on small devices. Third, because enterprise beans are portable components, the application assembler can build new applications from existing beans. These applications can run on any compliant J2EE server.

103

Enterprise JavaBeans Technology

Database Java client JDBC connection pool

JNDI

RMI classes EJB

Java client

Web Logic Server

container

The Enterprise JavaBeans specification defines an architecture for a transactional, distributed object system based on components. The specification mandates a programming model; that is, conventions or protocols and a set of classes and interfaces which make up the EJB API. The EJB programming model provides bean developers and EJB server vendors with a set of contracts that defines a common platform for development. The goal of these contracts is to ensure portability across vendors while supporting a rich set of functionality.

The EJB Container


Enterprise beans are software components that run in a special environment called an EJB container. The container hosts and manages an enterprise bean in the same manner that the Java Web Server hosts a Servlet or an HTML browser hosts a Java applet. An enterprise bean cannot function outside of an EJB container. The EJB container manages every aspect of an enterprise bean at run time including remote access to the bean, security, persistence, transactions, concurrency, and access to and pooling of resources. The container isolates the enterprise bean from direct access by client applications. When a client application invokes a remote method on an enterprise bean, the container first intercepts the invocation to ensure persistence, transactions, and security are applied properly to every operation a client performs on the bean. The container manages security, transactions, and persistence automatically for the bean, so the bean developer doesn't have to write this type of logic into the bean code itself. The 104

enterprise bean developer can focus on encapsulating business rules, while the container takes care of everything else. Containers will manage many beans simultaneously in the same fashion that the Java WebServer manages many servlets. To reduce memory consumption and processing, containers pool resources and manage the lifecycles of all the beans very carefully. When a bean is not being used, a container will place it in a pool to be reused by another client, or possibly evict it from memory and only bring it back when its needed. Because client applications don't have direct access to the beans -- the container lies between the client and bean -- the client application is completely unaware of the containers resource management activities. A bean that is not in use, for example, might be evicted from memory on the server, while its remote reference on the client remains intact. When the client invokes a method on the remote reference, the container simply re-incarnates the bean to service the request. The client application is unaware of the entire process. An enterprise bean depends on the container for everything it needs. If an enterprise bean needs to access a JDBC connection or another enterprise bean, it does so through the container; if an enterprise bean needs to access the identity of its caller, obtain a reference to itself, or access properties it does so through the
EJB Server EJB Container

EJB Hom e Interface Client Client EJB Rem ote Interface

EJB Bean EJB Bean

container. The enterprise bean interacts with its container through one of three mechanisms: callback methods, the EJBContext interface, or JNDI.

Callback Methods

Every bean implements a subtype of the EnterpriseBean interface which defines several methods, called callback methods. Each callback method alerts the bean of a different event in its lifecycle and the container will invoke these methods to notify the bean when it's about to pool 105

the bean, persist its state to the database, end a transaction, remove the bean from memory, etc. The callback methods give the bean a chance to do some housework immediately before or after some event. Callback methods are discussed in more detail in later sections. EJBContext : Every bean obtains an EJBContext object, which is a reference directly to the container. The EJBContext interface provides methods for interacting with the container so that that bean can request information about its environment like the identity of its client, the status of a transaction, or to obtain remote references to itself.

Java Naming and Directory Interface

Java Naming and Directory Interface (JNDI) is a standard extension to the Java platform for accessing naming systems like LDAP, NetWare, file systems, etc.

When to Use Enterprise Beans


We should consider using enterprise beans if our application has any of the following requirements: The application must be scalable. To accommodate a growing number of users, we may need to distribute an application's components across multiple machines. Not only can the enterprise beans of an application run on different machines, but their location will remain transparent to the clients. Transactions are required to ensure data integrity. Enterprise beans support transactions, the mechanisms that manage the concurrent access of shared objects. The application will have a variety of clients. With just a few lines of code, remote clients can easily locate enterprise beans. These clients can be thin, various, and numerous.

106

Types of Enterprise Beans


Table summarizes the three different types of enterprise beans. The following sections discuss each type in more detail. Summary of Enterprise Bean Types Enterprise Bean Type Session Entity Message-Driven Performs a task for a client Represents a business entity object that exists in persistent storage Acts as a listener for the Java Message Service API, processing messages asynchronously Purpose

What does an EJB contains?


1. Home Interface 2. Remote Interface [ Component Inetrface] 3. Bean class 4. Deployment Descripter

Home Interface
Starting point for getting a reference of bean. We can think the home interface as a kind of factory that makes and distribution bean reference toclient. This defines the beans life-cycle methods for creating, removing and finding beans.

Remote Interface
This declares the beans business methods Note:- Although the bean provider specifies these interfaces it is the container that creates a class that implements it.

Bean Class
This is actual bean class where we provides implementations of the business methods.

107

Deployment Descriptors
This xml files describes all the three files and their relationship. The server would not identify three files itself. We have to tell the server through Deployment Descriptors About these files.

Clients of EJB
1. Servlets and JSP 2. Application programs 3. CORBA clients 4. One ejb can be client of another ejb.

7.2 EJB AND JAVA BEAN


Both EJB and javabean are used to encapsulate business logic but both are entirely different. Those differences are1. 2. 3. 4. The javabean architecture is designed to provide a format for general purpose component where Enterprise javabean architecture provides a format for highly specialized business logic components deployed in j2ee environment. To execute javabean JVM is sufficient but for EJB ejb container is required. Container does not provide specific service to javabean but for EJB container provides many services like persistence, transaction, security, lifecycle services etc. We can use javabean in any tier but EJB we can use only in business tier.

7.3 SESSION BEAN


A session bean represents a single client inside the J2EE server. To access an application that is deployed on the server, the client invokes the session bean's methods. The session bean performs work for its client, shielding the client from complexity by executing business tasks inside the server. As its name suggests, a session bean is similar to an interactive session. A session bean is not shared--it may have just one client, in the same way that an interactive session may have just one user. Like an interactive session, a session bean is not persistent. When the client terminates, its session bean appears to terminate and is no longer associated with the client.

108

State Management Modes


There are two types of session beans: stateful and stateless.

Stateful Session Beans


The state of an object consists of the values of its instance variables. In a stateful session bean, the instance variables represent the state of a unique client-bean session. Because the client interacts ("talks") with its bean, this state is often called the conversational state. The state is retained for the duration of the client-bean session. If the client removes the bean or terminates, the session ends and the state disappears. This transient nature of the state is not a problem, however, because when the conversation between the client and the bean ends there is no need to retain the state.

Stateless Session Beans


A stateless session bean does not maintain a conversational state for a particular client. When a client invokes the method of a stateless bean, the bean's instance variables may contain a state, but only for the duration of the invocation. When the method is finished, the state is no longer retained. Except during method invocation, all instances of a stateless bean are equivalent, allowing the EJB container to assign an instance to any client. Because stateless session beans can support multiple clients, they can offer better scalability for applications that require large numbers of clients. Typically, an application requires fewer stateless session beans than stateful session beans to support the same number of clients. At times, the EJB container may write a stateful session bean to secondary storage. However, stateless session beans are never written to secondary storage. Therefore, stateless beans may offer better performance than stateful beans.

When to Use Session Beans


In general, we should use a session bean if the following circumstances hold: At any given time, only one client has access to the bean instance. The state of the bean is not persistent, existing only for a short period of time (perhaps a few hours).

Stateful session beans are appropriate if any of the following conditions are true:

109

The bean's state represents the interaction between the bean and a specific client. The bean needs to hold information about the client across method invocations. The bean mediates between the client and the other components of the application, presenting a simplified view to the client. Behind the scenes, the bean manages the work flow of several enterprise beans. To improve performance, we might choose a stateless session bean if it has any of these traits The bean's state has no data for a specific client. In a single method invocation, the bean performs a generic task for all clients. For example, we might use a stateless session bean to send an e-mail that confirms an online order. The bean fetches from a database a set of read-only data that is often used by clients. Such a bean, for example, could retrieve the table rows that represent the products that are on sale this month.

The Life Cycle of a Stateful Session Bean


Figure illustrates the stages that a session bean passes through during its lifetime. The client initiates the life cycle by invoking the create method. The EJB container instantiates the bean and then invokes the setSessionContext and ejbCreate methods in the session bean. The bean is now ready to have its business methods invoked.

While in the ready stage, the EJB container may decide to deactivate, or passivate, the bean by moving it from memory to secondary storage. The EJB container invokes the bean's ejbPassivate method immediately before passivating it. If a client invokes a business method on the bean while it is in the passive stage, the EJB container activates the bean, moving it back to the ready stage, and then calls the bean's ejbActivate method. 110

At the end of the life cycle, the client invokes the remove method and the EJB container calls the bean's ejbRemove method. The bean's instance is ready for garbage collection. Our code controls the invocation of only two life-cycle methods--the create and remove methods in the client. All other methods in Figure are invoked by the EJB container. The ejbCreate method, for example, is inside the bean class, allowing we to perform certain operations right after the bean is instantiated. For instance, we may wish to connect to a database in the ejbCreate method.

Code samples for stateful session bean using weblogic server:Home Interface: chhabi_home.java
import javax.ejb.*; import java.rmi.RemoteException; public interface chhabi_home extends EJBHome { public chhabi_remote create(int var) throws CreateException,RemoteException; }

Remote Interface: chhabi_remote.java


import javax.ejb.*; import java.rmi.RemoteException; public interface chhabi_remote extends EJBObject { public int count() throws RemoteException; }

Bean Class: chhabi_bean.java


import javax.ejb.*; public class chhabi_bean implements SessionBean { public int var; public int count() { System.out.println("count()"); return ++var; } public void ejbCreate(int var) throws CreateException { this.var=var; System.out.println("create()"); } public void ejbPassivate() { System.out.println("ejbActivate()"); } public void ejbActivate() { System.out.println("ejbPassivate()");

111

} public void ejbRemove() { System.out.println("ejbRemove()"); } public void setSessionContext(SessionContext ctx) { System.out.println("setSessionContext()"); }

Client Program: chhabi_client .java


import javax.rmi.PortableRemoteObject; import javax.naming.*; import java.util.Properties; public class chhabi_client { public static void main(String a[]) { try { Properties p=new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory" ); p.put(Context.PROVIDER_URL,"t3://localhost:7001"); Context ctx=new InitialContext(p); chhabi_home home=(chhabi_home)ctx.lookup("chhabi_stateful_jndi"); chhabi_remote r[]=new chhabi_remote[4]; int ct=0; System.out.println("Bean intialization......"); for(int i=0;i<4;i++) { r[i]=home.create(ct); ct=r[i].count(); System.out.println(ct); Thread.sleep(5000); } System.out.println("Calling count method...."); for(int i=0;i<4;i++) { ct=r[i].count(); System.out.println(ct); Thread.sleep(5000); } for(int i=0;i<4;i++) { r[i].remove(); } }catch(Exception e) { } } }

112

The Life Cycle of a Stateless Session Bean Stateless session beans, like all session beans, are not persistent business objects as are entity beans. They do not represent data in the database. Instead, they represent business processes or tasks that are performed on behalf of the client using them. The business methods in a stateless bean act more like traditional procedures in a legacy transactionprocessing monitor. Each invocation of a stateless business method is independent from previous invocations. Because stateless session beans are "stateless" they are easier for the EJB container to manage, so they tend to process requests faster and use less resources. Because a stateless session bean is never passivated, its life cycle has just two stages: nonexistent and ready for the invocation of business methods. Figure illustrates the stages of a stateless session bean.

Code samples for stateless session bean using weblogic server:Home Interface: cegonhome.java
import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface cegonhome extends EJBHome { public cegonremote create() throws CreateException,RemoteException; }

113

Remote Interface: cegonremote.java


import java.rmi.RemoteException; import javax.ejb.*; public interface cegonremote extends EJBObject { public int xadd(int m,int n) throws RemoteException; }

Bean Class:
import javax.ejb.*; import java.rmi.*; public class cegonbean implements SessionBean { public int xadd(int m,int n) { return m+n; } public void ejbCreate() throws CreateException { } public public public public } System.out.println("Create Method"); void void void void ejbRemove() { } ejbActivate() { } ejbPassivate() { } setSessionContext(SessionContext sc) { }

Client Program: cegonclient.java


import javax.naming.*; import java.util.Properties; public class cegonclient { public static void main(String a[]) { try { Properties p=new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFa ctory"); p.put(Context.PROVIDER_URL,"t3://localhost:7001"); Context ctx=new InitialContext(p); cegonhome home=(cegonhome)ctx.lookup("cegon_home_jndi1"); cegonremote rem=home.create(); System.out.println(rem.xadd(100,200)); } catch(Exception e){ System.out.println(e.getMessage()); } }

114

7.4 Entity Bean


Entity bean represent and manipulate the persistent data of an application, and provides an object-oriented representation of data in a database. Encapsulating this state behind an object isolates the uses from the implementation details of how the state is represented in memory and in the persistent store. The entity bean is then responsible for loading the state from the store and saving it back later. Entity Bean can be accessed simultaneously by multiple clients An entity bean might represent a customer, a product or an account. The lifespan of an entity EJB is long as of the data if represents in the database.

Types of Entity Bean


Bean Managed Persistence
provider. Container Managed Persistence container. :In CMP, the persistence of an entity bean to persistent storage is the responsibility of ejb : In BMP, the persistence of an entity bean to persistent storage is the responsibility of bean

The Life Cycle of an Entity Bean

115

Figure shows the stages that an entity bean passes through during its lifetime. After the EJB container creates the instance, it calls the setEntityContext method of the entity bean class. The setEntityContext method passes the entity context to the bean. After instantiation, the entity bean moves to a pool of available instances. While in the pooled stage, the instance is not associated with any particular EJB object identity. All instances in the pool are identical. The EJB container assigns an identity to an instance when moving it to the ready stage. There are two paths from the pooled stage to the ready stage. On the first path, the client invokes the create method, causing the EJB container to call the ejbCreate and ejbPostCreate methods. On the second path, the EJB container invokes the ejbActivate method. While in the ready stage, an entity bean's business methods may be invoked. There are also two paths from the ready stage to the pooled stage. First, a client may invoke the remove method, which causes the EJB container to call the ejbRemove method. Second, the EJB container may invoke the ejbPassivate method. At the end of the life cycle, the EJB container removes the instance from the pool and invokes the unsetEntityContext method. In the pooled state, an instance is not associated with any particular EJB object identity. With beanmanaged persistence, when the EJB container moves an instance from the pooled state to the ready state, it does not automatically set the primary key. Therefore, the ejbCreate and ejbActivate methods must assign a value to the primary key. If the primary key is incorrect, the ejbLoad and ejbStore methods cannot synchronize the instance variables with the database. The ejbCreate method assigns the primary key from one of the input parameters. The ejbActivate method sets the primary key (id) as follows: id = (String)context.getPrimaryKey(); In the pooled state, the values of the instance variables are not needed. We can make these instance variables eligible for garbage collection by setting them to null in the ejbPasssivate method.

Container-Managed Persistence
Container-managed persistence beans are the simplest for the bean developer to create and the most difficult for the EJB sever to support. This is because all the logic for synchronizing the bean's state with the database is handled automatically by the container. This means that the bean developer doesn't need to write any data access logic, while the EJB server is supposed to take care of all the persistence needs automatically -- a tall order for any vendor. Most EJB vendors support automatic persistence to a relational database, but the level of support varies. Some provide very sophisticated Object-to-Relational mapping, while others are very limited. 116

Code samples for CMP entity bean using weblogic server:Home Interface: AccountHome.java
import javax.ejb.CreateException; import javax.ejb.EJBHome; import javax.ejb.FinderException; import java.rmi.RemoteException; import java.util.Collection; public interface AccountHome extends EJBHome { public Account create(String accountId, double initialBalance, String type) throws CreateException, RemoteException; public Account findByPrimaryKey(String primaryKey) throws FinderException, RemoteException; public Collection findBigAccounts(double balanceGreaterThan) throws FinderException, RemoteException; } Remote Interface: Account.java import java.rmi.RemoteException; import javax.ejb.*; public public public public public } interface Account extends EJBObject { double deposit(double amount) throws RemoteException; double withdraw(double amount) throws RemoteException; double balance() throws RemoteException; String accountType() throws RemoteException;

Bean Class: AccountBean.java


import java.io.Serializable; import java.util.Enumeration; import java.util.Vector; import javax.ejb.*; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; abstract public class AccountBean implements EntityBean { private EntityContext ctx; public AccountBean() {}; public void setEntityContext(EntityContext ctx) { this.ctx = ctx; } public void unsetEntityContext() { this.ctx = null; } abstract public String getAccountId(); abstract public void setAccountId(String val);

117

abstract public double getBalance(); abstract public void setBalance(double val); abstract public String getAccountType(); abstract public void setAccountType(String val); public void ejbActivate() { System.out.println("AccountBean.ejbActivate"); } public void ejbPassivate() { System.out.println("AccountBean.ejbPassivate"); } public void ejbLoad() { System.out.println("AccountBean.ejbLoad"); } public void ejbStore() { System.out.println("AccountBean.ejbStore"); } public void ejbRemove() throws RemoveException { System.out.println("AccountBean.ejbRemove"); } public String ejbCreate(String accountId,double initialBalance,String type)throws CreateException { setAccountId(accountId); setBalance(initialBalance); setAccountType(type); return null; } public void ejbPostCreate(String accountId,double initialBalance,String type) { System.out.println("AccountBean.ejbPostCreate"); } public double deposit(double amount) { System.out.println("AccountBean.deposit: Depositing $" +amount + " into '" + getAccountId() + "'"); setBalance(getBalance() + amount); return getBalance();

} public double withdraw(double amount) { System.out.println("AccountBean.withdraw: Withdrawing $" + amount + " from '" + getAccountId() + "'"); if (amount > getBalance()) {

118

System.out.println( "Request to withdraw $" + amount + "; is more than balance $" + getBalance() + " in account " + getAccountId()); } setBalance(getBalance() - amount); return getBalance();

public double balance() { System.out.println("AccountBean.balance "); return getBalance(); } public String accountType() { System.out.println("AccountBean.accountType "); return getAccountType(); } }

Client Program: Client.java


import import import import import import import java.rmi.RemoteException; java.util.*; javax.ejb.*; javax.naming.Context; javax.naming.InitialContext; javax.naming.NamingException; javax.rmi.PortableRemoteObject;

public class Client { public static void main(String[] args) throws NamingException { try{ Properties h = new Properties(); h.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialCont extFactory"); h.put(Context.PROVIDER_URL,"t3://localhost:7001"); Context ctx=new InitialContext(h); AccountHome home=(AccountHome)ctx.lookup("AccountBean25"); Account [] accounts = new Account [10]; for (int i=0; i<10; i++) { accounts [i] = (Account)home.create("ID: "+i, i * 1000,"Savings"); } Account one=home.findByPrimaryKey("ID: 2") ; one.deposit(5000); Account two=home.findByPrimaryKey("ID: 6") ; two.withdraw(3000); // find all accounts with a balance > 5000 Collection col = home.findBigAccounts(5000); Iterator it=col.iterator(); while (it.hasNext()) { Account accountGT =(Account)it.next(); System.out.println("Account " + accountGT.getPrimaryKey() + "; balance is $" + accountGT.balance());

119

}}

} }catch(Exception e){ System.out.println("eros:"+e); } System.out.println("\nEnd beanManaged.Client...\n");

Bean-Managed Persistence
The bean-managed persistence (BMP) enterprise bean manages synchronizing its state with the database as directed by the container. The bean uses a database API (usually JDBC) to read and write its fields to the database, but the container tells it when to do each synchronization operation and manages the transactions for the bean automatically. Bean-managed persistence gives the bean developer the flexibility to perform persistence operations that are too complicated for the container or to use a data source that is not supported by the container -custom and legacy databases for example.

Code samples for BMP entity bean using weblogic server:Home Interface: bmp_home.java
import import import public javax.ejb.*; java.rmi.RemoteException; java.util.Collection; interface bmp_home extends EJBHome { public bmp_remote create(String accountId, double initialBalance, String type) throws CreateException,RemoteException; public bmp_remote findByPrimaryKey(String primaryKey) throws FinderException,RemoteException; public Collection findBigAccounts(double balanceGreaterThan) throws FinderException,RemoteException; }

Remote Interface: bmp_remote.java


import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface bmp_remote extends EJBObject { public double deposit(double amount) throws RemoteException; public double withdraw(double amount) throws RemoteException; public double balance() throws RemoteException; public String accountType() throws RemoteException; }

Bean class: bmp_bean.java


import import import import java.io.Serializable; java.sql.*; java.util.*; javax.ejb.*;

120

import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; public class bmp_bean implements EntityBean private EntityContext ctx; private String accountId; private double balance; private String type; private Connection con=null; private PreparedStatement ps = null; {

public void setEntityContext(EntityContext ctx) { this.ctx = ctx; } public void unsetEntityContext() { this.ctx = null; } public String ejbCreate(String accountId,double balance,String throws CreateException { this.accountId=accountId; this.balance=balance; this.type=type; try { getConnection(); ps=con.prepareStatement("insert into myaccount (accountId,balance,type) values(?,?,?)"); ps.setString(1,accountId); ps.setDouble(2,balance); ps.setString(3,type); int result=ps.executeUpdate(); } catch(SQLException se) { } return accountId; } public void ejbPostCreate(String accountId,double balance,String type) { } public void ejbActivate() { System.out.println("activate"); } public void ejbPassivate() { System.out.println("pasivate"); } public void ejbLoad() { accountId = (String) ctx.getPrimaryKey(); try { getConnection(); ps=con.prepareStatement("select accountId,balance,type from myaccount where accoundId=?"); ps.setString(1,accountId); ResultSet rs=ps.executeQuery(); if(rs.next()) { accountId = rs.getString(1); balance=rs.getDouble(2); type=rs.getString(3); }

type)

121

else{ } }catch(SQLException se) {} } public void ejbStore() { accountId = (String) ctx.getPrimaryKey(); try { getConnection(); ps=con.prepareStatement("update myaccount set balance=?,type=? where accountId=?"); ps.setDouble(1,balance); ps.setString(2,type); ps.setString(3,accountId); ps.executeUpdate(); } catch(SQLException se) {} } public void ejbRemove() { accountId = (String) ctx.getPrimaryKey(); try { getConnection(); accountId= (String) ctx.getPrimaryKey(); ps=con.prepareStatement("delete from myaccount where accountId=?"); ps.setString(1,accountId); } catch(Exception se) {} } public String ejbFindByPrimaryKey(String pk) throws ObjectNotFoundException { String temp=null; try { getConnection(); ps=con.prepareStatement("select accountId from myaccount where accountId=?"); ps.setString(1,pk); ResultSet rs=ps.executeQuery(); if(rs.next()) { temp=rs.getString("accountId"); } else {} } catch(SQLException se) {} return temp; } public Collection ejbFindBigAccounts(double balance) { Vector v=new Vector(); try { getConnection(); ps=con.prepareStatement("select accountId from myaccount where balance > ?"); ps.setDouble(1,balance); ResultSet rs=ps.executeQuery(); String Id=null; while (rs.next()) {

122

Id = rs.getString("accountId"); v.add(Id); } } catch(SQLException se) {} return v; } public double deposit(double amount) { balance=balance+amount; return balance; } public double withdraw(double amount) { balance=balance-amount; return balance; } public double balance() { try { getConnection(); accountId= (String) ctx.getPrimaryKey(); ps=con.prepareStatement("select balance from myaccount where accountId=?"); ps.setString(1,accountId); ResultSet rs=ps.executeQuery(); balance=rs.getDouble(1); } catch(Exception se) { } return balance; } public String accountType() { try { getConnection(); accountId= (String) ctx.getPrimaryKey(); ps=con.prepareStatement("select type from myaccount where accountId=?"); ps.setString(1,accountId); ResultSet rs=ps.executeQuery(); type=rs.getString(1); } catch(Exception se) { } return type; } private void getConnection() throws SQLException { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con=DriverManager.getConnection("jdbc:odbc:mydatasource"); } catch(Exception e) {} }}

Client Program: bmp_client.java


import java.rmi.*; import java.util.*; import javax.ejb.*;

123

import javax.naming.*; public class bmp_client { public static void main(String[] args) throws NamingException { System.out.println("\nBeginning BeanManaged.Client...\n"); try{ Properties h = new Properties(); h.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialCon textFactory"); h.put(Context.PROVIDER_URL,"t3://localhost:7001"); System.out.println("\nBeginning beanManaged.Client...\n"); Context ctx=new InitialContext(h); Object obj=ctx.lookup("mybmp_client_jndi"); bmp_home home=(bmp_home)PortableRemoteObject.narrow(obj,bmp_home.class); bmp_remote [] accounts = new bmp_remote [10]; for (int i=0; i<10; i++) { accounts [i] = (bmp_remote)home.create("ID: "+i, i * 1000,"Savings"); } // Executing home interface methods // find all accounts with a balance > 4000 /*Collection col = home.findBigAccounts(1000); Iterator it = col.iterator(); while (it.hasNext()) { bmp_remote accountGT =(bmp_remote)it.next(); System.out.println("Account " + accountGT.getPrimaryKey() + ": balance is $" + accountGT.balance()); }*/ // Executing Componenet interface methods bmp_remote temp=home.findByPrimaryKey("ID: 5"); temp.deposit(2000); System.out.println("After Deposit in Account " temp.getPrimaryKey() + " balance is $" + temp.balance()); temp.withdraw(1500); System.out.println("After withdraw in Account " temp.getPrimaryKey() + " balance is $" + temp.balance()); } catch(Exception e){ System.out.println("eros:"+e);} } } System.out.println("\nEnd beanManaged.Client...\n");

+ +

124

7.5 MESSAGE DRIVEN BEAN


The message-driven beans perform one specific function retrieve messages from a messageoriented middleware(MOM). As opposed to session or entity beans, client programs do not accessthese eans directly. These beans use message listeners and are activated by the EJB container when the message arrives. The client programs could be written using Java or any other language that can send messages to the MOM of our choice, which makes messaging in general and MDB in particular a good component for integration of the J2EE systems with the legacy applications. A sample scenario of ticket reservations system that uses MDB is shown Figure-

Java JMS Client

Reservation queue EJB container receive

Java non-JMS client

MDB Confirmation queue sends

Non-java Client

Session bean MOM

An MDB has neither home nor remote interface, because its clients do not need to access the bean.

Code samples for BMP entity bean using weblogic server:Client Program: QSender.java
import javax.jms.*; import javax.naming.*; import java.util.*; public class QSender { public static void main (String arg []) { Context ctx=null; Hashtable ht= new Hashtable(); QueueConnectionFactory qcf=null; QueueConnection qc=null; QueueSession qs=null; QueueSender qsen=null; Queue q=null; TextMessage tm=null; String msg;

125

try { ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialCo ntextFactory"); ht.put(Context.PROVIDER_URL,"t3://localhost:7001"); ctx=new InitialContext(ht); qcf=(QueueConnectionFactory)ctx.lookup("dinesh_jndi"); qc=qcf.createQueueConnection(); qs=qc.createQueueSession(false,javax.jms.QueueSession.AUTO_ACKNOW LEDGE); q=(Queue)ctx.lookup("dinesh_queue_jndi"); qsen=qs.createSender(q); System.out.println("\nSending message to q....\n"); tm=qs.createTextMessage(); for(int i=1;i<=10;i++){ msg="Message #"+ i +"to queue"; tm.clearBody(); tm.setIntProperty("severity",i); tm.setText(msg); System.out.println("\nSending message....:"+msg); qsen.send(tm); } msg="Stop"; tm.clearBody(); tm.setIntProperty("severity",0); tm.setText(msg); System.out.println("Sending message...:"+msg); qsen.send(tm); } catch(Exception e) { e.printStackTrace(); } finally{ try{ qs.close(); qsen.close(); qc.close(); } catch(Exception e){ e.printStackTrace(); } } } }

Bean Class: mymdb.java


import javax.ejb.*; import javax.jms.*; import javax.naming.*; public class mymdb implements MessageDrivenBean, MessageListener { private MessageDrivenContext ctx; public void setMessageDrivenContext(MessageDrivenContext this.ctx=ctx; } public void ejbCreate() {

ctx) {

126

} public void ejbRemove() { } public void onMessage(Message msg) { TextMessage m=(TextMessage)msg; try { System.out.println(m.getText()); }catch (Exception e) {} }

127

CHAPTER - VIII STRUTS


8.1 INTRODUCTION TO STRUTS
Struts is Java MVC framework for building web applications on the J2EE platform. It is a serverside Java implementation of the Model-View-Controller (MVC) design pattern. To understand Struts Framework, we must have a fundamental understanding of the MVC design pattern, The MVC design pattern, which originated from Smalltalk, consists of three components: a Model, a View, and a Controller. Model Represents the data objects. The Model is what is being manipulated and presented to the user. View Serves as the screen representation of the Model. It is the object that presents the current state of the data objects. Controller Defines the way the user interface reacts to the users input. The Controller component is the object that manipulates the Model, or data object.

Benefits of the MVC include:


Reliability
The presentation and transaction layers have clear separation, which allows us to change the look and feel of an application without recompiling Model or Controller code. High reuse and adaptability: The MVC lets us use multiple types of views, all accessing the same server-side code. Very low development and life-cycle costs: The MVC makes it possible to have lower-level programmers develop and maintain the user interfaces. Rapid deployment: Development time can be significantly reduced because Controller programmers (Java developers) focus solely on transactions, and View programmers (HTML and JSP developers) focus solely on presentation.

128

Maintainability: The separation of presentation and business logic also makes it easier to maintain and modify a Struts-based Web application.

The Struts Implementation of the MVC


The Struts Framework models its server-side implementation of the MVC using a combination of JSPs, custom JSP tags, and Java servlets.
[[

Figure depicts the route that most Struts application requests follow. This process can be broken down into five basic steps. Following these steps is a description of the ActionServlet and Action classes. 1. 2. 3. 4. A request is made from a previously displayed View. The request is received by the ActionServlet, which acts as the Controller, and the ActionServlet looks up the requested URI in an XML file and determines the name of the Action class that will perform the necessary business logic. The Action class performs its logic on the Model components associated with the application. Once the Action has completed its processing, it returns control to the ActionServlet. As part of the return, the Action class provides a key that indicates the results of its processing. The ActionServlet uses this key to determine where the results should be forwarded for presentation.

129

5.

The request is complete when the ActionServlet responds by forwarding the request to the View that was linked to the returned key, and this View presents the results of the Action.

The Model
The Struts Framework does not provide any specialized Model components; therefore, we will not dedicate an entire chapter to the Model component. Instead, we will reference Model components as they fit into each example.

The View
Each View component in the Struts Framework is mapped to a single JSP that can contain any combination of Struts custom tags.

The Controller
The Controller component of the Struts Framework is the backbone of all Struts Web applications. It is implemented using a servlet named org.apache.struts.action.ActionServlet.This servlet receives all requests from clients, and delegates control of each request to a user-defined org.apache.struts.action.Action class. The ActionServlet delegates control based on the URI of the incoming request. Once the Action class has completed its processing, it returns a key to the ActionServlet, which is then used by the ActionServlet to determine the View that will present the results of the Actions processing. The ActionServlet is similar to a factory that creates Action objects to perform the actual business logic of the application.

8.2 A simple application


First, we explain the steps that we must perform when installing and configuring a Struts application. Then, we create a sample application that displays the components of a working Struts application. The goal of this chapter is to provide we with a quick introduction to the components of a Struts application.

Obtaining and Installing the Jakarta Struts Project


Before we can get started with our Struts development, we need to obtain the latest release of the Struts archive and all of its supporting archives. We need to acquire: The latest-release Jakarta Struts binary for our operating system. For these examples, we are using Struts 1.1, which can be found at http://jakarta.apache.org/ Once we have the latest Struts release, we need to complete the following steps to prepare for the remainderof the text. We will have to complete these steps for each Struts Web application that we intend to deploy. 1. Uncompress the Struts archive to our local disk. 130

2. Create a new Web application directory structure. For our example, the name of our Web application is wileystruts. 3. Copy the following JAR files, extracted from the Jakarta Struts archive, to the wileystruts/WEB-INF/lib directory: struts.jar commons-beanutils.jar commons-collections.jar commons-dbcp.jar commons-digester.jar commons-logging.jar commons-pool.jar commons-services.jar commons-validator.jar 4. Create an empty web.xml file, and copy it to the wileystruts/WEB-INF/ directory. A sample web.xml file is shown in the following code snippet: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"> <web-app> </web-app> 5. Create a basic strut-config.xml file, and copy it to the wileystruts/WEB-INF/ directory. The struts-config.xml file is the deployment descriptor for Struts applications. It is the file that glues all of the MVC (Model-View-Controller) components together. Its normal location is in the WEB-INF/ directory. We will be using this file extensively throughout the remainder of this text. An empty struts-config.xml file is listed here:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/strutsconfig_1_1.dtd"> <struts-config> <message-resources parameter="wiley.ApplicationResources"/> </struts-config>

At this point, we have all of the necessary components to build the simplest of Struts applications. As we begin the design and development of our Struts application, we will need to install and configure further Struts components as necessary. In the next section, we take we through the steps that must be accomplished when developing a Struts application.

131

Creating First Struts Application


Now that we have Struts downloaded and installed, we can begin the development of our own sample Struts application. Our application consists of a simple set of JSP screens that queries a user for a stock symbol, performs a simple stock lookup, and returns the current price of the submitted stock. We will use this example to describe the steps that must be performed when creating any Struts application. Because Struts is modeled after the MVC design pattern, we can follow a standard development process for all of our Struts Web applications. This process begins with the identification of the application Views, the Controller objects that will service those Views, and the Model components being operated on. This process can be described using the following steps: Define and create all of the Views, in relation to their purpose, that will represent the user interface of our application. Add all ActionForms used by the created Views to the strutsconfig.xml file. 1. 2. 3. 4. 5. Create the components of the applications Controller. Define the relationships that exist between the Views and the Controllers (strutsconfig.xml). Make the appropriate modifications to the web.xml file; describe the Struts components to the Web application. Run the application. These steps provide a high-level description of the Struts development process. In the sections that follow, we will describe each of these steps in much greater detail.

Creating the Views


When creating Views in a Struts application, we are most often creating JSPs that are a combination of JSP/HTML syntax and prepackaged Struts tag libraries. The JSP/HTML syntax is similar to any other Web page and does not merit discussion, but the specialized Struts custom tag libraries do. Currently, there are three major Struts tag libraries: Bean, HTML, and Logic. To begin the development of our application, we need to first describe the Views that will represent the user interface of our application. Two Views are associated with our sample application: index.jsp and quote.jsp. The Index View The Index View, which is represented by the file index.jsp, is our starting View. It is the first page our application users will see, and its purpose is to query the user for a stock symbol and submit the inputted symbol to the appropriate action. The source for index.jsp is
index.jsp. <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <html> <head>

132

<title>Wiley Struts Application</title> </head> <body> <table width="500" border="0" cellspacing="0" cellpadding="0"> <tr> <td>&nbsp;</td> </tr> <tr bgcolor="#36566E"> <td height="68" width="48%"> <div align="left"> <img src="images/hp_logo_wiley.gif" width="220" height="74"> </div> </td> </tr> <tr> <td>&nbsp;</td> </tr> </table> <html:form action="Lookup" name="lookupForm" type="wiley.LookupForm" > <table width="45%" border="0"> <tr> <td>Symbol:</td> <td><html:text property="symbol" /></td> </tr> <tr> <td colspan="2" align="center"><html:submit /></td> </tr> </table> </html:form> </body> </html>

As we look over the source for the Index View, we will notice that it looks much like any other HTML pagecontaining a form used to gather data, with the exception of the actual form tags. Instead of using the standard TML Form tag, like most HTML pages, the index.jsp uses a Strutsspecific Form tag: <html:form />. This tag, with its child tags, encapsulates Struts form processing. The form tag attributes used in this example are
action :- Represents the URL to which this form will be submitted. This attribute is also

used to find the appropriate ActionMapping in the Struts configuration file, which we will describe later in this section. The value used in our example is Lookup, which will map to an ActionMapping with a path attribute equal to Lookup. name :- Identifies the key that the ActionForm will be referenced by. We use the value LookupForm. An ActionForm is an object that is used by Struts to represent the form data as a JavaBean. It main purpose is to pass form data between View and Controller components.

133

type :- Names the fully qualified class name of the form bean to use in this request. For this example, we use the value wiley.LookupForm, which is an ActionForm object containing data members matching the inputs of this form. This instance of the <html:form /> tag is also the parent to two other HTML tags. The first of the tags is the <html:text /> tag. This tag is synonymous with the HTML text input tag; the only difference is the property attribute, which names a unique data member found in the ActionForm bean class named by the forms type attribute. The named data member will be set to the text value of the corresponding input tag. The second HTML tag that we use is the <html:submit /> tag. This tag simply emulates an HTML submit button. The net effect of these two tags is Upon submission, the ActionForm object named by the <html:form /> tag will be created, populated with the value of the <html:text /> tags, and stored in the session. Once the ActionForm object is populated with the appropriate values, the action referenced by the <html:form /> will be invoked and passed a reference to the populated ActionForm. To use the previous two HTML tags, we must first add a taglib entry in the wileystruts applications web.xml file that references the URI /WEB-INF/struts-html.tld. This TLD describes all of the tags in the HTML tag library. The following snippet shows the <taglib> element that must be added to the web.xml file:
<taglib> <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib>

Second, we must copy the struts-html.tld from the lib directory of the extracted Struts archive to the wileystruts/ WEB_INF/ directory. Note The previous two steps are used to deploy all of the Struts tag libraries. The only difference between each library's deployment is the name of the TLD. The ActionForm The ActionForm used in this example contains a single data member that maps directly to the symbol input parameter of the form defined in the Index View. As I stated in the previous section, when an <html:form /> is submitted, the Struts framework populates the matching data members of the ActionForm with the values entered into the <html:input /> tags. The Struts framework does this by using JavaBean reflection; therefore, the accessors of the ActionForm must follow the JavaBean standard naming convention. An example of this naming convention is shown here: private String symbol; public void setSymbol(String symbol); 134

public String getSymbol(); In this example, we have a single data member symbol. To satisfy the JavaBean standard, the accessors used to set the data member must be prefixed with set and get, followed by the data member name with its first letter capitalized. Next Listing contains the source for our ActionForm. Listing: The LookupForm implementation LookupForm.java.
package wiley; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; public class LookupForm extends ActionForm { private String symbol = null; public String getSymbol() { return (symbol); } public void setSymbol(String symbol) { this.symbol = symbol; } public void reset(ActionMapping mapping, HttpServletRequest request) { this.symbol = null; } }

There is really nothing special about this class. It is a simple bean that extends org.apache.struts.action.ActionForm, as must all ActionForm objects, with get and set accessors that match each of its data members. It does have one method that is specific to an ActionForm bean: the reset() method. The reset() method is called by the Struts framework with each request that uses the LookupForm. The purpose of this method is to reset all of the LookupForms data members and allow the object to be pooled for reuse. To deploy the LookupForm to our Struts application, we need to compile this class, move it to the wileystruts/WEB-INF/classes/wiley directory, and add the following line to the <formbeans> section of the wileystruts/WEB-INF/struts-config.xml file: <form-bean name="lookupForm" type="wiley.LookupForm"/> This entry makes the Struts application aware of the LookupForm and how it should be referenced.

The Quote View


The last of our Views is the quote.jsp. This View is presented to the user upon successful stock symbol lookup. It is a very simple JSP with no Struts specific functionality. Next Listing contains its source. Listing: quote.jsp. 135

<html> <head> <title>Wiley Struts Application</title> </head> <body> <table width="500" border="0" cellspacing="0" cellpadding="0"> <tr> <td>&nbsp;</td> </tr> <tr bgcolor="#36566E"> <td height="68" width="48%"> <div align="left"> <img src="images/hp_logo_wiley.gif" width="220" height="74"> </div> </td> </tr> <tr> <td>&nbsp;</td> </tr> <tr> <td>&nbsp;</td> </tr> <tr> <td>&nbsp;</td> </tr> <tr> <td> Current Price : <%= request.getAttribute("PRICE") %> </td> </tr> <tr> <td>&nbsp;</td> </tr> </table> </body> </html>

As we look over this JSP, we will notice that it contains a single JSP functional line of code. This line of code retrieves the current price from the HttpServletRequest of the submitted stock symbol. This value is placed in the HttpServletRequest by the Action object that services this request, as shown in the next section.

Creating the Controller Components


In a Struts application, two components make up the Controller. These two components are the org.apache.struts.action.ActionServlet and the org.apache. struts.action.Action classes. In most Struts applications, there is one org. apache.struts.action.ActionServlet implementation and many org.apache.struts.action.Action implementations. The org.apache.struts.action.ActionServlet is the Controller component that handles client requests and determines which org.apache.struts.action.Action will process the received request. 136

When assembling simple applications, such as the one we are building, the default ActionServlet will satisfy our application needs, and therefore,we do not need to create a specialized org.apache.struts.action.ActionServlet implementation. When the need arises, however, it is a very simple process. For our example, we will stick with the ActionServlet as it is delivered in the Struts packages. The second component of a Struts Controller is the org.apache.struts. action.Action class. As opposed to the ActionServlet, the Action class must be extended for each specialized function in our application. This class is where our applications specific logic begins. For our example, we have only one process to perform: looking up the value of the submitted stock symbol. Therefore, we are going to create a single org.apache.struts.action.Action bean named LookupAction. The source for our Action is shown in next Listing. As we examine this listing, be sure to pay close attention to the execute() method. Listing: The LookupAction bean.
package wiley; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class LookupAction extends Action { protected Double getQuote(String symbol) { if ( symbol.equalsIgnoreCase("SUNW") ) { return new Double(25.00); } return null; } public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { Double price = null; // Default target to success String target = new String("success"); if ( form != null ) { // Use the LookupForm to get the request parameters LookupForm lookupForm = (LookupForm)form; String symbol = lookupForm.getSymbol(); price = getQuote(symbol); } // Set the target to failure if ( price == null ) { target = new String("failure"); } else {

137

request.setAttribute("PRICE", price); } // Forward to the appropriate View return (mapping.findForward(target)); } }

After examining this class, we will notice that it extends the org.apache.struts.action.Action class and contains two methods: getQuote() and execute(). The getQuote() method is a simple method that will return a fixed price (if SUNW is the submitted symbol). The second method is the execute() method, where the main functionality of the LookupAction is found. This is the method that must be defined by all Action class implementations. Before we can examine how the logic contained in the execute() method works, we need to examine the four parameters passed to it. These parameters are ActionMapping:The ActionMapping class contains all of the deployment information for a particular Action bean. This class will be used to determine where the results of the LookupAction will be sent once its processing is complete. The ActionForm represents the form inputs containing the request parameters from the View referencing this Action bean. The reference being passed to our LookupAction points to an instance of our LookupForm.

ActionForm:-

HttpServletRequest:- The HttpServletRequest attribute is a reference to the current HTTP request object. HttpServletResponse:- The HttpServletResponse is a reference to the current HTTP response object. Now that we have described the parameters passed to the execute() method, we can move on to describing the actual method body. The first notable action taken by this method is to create a String object named target with a value of success. This object will be used to determine the View that will present successful results of this action. The next step performed by this method is to get the request parameters contained in the LookupForm. When the form was submitted, the ActionServlet used Javas reflection mechanisms to set the values stored in this object. We should note that the reference passed to the execute() method is an ActionForm that must be cast to the ActionForm implementation used by this action. The following code snippet contains the source used to access the request parameters:

138

// Use the LookupForm to get the request parameters LookupForm lookupForm = (LookupForm)form; String symbol = lookupForm.getSymbol(); Once we have references to the symbol parameters, we pass these values to the getQuote() method. This method is a simple user-defined method that will return the Double value 25.00. If the symbol String contains any values other than SUNW, then null is returned, and we change the value of our target to failure. This will have the effect of changing the targeted View. If the value was not null, then we add the returned value to the request with a key of PRICE. At this point, the value of target equals either success or failure. This value is then passed to the ActionMapping.findForward() method, which returns an ActionForward object referencing the physical View that will actually present the results of this action. The final step of the execute() method is to return the ActionForward object to the invoking ActionServlet, which will then forward the request to the referenced View for presentation. This step is completed using the following line of code: return (mapping.findForward(target)); To deploy the LookupAction to our Struts application, we need to compile the LookupAction class, move the class file to the wileystruts/WEB-INF/classes/wiley directory, and add the following entry to the <action-mappings> section of the wileystruts/ WEB-INF/strutsconfig.xml file:
<action path="/Lookup" type="wiley.LookupAction" name="lookupForm" input="/index.jsp"> <forward name="success" path="/quote.jsp"/> <forward name="failure" path="/index.jsp"/> </action>

This entry contains the data that will be stored in the ActionMapping object that is passed to the execute() method of the LookupAction. It contains all of the attributes required to use this instance of the LookupAction, including a collection of keyed <forward> subelements representing the possible Views that can present the results of the LookupAction.

Deploying our Struts Application


Now we have all of the necessary Struts components deployed and modified. Next, we need to tell the Web application itself about our application components. To do this, we must make some simple changes to the web.xml file. The first change we must make is to tell the Web application about our ActionServlet. This is accomplished by adding the following servlet definition to the wileystruts/WEBINF/web.xml file:
<servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet

139

</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>

This entry tells the Web application that we have a servlet named action that is implemented by the class org.apache.struts.action.ActionServlet, which, as we stated earlier, is the default ActionServlet provided with Struts. The entry defines a single servlet initialization parameter, config, that tells the ActionServlet where to find the struts-config.xml file. It also includes a load-on-startup element that tells the JSP/servlet container that we want this servlet to be preloaded when the Web application starts. We must pre-load the ActionServlet, or our Struts Views will not load all of their necessary resources. Once we have told the container about the ActionServlet, we need to tell it when the action should be executed. To do this, we have to add a <servlet-mapping> element to the wileystruts/WEB-INF/ web.xml file:
<servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>

Note We will notice in the previously listed index.jsp that our action does not include a .do at the end of the URL. We do not have to append the .do because it is automatically appended if we use the <html:form /> tag. If we do not use the <html:form /> tag, then we will need to append .do to the action's URL. This mapping tells the Web application that whenever a request is received with .do appended to the URL, the servlet named action should service the request.

Walking through the wileystruts Web Application


At this point, we should have completed all of the steps described in the previous section and have a deployed wileystruts Web application. In this section, we will go through this sample application and discuss each of the steps performed by Struts along the way. The purpose of this section is to provide a walkthrough that ties together all of the previously assembled components. To begin using this application, we need to restart Tomcat and open Web browser to the following URL:http://localhost:8080/wileystruts/ If everything went according to plan, we should see a page similar

140

When this page loads, the following actions occur: 1. The <html:form> creates the necessary HTML used to represent a form and then checks for an instance of the wiley.LookupForm in session scope. If there was an instance of the wiley.LookupForm, then the value stored in the ActionForms data member will be mapped to the input element value on the form and the HTML form will be written to the response. This is a very handy technique that can be used to handle errors in form data. 2. The Index View is then presented to the user. To move on to the next step, enter the value SUNW into the Symbol text box, and click the Submit button. This will invoke the following functionality: 3. The Submit button will cause the browser to invoke the URL named in the <html:form /> tags action attribute, which in this case is Lookup. When the JSP/servlet container receives this request, it looks in the web.xml file for a <servlet-mapping> with a <urlpattern> that ends with .do. It will find the following entry, which tells the container to send the request to a servlet that has been deployed with a <servlet-name> of action:
<!-- Standard Action Servlet Mapping --> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>

4. The container will find the following <servlet> entry with a <servlet-name> of action that points to the ActionServlet, which acts as the Controller for our Struts application:
<servlet> <servlet-name>action</servlet-name> <servlet-class> org.apache.struts.action.ActionServlet </servlet-class> </servlet>

141

5. The ActionServlet then takes over the servicing of this request by retrieving the previously created LookupForm, populating its symbol data member with the value passed on the request, and adding the LookupForm to the session with a key of lookupForm. 6. At this point, the ActionServlet looks for an <ActionMapping> entry in the struts-config.xml file with a <path> element equal to Lookup. It finds the following entry:
<action path="/Lookup" type="wiley.LookupAction" name="lookupForm" input="/index.jsp"> <forward name="success" path="/quote.jsp"/> <forward name="failure" path="/index.jsp"/> </action>

7. It then creates an instance of the LookupAction class named by the type attribute. It also creates an ActionMapping class that contains all of the values in the <ActionMapping> element. Note The Struts framework does pool instances of Action classes; therefore, if the wiley.LookupAction had already been requested, then it will be retrieved from the instance pool as opposed to being created with every request. 8. It then invokes the LookupAction.execute() with the appropriate parameters. The LookupAction.execute() method performs its logic, and calls the ActionMapping.findForward() method with a String value of either success or failure. 9. The ActionMapping.findForward() method looks for a <forward> subelement with a name attribute matching the target value. It then returns an ActionForward object containing the results of the lookup, which is the value of the path attribute /quote.jsp (upon success) or /index.jsp (upon failure). 10. The LookupAction then returns the ActionForward object to the ActionServlet, which in turn forwards the request object to the targeted View for presentation. The results of a successful transaction are shown in Figure. Figure : The wileystruts Quote View.

142

Note: If we submit any value other than SUNW, we will be sent back index.jsp, which is the failure path of the LookupAction. If this does happen, we will see that the input value on the index page is prepopulated with our originally submitted value. This is one of the handy errorhandling techniques provided by the Struts application.

8.3 Controller
In this chapter, we dig further into the Controller components of the Struts framework. We begin by looking at three distinct Struts Controller components, including the ActionServlet class, the Action class, Plugins, and the RequestProcesser. The goal of this chapter is to provide a solid understanding of the Struts Controller components, and how they can be used and extended to create a robust and easily extended Web application.

The ActionServlet Class


The org.apache.struts.action.ActionServlet is the backbone of all Struts applications. It is the main Controller component that handles client requests and determines which org.apache.struts.action.Action will process each received request. It acts as an Action factory by creating specific Action classes based on the users request. While the ActionServlet sounds as if it might perform some extraordinary magic, it is a simple servlet. Just like any other HTTP servlet, it extends the class javax.servlet.http.HttpServlet and implements each of the HttpServlets life-cycle methods, including the init(), doGet(), doPost(), and destroy() methods. The special behavior begins with the ActionServlets process() method. The process() method is the method that handles all requests. It has the following method signature:
protected void process(HttpServletRequest request, HttpServletResponse response);

When the ActionServlet receives a request, it completes the following steps:

143

1. The doPost() or doGet() methods receive a request and invoke the process() method. 2. The process() method gets the current RequestProcessor, and invokes its process() method. Note: If we intend to extend the ActionServlet, the most logical place for customization is in the RequestProcessor object. It contains the logic that the Struts controller performs with each request from the container. 3. The RequestProcessor.process() method is where the current request is actually serviced. The RequestProcessor.process() method retrieves, from the struts-config.xml file, the <action> element that matches the path submitted on the request. It does this by matching the path passed in the <html:form /> tags action element to the <action> element with the same path value. An example of this match is shown below:
<html:form action="/Lookup" name="lookupForm" type="wiley.LookupForm" > <action path="/Lookup" type="wiley.LookupAction" name="lookupForm" > <forward name="success" path="/quote.jsp"/> <forward name="failure" path="/index.jsp"/> </action>

4. When the RequestProcessor.process() method has a matching <action>, it looks for a <form-bean> entry that has a name attribute that matches the <action> elements name attribute. The following code snippet contains a sample match:
<form-beans> <form-bean name="lookupForm" type="wiley.LookupForm"/> </form-beans> <action path="/Lookup" type="wiley.LookupAction" name="lookupForm" > <forward name="success" path="/quote.jsp"/> <forward name="failure" path="/index.jsp"/> </action>

5. When the RequestProcessor.process() method knows the fully qualified name of the FormBean, it creates or retrieves a pooled instance of the ActionForm named by the <form-bean> elements type attribute, and populates its data members with the values submitted on the request. 6. After the ActionForms data members are populated, the RequestProcessor.process() method calls the ActionForm.validate() method, which checks the validity of the submitted values. 7. At this point, the RequestProcessor.process() method knows all that it needs to know, and it is time to actually service the request. It does this by retrieving the fully qualified name of the Action class from the <action> elements type attribute, creating or retrieving the named class, and calling the Action.execute() method.

144

8. When the Action class returns from its processing, its execute() method returns an ActionForward object that is used to determine the target of this transaction. The RequestProcessor.process() method resumes control, and the request is then forwarded to the determined target. 9. At this point, the ActionServlet instance has completed its processing for this request and is ready to service future requests.

Extending the ActionServlet


Now that we have seen what the ActionServlet is and how it is configured, lets look at how it can be extended to provide additional functionality. As we might have guessed, there are several different ways in which the ActionServlet can be extended, and we are going to examine just one of them. This examination, however, should provide the foundation we need to extend the ActionServlet for our own uses. To develop our own ActionServlet, we must complete the following four steps. We will perform each of these steps when creating our custom ActionServlet. 1. Create a class that extends the org.apache.struts.action.ActionServlet class. 2. Implement the methods specific to our business logic. 3. Compile the new ActionServlet and move it into the Web applications classpath. 4. Add a <servlet> element to the applications web.xml file; name the new ActionServlet as the mapping to the .do extension. In the 1.0x version of Struts, this was very common method of extending the ActionServlet. As of Struts 1.1, it is more appropriate to extend a RequestProcessor to modify the default ActionServlet processing.

Configuring the ActionServlet


Now that we have a solid understanding of how the ActionServlet performs its duties, lets take a look at how it is deployed and configured. The ActionServlet is like any other servlet and is configured using a web.xml <serlvet> element. We can take many approaches when setting up an ActionServlet. We can go with a bare-bones approach or we can get more serious and include any combination of the available initialization parameters described -The Initialization Parameters of the ActionServlet bufferSize Config : : Names the size of the input buffer used when uploading files. The default value is 4096 bytes. (optional) Names the context-relative path to the struts-config.xml file. The default location is in the /WEB-INF/struts-config.xml directory. (optional)

145

Content debug detail factory In most cases, (optional) locale (optional) mapping

: : : :

Names the content type and character encoding to be set on each response. The default value is text/html. (optional) Determines the debugging level for the ActionServlet. The default value is 0, which turns debugging off. (optional) Sets the debug level for the Digester object, which is used during ActionServlet initialization. The default value is 0. (optional) Names the fully qualified class name of the object used to create the application's MessageResources object. The default value is org.apache.struts.util.PropertyMessageResourcesFactory. the default class will handle our application needs. If set to true and the requesting client has a valid session, then the Locale object is stored in the user's session bound to the key Action.LOCALE_KEY. The default value is true.

Names the fully qualified class name of the ActionMapping implementation used to describe each Action deployed to this application. The default value is org.apache.struts.action.ActionMapping. We will create our own ActionMapping extension in Chapter 8, "Creating Custom ActionMappings." (optional) maxFileSize : 250M. multipartClass: Names the maximum file size (in bytes) of a file to be uploaded to a Struts application. This value can be expressed using K, M, or G, understood as kilobytes, megabytes, or gigabytes, respectively. The default size is (optional)

Names the fully qualified class of the MultipartRequestHandler implementation to be used when file uploads are being processed. The default value is org.apache.struts.upload.DiskMultipartRequestHandler. (optional) nocache : If set to true, will add the appropriate HTTP headers to every response, turning off browser caching. This parameter is very useful when browser is not reflecting our application changes. The false. (optional) If set to true, will cause the Struts application resources to return null, as opposed to an error message, if it cannot find the requested key in application resource bundle. The default value for this parameter is (optional)

the client default value is null the true. :

146

tempDir hosting validate (optional) validating is

Names a directory to use as a temporary data store when file uploads are being processed. The default value is determined by the container the application. (optional) If set to true, tells the ActionServlet that we are using the configuration file format defined as of Struts 1.0. The default value is true. If set to true, tells the ActionServlet that we want to validate the strutconfig.xml file against its DTD. While this parameter is optional, it highly recommended, and therefore the default is set to true.

While none of these initialization parameters are required, the most common ones include the config, application, and mapping parameters. It is also common practice to use a <load-onstartup> element to ensure that the ActionServlet is started when the container starts the Web application. An example <serlvet> entry, describing an ActionServlet, is shown in the following code snippet:
<servlet> <servlet-name>action</servlet-name> <servlet-class> org.apache.struts.action.ActionServlet </servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>mapping</param-name> <param-value>wiley.WileyActionMapping</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>

The Action Class


The second component of a Struts Controller is the org.apache.struts.action. Action class must and will be extended for each specialized Struts function in our application. The collection of the Action classes that belong to our Struts application is what defines our Web application. To begin our discussion of the Action class, we must first look at some of the Action methods that are more commonly overridden or leveraged when creating an extended Action class. The following sections describe five of these methods.

The execute() Method


The execute() method is where our application logic begins. It is the method that we need to override when defining our own Actions. The Struts framework defines two execute() methods. 147

The first execute() implementation is used when we are defining custom Actions that are not HTTP-specific. This implementation of the execute() method would be analogous to the javax.serlvet.GenericServlet class. The signature of this execute() method is public ActionForward execute(ActionMapping mapping,ActionForm form,ServletRequest request,ServletResponse response) throws IOException, ServletException We will notice that this method receives, as its third and fourth parameter, a ServletRequest and a ServletResponse object, as opposed to the HTTP-specific equivalents HttpServletRequest and HttpServletResponse. The second execute() implementation is used when we are defining HTTP- specific custom Actions. This implementation of the execute() method would be analogous to the javax.serlvet.http.HttpServlet class. The signature of this execute() method is public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException We will notice that this method receives, as its third and fourth parameter, a HttpServletRequest and a HttpServletResponse object, as opposed to the previously listed execute() method. This implementation of the execute() method is the implementation that we will most often extend. Parameters of the Action.execute() method. ActionMapping of the ActionForm LoginForm. HttpServletRequest : HttpServletResponse Is a reference to the current HTTP request object. : Is a reference to the current HTTP response object. : : Contains all of the deployment information for a particular Action bean. This class will be used to determine where the results LoginAction will be sent after its processing is complete. Represents the Form inputs containing the request parameters from the View referencing this Action bean. The reference being passed to our LoginAction points to an instance of our

Extending the Action Class


Now that we have seen the Action class and some of its configuration options, lets see how we can create our own Action class. To develop our own Action class, we must complete the following steps. These steps describe the minimum actions that must be completed when creating a new Action:

148

1. 2. 3. 4.

Create a class that extends the org.apache.struts.action.Action class. Implement the appropriate execute() method and our specific to our business logic. Compile the new Action and move it into the Web applications classpath. Add an <action> element to the applications struts-config.xml file describing the new Action.

An example execute() implementation is listed in the following snippet. We will be extending the Action class throughout the remainder of this text.
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { Double price = null; // Default target to success String target = new String("success"); if ( form != null ) { // Use the LookupForm to get the request parameters LookupForm lookupForm = (LookupForm)form; String symbol = lookupForm.getSymbol(); price = getQuote(symbol); } // Set the target to failure if ( price == null ) { target = new String("failure"); } else { request.setAttribute("PRICE", price); } // Forward to the appropriate View return (mapping.findForward(target)); }

Configuring the Action Class


Now that we have seen the major methods of the Action class, lets examine its configuration options. The Action class is a Struts-specific object, and therefore must be configured using the struts-config.xml file. The element that is used to configure a Struts action is an <action> element. The class that defines the <action> elements attributes is the org.apache. struts.action.ActionMappings class. Next Table describes the attributes of an <action> element as they are defined by the default ActionMappings class. Note When using an <action> element to describe an Action class, we are describing only one instance of the named Action class. There is nothing stopping we from using n-number of <action> elements that describe the same Action class. The only restriction is that the path attribute must be unique for each <action> element. Path : Represents the context-relative path of the submitted request. The path must be unique and start with a / character. (required)

149

type include or name scope input is the className the the forward if no include if no validate not

: : : :

Names the fully qualified class name of the Action class being described by this ActionMapping. The type attribute is valid only if no forward attribute is specified. (optional) Identifies the name of the form bean, if any, that is coupled with the Action being defined. (optional) Names the scope of the form bean that is bound to the described Action. The default value is session. (optional) Names the context-relative path of the input form to which control should be returned if a validation error is encountered. The input attribute where control will be returned if ActionErrors are returned from ActionForm or Action objects. (optional) Names the fully qualified class name of the ActionMapping implementation class to use in when invoking this Action class. If className attribute is not included, the ActionMapping defined in ActionServlet's mapping initialization parameter is used. (optional) Represents the context-relative path of the servlet or JSP resource that will process this request. This attribute is used if we do not want an Action to service the request to this path. The forward attribute is valid only include or type attribute is specified. (optional) Represents the context-relative path of the servlet or JSP resource that will process this request. This attribute is used if we do not want an Action to service the request to this path. The include attribute is valid only forward or type attribute is specified. (optional) If set to true, causes the ActionForm.validate() method to be called on the form bean associated to the Action being described. If the validate attribute is set to false, then the ActionForm.validate() method is called. The default value is true. (optional)

A sample <action> subelement using some of the previous attributes is shown here:
<action-mappings> <action path="/Lookup" type="wiley.LookupAction" name="lookupForm" input="/index.jsp"> <forward name="success" path="/quote.jsp"/> <forward name="failure" path="/index.jsp"/> </action> </action-mappings>

This <action> element tells the ActionServlet the following things about this Action instance:

150

The Action class is implemented by the wiley.LookupAction class This Action should be invoked when the URL ends with the path /Lookup. This Action class will use the <form-bean> with the name lookupForm. The originating resource that submitted the request to this Action is the JSP index.jsp. This Action class will forward the results of its processing to either the quote.jsp or the index.jsp.

The previous <action> element uses only a subset of the possible <action> element attributes, but the attributes that it does use are some of the more common.

Struts Plugins
Struts Plugins are modular extensions to the Struts Controller. They have been introduced in Struts 1.1, and are defined by the org.apache.struts.action.Plugin interface. Struts Plugins are useful when allocating resources or preparing connections to databases or even JNDI resources. We will look at an example of loading application properties on startup later in this section. This interface, like the Java Servlet architecture, defines two methods that must be implemented by all used-defined Plugins: init() and destroy(). These are the life-cycle methods of a Struts Plugin.

init()
The init() method of a Struts Plugin is called whenever the JSP/Servlet container starts the Struts Web application containing the Plugin. It has a method signature as follows: public void init(ApplicationConfig config) throws ServletException; This method is convenient when initializing resources that are important to their hosting applications. As we will have noticed, the init() method receives an ApplicationConfig parameter when invoked. This object provides access to the configuration information describing a Struts application. The init() method marks the beginning of a Plugins life.

destroy()
The destroy() method of a Struts Plugin is called whenever the JSP/Servlet container stops the Struts Web application containing the Plugin. It has a method signature as follows: public void destroy(); This method is convenient when reclaiming or closing resources that were allocated in the Plugin.init() method. This method marks the end of a Plugins life.

Creating a Plugin

151

Now that we have discussed what a Plugin is, lets look at an example Plugin implementation. As we stated earlier, all Plugins must implement the two Plugin methods init() and destroy(). To develop our own Plugin, we must complete the following steps. These steps describe the minimum actions that must be completed when creating a new Plugin: 1. Create a class that implements the org.apache.struts.action.Plugin interface. 2. Add a default empty constructor to the Plugin implementation. We must have a default constructor to ensure that our Plugin is properly created by the ActionServlet. 3. Implement both the init() and destroy() methods and our implementation. 4. Compile the new Plugin and move it into the Web applications classpath. 5. Add an <plug-in> element to the applications struts-config.xml file describing the new Plugin. 5. An example Plugin implementation is listed in the following snippet. package wiley; import java.util.Properties; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.ServletContext; import org.apache.struts.action.PlugIn; import org.apache.struts.config.ApplicationConfig; import org.apache.struts.action.ActionServlet; public class WileyPlugin implements PlugIn { public static final String PROPERTIES = "PROPERTIES"; public WileyPlugin() { } destroy() public void init(ActionServlet servlet, ApplicationConfig applicationConfig) throws javax.servlet.ServletException { System.err.println("---->The Plugin is starting<----"); Properties properties = new Properties(); try { // Build a file object referening the properties file // to be loaded File file = new File("PATH TO PROPERTIES FILE"); // Create an input stream FileInputStream fis = new FileInputStream(file); // load the properties properties.load(fis); // Get a reference to the ServletContext ServletContext context = 152

servlet.getServletContext(); // Add the loaded properties to the ServletContext // for retrieval throughout the rest of the Application context.setAttribute(PROPERTIES, properties); } catch (FileNotFoundException fnfe) { throw new ServletException(fnfe.getMessage()); } catch (IOException ioe) { throw new ServletException(ioe.getMessage()); } } public void destroy() { // We don't have anything to clean up, so // just log the fact that the Plugin is shutting down System.err.println("---->The Plugin is stopping<----"); } } As we look over our example Plugin, we will see just how straightforward Plugin development can be. In this example, we create a simple Plugin that extends the init() method, which contains the property loading logic, and the destroy() method, which contains no specialized implementation. The purpose of this Plugin is to make a set of properties available upon application startup. To make the wiley.WileyPlugin available to we Struts application, we need to move on to the following section on Plugin configuration.

Configuring a Plugin
Now that we have seen a Plugin and understand how they can be used, lets take a look at how a Plugin is deployed and configured. To deploy and configure our wiley.WileyPlugin, we must 1. Compile and move the Plugin class file into the classpath. 2. Add a <plug-in> element to our struts-config.xml file. An example <plug-in> entry, describing the previously defined Plugin, is shown in the following code snippet: <plug-in className="wiley.WileyPlugin"/> Note The <plug-in> element must follow all <message-resources /> elements in the strutsconfig.xml. 3.Restart the Struts Web application. When this deployment is complete, this Plugin will begin its life when the hosting application restarts.

The RequestProcessor

153

As we stated previously, the org.apache.struts.action.RequestProcessor contains the logic that the Struts controller performs with each servlet request from the container. The RequestProcessor is the class that we will want to override when we want to customize the processing of the ActionServlet.

Creating a New RequestProcessor


Now that we have discussed what the RequestProcessor is, lets look at an example Plugin implementation. The RequestProcessor contains n-number of methods that we can override to change the behavior of the ActionServlet.

To create our own RequestProcessor, we must follow the steps described in the following list: 1. Create a class that extends the org.apache.struts.action.RequestProcessor class. 2.Add a default empty constructor to the RequestProcessor implementation. 3.Implement the method that we want to override. Our example overrides the processPreprocess() method. In our example, we are going to override one of the more useful RequestProcessor methods, the processPreprocess() method, to log information about every request being made to our application. The processPreprocess() method is executed prior to the execution of every Action.execute() method. It allows we to perform application-specific business logic before every Action. The method prototype for the processPreprocess() method is shown below: protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) The default implementation of the processPreprocess() method simply returns true, which tells the framework to continue its normal processing. we must return true from our overridden processPreprocess() method if we want to continue processing the request. Note If we do choose to return false from the processPreprocess() method, then the RequestProcessor will stop processing the request and return control back to the doGet() or doPost() of the ActionServlet. To see how all of this really works, take a look at our example RequestProcessor implementation, which is listed in the following snippet. package wiley; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import java.io.IOException;

154

import java.util.Enumeration; import org.apache.struts.action.RequestProcessor; public class WileyRequestProcessor extends RequestProcessor { public WileyRequestProcessor() { } public boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) { log("----------processPreprocess Logging--------------"); log("Request URI = " + request.getRequestURI()); log("Context Path = " + request.getContextPath()); Cookie cookies[] = request.getCookies(); if (cookies != null) { for (int i = 0; i < cookies.length; i++) { log("Cookie = " + cookies[i].getName() + " = " + cookies[i].getValue()); } } Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = (String) headerNames.nextElement(); Enumeration headerValues = request.getHeaders(headerName); while (headerValues.hasMoreElements()) { String headerValue = (String) headerValues.nextElement(); log("Header = " + headerName + " = " + headerValue); } } log("Locale = " + request.getLocale()); log("Method = " + request.getMethod()); log("Path Info = " + request.getPathInfo()); log("Protocol = " + request.getProtocol()); log("Remote Address = " + request.getRemoteAddr()); log("Remote Host = " + request.getRemoteHost()); log("Remote User = " + request.getRemoteUser()); log("Requested Session Id = " + request.getRequestedSessionId()); log("Scheme = " + request.getScheme()); log("Server Name = " + request.getServerName()); log("Server Port = " + request.getServerPort()); log("Servlet Path = " + request.getServletPath()); log("Secure = " + request.isSecure()); log("-------------------------------------------------"); return true; } }

155

In our processPreprocess() method, we are retrieving the information stored in the request and logging it to the ServletContext log. Once the logging is complete, the processPreprocess() method returns the Boolean value true, and normal processing continues. If the processPreprocess() method had returned false, then the ActionServlet would have terminated processing, and the Action would never have been performed.

Configuring an Extended RequestProcessor


Now that we have seen a Plugin and understand how it can be used, lets take a look at how a Plugin is deployed and configured. To deploy and configure our wiley.WileyPlugin, we must 1.Compile the new RequestProcessor and move it into the Web applications classpath. 2.Add a <controller> element to the applications struts-config.xml file describing the new RequestProcessor. An example <controller> entry, describing the our new RequestProcessor, is shown in the following code snippet: <controller processorClass="wiley.WileyRequestProcessor" /> Note The <controller> element must follow the <action-mappings> element and precede the <message-resources /> elements in the struts-config.xml. 1. Restart the Struts Web application. When this deployment is complete, the new RequestProcessor will take effect.

156

8.4 Views
In this chapter, we examine the View component of the Struts framework. Some of the topics that we discuss are using tags from Struts tag libraries, using ActionForms, and deploying Views to a Struts application. The goal of this chapter is to give an understanding of the Struts View and the components that can be leveraged to construct the View. Building a Struts View The Struts View is represented by a combination of JSPs, custom tag libraries, and optional ActionForm objects. In the sections that follow, we examine each of these components and how they can be leveraged. At this point, we should have a pretty good understanding of what JSPs are and how they can be used. We can now focus on how JSPs are leveraged in a Struts application. JSPs in the Struts framework serve two main functions. The first of these functions is to act as the presentation layer of a previously executed Controller Action. This is most often accomplished using a set of custom tags that are focused around iterating and retrieving data forwarded to the target JSP by the Controller Action. This type of View is not Struts-specific, and does not warrant special attention. The second of these functions, which is very much Struts-specific, is to gather data that is equired to perform a particular Controller Action. This is done most often with a combination of tag libraries and ActionForm objects.

Deploying JSPs to a Struts Application

157

Before we can begin looking at the role of a JSP in the Struts framework, we must take a look at how JSPs are deployed to the framework. JSPs are most often the target of a previous request; whether they are gathering or presenting data usually makes no difference as to how they are deployed. All JSPs should be deployed to a Struts application by using a <forward> element. This element is used to define the targets of Struts Actions, as shown in the following code snippet: <forward name="login" path="/login.jsp"/> In this example, the <forward> element defines a View named login with a path of /login.jsp. To make this <forward> element available to a Struts application, we must nest it within one of two possible Struts elements. We can make a JSP available globally to the entire application. This type of JSP deployment is useful for error pages and login pages. We perform this type of deployment by adding the JSP to the <global-forwards> section of the struts-config.xml file. An example of this is shown in the following code snippet: <global-forwards> <forward name="login" path="/login.jsp"/> </global-forwards> The previous <forward> element states that /login.jsp will be the target of all Struts Actions that return an ActionForward instance with the name login, as shown here: return (mapping.findForward("login")); Note The only time that a global forward is not used is when an <action> element has a <forward> declaration with the same name. In this instance, the <action> elements <forward> will take precedence. The second type of <forward> declaration is defined as an Action <forward>. These types of <forward> elements are defined as subelements of an <action> definition, and are accessible only from within that <action>. The following code snippet shows an example of this type of <forward> declaration:
<action path="/Login" type="com.wiley.LoginAction" validate="true" input="/login.jsp" name="loginForm" scope="request" > <forward name="success" path="/employeeList.jsp"/> <forward name="failure" path="/login.jsp"/> </action>

This <forward> definition states that /login.jsp will be the target of com.wiley.LoginAction when this Action returns an ActionForward instance with the name failure, as shown here: return (mapping.findForward("failure")); JSPs that Gather Data 158

Now that we know how JSPs are deployed in a Struts application, lets take a look at one of the two most common uses of a JSP in a Struts application: using JSPs to gather data. There are several methods that can be leveraged when gathering data using a JSP. The most common of these methods includes using the HTML <form> element and any combination of <input> subelements to build a form. While Struts uses this exact methodology, it does so with a set of JSP custom tags that emulate the HTML <form> and <input> elements, but also includes special Struts functionality. The following code snippet contains a JSP that uses the Struts tags to gather data:
<html:form action="/Login" name="loginForm" type="com.wiley.LoginForm" > <table width="45%" border="0"> <tr> <td>Username:</td> <td><html:text property="username" /></td> </tr> <tr> <td>Password:</td> <td><html:password property="password" /></td> </tr> <tr> <td colspan="2" align="center"><html:submit /></td> </tr> </table> </html:form>

If we break this JSP into logical sections, we will first take notice of the four Struts HTML tags: <html:form />, <html:text />, <html:password />, and <html:submit />. These tags include special Struts functionality that is used to gather HTML form data. We look at each of these tags in the sections that follow. Note The Struts library that includes the HTML tags listed in our JSP is named the HTML Tag Library. It includes tags that closely mimic the same functionality common to HTML form elements.

The <html:form /> Tag


The first of these tags is the <html:form /> tag. This tag serves as the container for all other Struts HTML input tags. It renders an HTML <form> element, containing all of the child elements associated with this HTML form. While the <html:form /> tag does serve as an HTML input container, it is also used to store and retrieve the data members of the named ActionForm bean. This tag, with its children, encapsulates the presentation layer of Struts form processing. The form tag attributes used in this example are :-

159

action :- Represents the URL to which this form will be submitted. This attribute is also used to find the appropriate ActionMapping in the Struts configuration file, which we describe later in this section. The value used in our example is /Login, which will map to an ActionMapping with a path attribute equal to /Login. name :- Identifies the key that the ActionForm that we will be using in this request to identify the FormBean associated with this Form. We use the value loginForm. ActionForms are described in the following section . type:- Provides the fully qualified class name of the ActionForm bean used in this request. For this example, we use the value com.wiley.LoginForm, which is described following.

ActionForm Beans
Before we can move on to examining the rest of this form, we must discuss the org.apache.struts.action.ActionForm object. ActionForms are JavaBeans that are used to encapsulate and validate the request parameters submitted by an HTTP request. A sample ActionForm, named LoginForm, is listed in the following code snippet:
package com.wiley; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionError; public class LoginForm extends ActionForm { private String password = null; private String username = null; public String getPassword() { return (this.password); } public void setPassword(String password) { this.password = password; } public String getUsername() { return (this.username); } public void setUsername(String username) { this.username = username; } public void reset(ActionMapping mapping, HttpServletRequest request) { this.password = null; this.username = null; } public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if ( (username == null ) || (username.length() == 0) ) { errors.add("username", new ActionError("errors.username.required")); }

160

if ( (password == null ) || (password.length() == 0) ) { errors.add("password", new ActionError("errors.password.required")); } return errors; } }

As we look over this class, we should first notice that it extends the org.apache.struts.action.ActionForm class; all ActionForm beans must extend this class. After this, we will notice that the LoginForm definition itself contains two data members--username and password--as well as six methods. The first four of these methods are simple setters and getters used to access and modify the two data members. Each of these setter methods is called by the Struts framework when a request is submitted with a parameter matching the data members name. This is accomplished using JavaBean reflection; therefore, the accessors of the ActionForm must follow the JavaBean standard naming convention. In the next section, we learn how these data members are mapped to request parameters. The last two methods of this ActionForm are probably the most important. These methods are defined by the ActionForm object, and are used to perform request-time processing. The reset() method is called by the Struts framework with each request that uses the defined ActionForm. The purpose of this method is to reset all of the LoginForms data members prior to the new request values being set. We should implement this method to reset our forms data members to their original values; otherwise, the default implementation will do nothing. As we look over our reset() method, we will note that it sets both of our data members back to null. This method guarantees that our data members are not holding stale data. The last method defined by our LoginForm is validate(). This method should be overridden when we are interested in testing the validity of the submitted data prior to the invocation of the Action.execute() method. The proper use of this method is to test the values of the data members, which have been set to the matching request parameters. If there are no problems with the submitted values, then the validate() method should return null or an empty ActionErrors object, and the execution of the request will continue with normal operation. If the values of the data members are invalid, then it should create a collection of ActionErrors containing an ActionError object for each invalid parameter and then return this ActionErrors instance to the Controller. If the Controller receives a valid ActionErrors collection, it will forward the request to the path identified by the <action>elements input attribute. If our ActionForm does not implement the validate() method, then the default implementation will simply return null, and processing will continue normally. After looking at the LoginForms validate() method, we will see that the request using this ActionForm must contain a username and password that is not null or a 0 length string. The Input Tags Once we get past the attributes of this instance of the <html:form /> tag, we will see that it also acts as a parent to three other HTML tags. These tags are synonymous with the HTML input elements.

161

The <html:text /> Tag The first of the HTML input tags is the <html:text /> tag. This tag is equivalent to the HTML text input tag, with the only difference being the property attribute, which names a unique data member found in the ActionForm bean class named by the forms type attribute. The following code snippet contains our <html:text /> tag. <html:text property="username" /> As we can see, the property attribute of this instance is set to the value username; therefore, when the form is submitted, the value of this input tag will be stored in the LoginForms username data member. The <html:password /> Tag The second of the HTML tags is the <html:password /> tag. This tag is equivalent to the HTML password input tag. It functions in the same way as <html:text />; the only difference is that its value is not displayed to the client. The following code snippet contains our <html:password /> tag: <html:password property="password" /> As we can see, the property attribute of this instance is set to the value password, which results in the LoginForms password data member being set to the value of this input parameter. The <html:submit />Tag The last HTML tag that we use is the <html:submit /> tag. This tag simply emulates an HTML submit button by submitting the request to the targeted action: <html:submit /> The Steps of a Struts Form Submission When a View containing this type of <html:form /> is requested, it will be evaluated and the resulting HTML will look similar to this:
<form name="loginForm"method="POST" action="/employees/Login.do"> <table width="45%" border="0"> <tr> <td>User Name:</td> <td> <input type="text" name="username" value=""></td> </tr> <tr> <td>Password:</td> <td>

162

<input type="password" name="password" value=""></td> </tr> <tr> <td colspan="2" align="center"> <input type="submit" name="submit" value="Submit"></td> </tr> </table> </form>

Note As we examine the evaluated form, we will notice that the value of the <input> elements is an empty string. This will not always be the case. If the session already includes an instance of the ActionForm named by the <form> element's name attribute, then the values stored in its data members will be used to prepopulate the input values. Once the user of this form has entered the appropriate values and clicked the Submit button, the following actions take place: 1.The Controller creates or retrieves (if it already exists) an instance of the com.wiley.LoginForm object, and stores the instance in the appropriate scope. The default scope is session. To change the scope of the ActionForm, we use the <html:form /> attribute scope. 2.The Controller then calls the com.wiley.LoginForm.reset() method to set the forms data members back to their default values. 3. The Controller next populates the com.wiley.LoginForm username and password data members with the values of the <html:text /> and <html:password /> tags, respectively. 4.Once the data members of the com.wiley.LoginForm have been set, the Controller invokes the com.wiley.LoginForm.validate() method. 5.If the validate() method does not encounter problems with the data, then the Action referenced by the <html:form />s action attribute is invoked and passes a reference to the populated ActionForm. Processing then continues normally. Thats about it. There is almost no limit to the type of Views that can exist in a Struts application, but this typeof View is most tightly bound to the Struts framework.

163

CHAPTER 9 XML
9.1 - Introduction to XML
XML was designed to describe data and to focus on what data is. HTML was designed to display data and to focus on how data looks. What We Should Already Know Before we continue, we should have a basic understanding of the following: HTML / XHTML JavaScript or VBScript What is XML? XML stands for EXtensible Markup Language XML is a markup language much like HTML XML was designed to describe data XML tags are not predefined. We must define our own tags XML uses a Document Type Definition (DTD) or an XML Schema to describe the data XML with a DTD or XML Schema is designed to be self-descriptive XML is a W3C Recommendation XML is a W3C Recommendation The Extensible Markup Language (XML) became a W3C Recommendation 10. February 1998. The main difference between XML and HTML XML was designed to carry data. XML is not a replacement for HTML. XML and HTML were designed with different goals: XML was designed to describe data and to focus on what data is. HTML was designed to display data and to focus on how data looks. HTML is about displaying information, while XML is about describing information. XML does not DO anything XML was not designed to DO anything. Maybe it is a little hard to understand, but XML does not DO anything. XML was created to structure, store and to send information. The following example is a note to Tove from Jani, stored as XML:

164

<note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> The note has a header and a message body. It also has sender and receiver information. But still, this XML document does not DO anything. It is just pure information wrapped in XML tags. Someone must write a piece of software to send, receive or display it. XML is free and extensible XML tags are not predefined. We must "invent" our own tags. The tags used to mark up HTML documents and the structure of HTML documents are predefined. The author of HTML documents can only use tags that are defined in the HTML standard (like <p>, <h1>, etc.). XML allows the author to define his own tags and his own document structure. The tags in the example above (like <to> and <from>) are not defined in any XML standard. These tags are "invented" by the author of the XML document. XML in future Web development XML is going to be everywhere. We have been participating in XML development since its creation. It has been amazing to see how quickly the XML standard has been developed and how quickly a large number of software vendors have adopted the standard. We strongly believe that XML will be as important to the future of the Web as HTML has been to the foundation of the Web and that XML will be the most common tool for all data manipulation and data transmission. How can XML be Used? It is important to understand that XML was designed to store, carry, and exchange data. XML was not designed to display data. XML can separate Data from HTML With XML, our data is stored outside our HTML. When HTML is used to display data, the data is stored inside our HTML. With XML, data can be stored in separate XML files. This way we can concentrate on using HTML for data layout and display, and be sure that changes in the underlying data will not require any changes to our HTML. XML data can also be stored inside HTML pages as "Data Islands". We can still concentrate on using HTML only for formatting and displaying the data. XML is used to Exchange Data With XML, data can be exchanged between incompatible systems. In the real world, computer systems and databases contain data in incompatible formats. One of the most time-consuming challenges for developers has been to exchange data between such systems over the Internet. Converting the data to XML can greatly reduce this complexity and create data that can be read by many different types of applications. 165

XML and B2B With XML, financial information can be exchanged over the Internet. Expect to see a lot about XML and B2B (Business To Business) in the near future. XML is going to be the main language for exchanging financial information between businesses over the Internet. A lot of interesting B2B applications are under development. XML can be used to Share Data With XML, plain text files can be used to share data. Since XML data is stored in plain text format, XML provides a software- and hardwareindependent way of sharing data. This makes it much easier to create data that different applications can work with. It also makes it easier to expand or upgrade a system to new operating systems, servers, applications, and new browsers. XML can be used to Store Data With XML, plain text files can be used to store data. XML can also be used to store data in files or in databases. Applications can be written to store and retrieve information from the store, and generic applications can be used to display the data.

9.2 - XML Syntax


The syntax rules of XML are very simple and very strict. The rules are very easy to learn, and very easy to use. Because of this, creating software that can read and manipulate XML is very easy. An example XML document XML documents use a self-describing and simple syntax. <?xml version="1.0" encoding="ISO-8859-1"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> The first line in the document - the XML declaration - defines the XML version and the character encoding used in the document. In this case the document conforms to the 1.0 specification of XML and uses the ISO-8859-1 (Latin-1/West European) character set. The next line describes the root element of the document (like it was saying: "this document is a note"): <note> The next 4 lines describe 4 child elements of the root (to, from, heading, and body):

166

<to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> And finally the last line defines the end of the root element: </note> Can we detect from this example that the XML document contains a Note to Tove from Jani? Don't we agree that XML is pretty self-descriptive? All XML elements must have a closing tag With XML, it is illegal to omit the closing tag. In HTML some elements do not have to have a closing tag. The following code is legal in HTML: <p>This is a paragraph <p>This is another paragraph In XML all elements must have a closing tag, like this: <p>This is a paragraph</p> <p>This is another paragraph</p> Note: We might have noticed from the previous example that the XML declaration did not have a closing tag. This is not an error. The declaration is not a part of the XML document itself. It is not an XML element, and it should not have a closing tag. XML tags are case sensitive Unlike HTML, XML tags are case sensitive. With XML, the tag <Letter> is different from the tag <letter>. Opening and closing tags must therefore be written with the same case: <Message>This is incorrect</message> <message>This is correct</message> All XML elements must be properly nested Improper nesting of tags makes no sense to XML. In HTML some elements can be improperly nested within each other like this: <b><i>This text is bold and italic</b></i> In XML all elements must be properly nested within each other like this:

167

<b><i>This text is bold and italic</i></b> All XML documents must have a root element All XML documents must contain a single tag pair to define a root element. All other elements must be within this root element. All elements can have sub elements (child elements). Sub elements must be correctly nested within their parent element: <root> <child> <subchild>.....</subchild> </child> </root> Attribute values must always be quoted With XML, it is illegal to omit quotation marks around attribute values. XML elements can have attributes in name/value pairs just like in HTML. In XML the attribute value must always be quoted. Study the two XML documents below. The first one is incorrect, the second is correct: <?xml version="1.0" encoding="ISO-8859-1"?> <note date=12/11/2002> <to>Tove</to> <from>Jani</from> </note>

<?xml version="1.0" encoding="ISO-8859-1"?> <note date="12/11/2002"> <to>Tove</to> <from>Jani</from> </note> The error in the first document is that the date attribute in the note element is not quoted. This is correct: date="12/11/2002". This is incorrect: date=12/11/2002. With XML, white space is preserved With XML, the white space in our document is not truncated. This is unlike HTML. With HTML, a sentence like this: Hello my name is Tove, will be displayed like this: 168

Hello my name is Tove, because HTML reduces multiple, consecutive white space characters to a single white space. Comments in XML The syntax for writing comments in XML is similar to that of HTML. <!-- This is a comment --> There is nothing special about XML There is nothing special about XML. It is just plain text with the addition of some XML tags enclosed in angle brackets. Software that can handle plain text can also handle XML. In a simple text editor, the XML tags will be visible and will not be handled specially. In an XML-aware application however, the XML tags can be handled specially. The tags may or may not be visible, or have a functional meaning, depending on the nature of the application.

169

9.3 - XML Elements


XML Elements are Extensible XML documents can be extended to carry more information. Look at the following XML NOTE example: <note> <to>Tove</to> <from>Jani</from> <body>Don't forget me this weekend!</body> </note> Let's imagine that we created an application that extracted the <to>, <from>, and <body> elements from the XML document to produce this output: MESSAGE To: Tove From: Jani Don't forget me this weekend! Imagine that the author of the XML document added some extra information to it: <note> <date>2002-08-01</date> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> Should the application break or crash? No. The application should still be able to find the <to>, <from>, and <body> elements in the XML document and produce the same output. XML documents are Extensible. XML Elements have Relationships Elements are related as parents and children. To understand XML terminology, we have to know how relationships between XML elements are named, and how element content is described. Imagine that this is a description of a book: My First XML 170

Introduction to XML What is HTML What is XML XML Syntax Elements must have a closing tag Elements must be properly nested Imagine that this XML document describes the book: <book> <title>My First XML</title> <prod id="33-657" media="paper"></prod> <chapter>Introduction to XML <para>What is HTML</para> <para>What is XML</para> </chapter> <chapter>XML Syntax <para>Elements must have a closing tag</para> <para>Elements must be properly nested</para> </chapter> </book> Book is the root element. Title, prod, and chapter are child elements of book. Book is the parent element of title, prod, and chapter. Title, prod, and chapter are siblings (or sister elements) because they have the same parent. Elements have Content Elements can have different content types. An XML element is everything from (including) the element's start tag to (including) the element's end tag. An element can have element content, mixed content, simple content, or empty content. An element can also have attributes. In the example above, book has element content, because it contains other elements. Chapter has mixed content because it contains both text and other elements. Para has simple content (or text content) because it contains only text. Prod has empty content, because it carries no information.

171

In the example above only the prod element has attributes. The attribute named id has the value "33-657". The attribute named media has the value "paper". Element Naming XML elements must follow these naming rules: Names can contain letters, numbers, and other characters Names must not start with a number or punctuation character Names must not start with the letters xml (or XML, or Xml, etc) Names cannot contain spaces Take care when we "invent" element names and follow these simple rules: Any name can be used, no words are reserved, but the idea is to make names descriptive. Names with an underscore separator are nice. Examples: <first_name>, <last_name>. Avoid "-" and "." in names. For example, if we name something "first-name," it could be a mess if our software tries to subtract name from first. Or if we name something "first.name," our software may think that "name" is a property of the object "first." Element names can be as long as we like, but don't exaggerate. Names should be short and simple, like this: <book_title> not like this: <the_title_of_the_book>.

9.4 - XML Attributes


XML elements can have attributes in the start tag, just like HTML. Attributes are used to provide additional information about elements. XML Attributes XML elements can have attributes. From HTML we will remember this: <IMG SRC="computer.gif">. The SRC attribute provides additional information about the IMG element. In HTML (and in XML) attributes provide additional information about elements: <img src="computer.gif"> <a href="demo.asp"> Attributes often provide information that is not a part of the data. In the example below, the file type is irrelevant to the data, but important to the software that wants to manipulate the element: <file type="gif">computer.gif</file> Quote Styles, "female" or 'female'? Attribute values must always be enclosed in quotes, but either single or double quotes can be used. For a person's sex, the person tag can be written like this:

172

<person sex="female"> or like this: <person sex='female'> Note: If the attribute value itself contains double quotes it is necessary to use single quotes, like in this example: <gangster name='George "Shotgun" Ziegler'> Note: If the attribute value itself contains single quotes it is necessary to use double quotes, like in this example: <gangster name="George 'Shotgun' Ziegler"> Use of Elements vs. Attributes Data can be stored in child elements or in attributes. Take a look at these examples: <person sex="female"> <firstname>Anna</firstname> <lastname>Smith</lastname> </person>

<person> <sex>female</sex> <firstname>Anna</firstname> <lastname>Smith</lastname> </person> In the first example sex is an attribute. In the last, sex is a child element. Both examples provide the same information. There are no rules about when to use attributes, and when to use child elements. My experience is that attributes are handy in HTML, but in XML we should try to avoid them. Use child elements if the information feels like data. The Best Way is to store data in child elements. The following three XML documents contain exactly the same information: A date attribute is used in the first example: <note date="12/11/2002"> <to>Tove</to>

173

<from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> A date element is used in the second example: <note> <date>12/11/2002</date> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> An expanded date element is used in the third: (THIS IS MY FAVORITE): <note> <date> <day>12</day> <month>11</month> <year>2002</year> </date> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> Avoid using attributes? Should We avoid using attributes? Some of the problems with using attributes are: attributes cannot contain multiple values (child elements can) attributes are not easily expandable (for future changes) attributes cannot describe structures (child elements can) attributes are more difficult to manipulate by program code attribute values are not easy to test against a Document Type Definition (DTD) - which is used to define the legal elements of an XML document

174

If we use attributes as containers for data, we end up with documents that are difficult to read and maintain. Try to use elements to describe data. Use attributes only to provide information that is not relevant to the data. Don't end up like this (this is not how XML should be used): <note day="12" month="11" year="2002" to="Tove" from="Jani" heading="Reminder" body="Don't forget me this weekend!"> </note>

9.5 - XML Validation


XML with correct syntax is Well Formed XML. XML validated against a DTD is Valid XML. "Well Formed" XML documents A "Well Formed" XML document has correct XML syntax. A "Well Formed" XML document is a document that conforms to the XML syntax rules that were described in the previous chapters: <?xml version="1.0" encoding="ISO-8859-1"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> "Valid" XML documents A "Valid" XML document also conforms to a DTD. A "Valid" XML document is a "Well Formed" XML document, which also conforms to the rules of a Document Type Definition (DTD): <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE note SYSTEM "InternalNote.dtd"> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> Viewing XML Files 175

Raw XML files can be viewed in Mozilla, Firefox, Opera, Internet Explorer, and Netscape 6+. However, to make XML documents display as nice web pages, we will have to add some display information. Viewing XML Files Open the XML file (typically by clicking on a link) - The XML document will be displayed with color-coded root and child elements. A plus (+) or minus sign (-) to the left of the elements can be clicked to expand or collapse the element structure. To view the raw XML source (without the + and - signs), select "View Page Source" or "View Source" from the browser menu.

Note: Do not expect XML files to be formatted like HTML documents! Viewing an Invalid XML File If an erroneous XML file is opened, the browser will report the error. Look at this XML file:

176

9.6 - Displaying XML with CSS


With CSS (Cascading Style Sheets) we can add display information to an XML document. Displaying our XML files with CSS? It is possible to use CSS to format an XML document. Below is an example of how to use a CSS style sheet to format an XML document: Take a look at this XML file: The CD catalog

177

Then look at this style sheet: The CSS file

178

Finally, view: The CD catalog formatted with the CSS file

179

Below is a fraction of the XML file. The second line, <?xml-stylesheet type="text/css" href="cd_catalog.css"?>, links the XML file to the CSS file: <?xml version="1.0" encoding="ISO-8859-1"?> <?xml-stylesheet type="text/css" href="cd_catalog.css"?> <CATALOG> <CD> <TITLE>Empire Burlesque</TITLE> <ARTIST>Bob Dylan</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Columbia</COMPANY> <PRICE>10.90</PRICE> <YEAR>1985</YEAR> </CD> <CD> <TITLE>Hide our heart</TITLE> <ARTIST>Bonnie Tyler</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>CBS Records</COMPANY> <PRICE>9.90</PRICE> <YEAR>1988</YEAR> </CD> . . . . </CATALOG> Note: Formatting XML with CSS is NOT the future of how to style XML documents. XML document should be styled by using the W3C's XSL standard!

9.7 - Displaying XML with XSL


With XSL we can add display information to our XML document. Displaying XML with XSL XSL is the preferred style sheet language of XML.

180

XSL (the eXtensible Stylesheet Language) is far more sophisticated than CSS. One way to use XSL is to transform XML into HTML before it is displayed by the browser as demonstrated in these examples: the XSL style sheet,

and View the result.

181

Below is a fraction of the XML file. The second line, <?xml-stylesheet type="text/xsl" href="simple.xsl"?>, links the XML file to the XSL file: <?xml version="1.0" encoding="ISO-8859-1"?> <?xml-stylesheet type="text/xsl" href="simple.xsl"?> <breakfast_menu> <food> <name>Belgian Waffles</name> <price>$5.95</price> <description> two of our famous Belgian Waffles </description> <calories>650</calories> </food> </breakfast_menu> If we want to learn more about XSL, please visit our XSL tutorial.

182

9.8 - XML Namespaces


XML Namespaces provide a method to avoid element name conflicts. Name Conflicts Since element names in XML are not predefined, a name conflict will occur when two different documents use the same element names. This XML document carries information in a table: <table> <tr> <td>Apples</td> <td>Bananas</td> </tr> </table> This XML document carries information about a table (a piece of furniture): <table> <name>African Coffee Table</name> <width>80</width> <length>120</length> </table> If these two XML documents were added together, there would be an element name conflict because both documents contain a <table> element with different content and definition. Solving Name Conflicts using a Prefix This XML document carries information in a table: <h:table> <h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr> </h:table> This XML document carries information about a piece of furniture: <f:table> <f:name>African Coffee Table</f:name> <f:width>80</f:width>

183

<f:length>120</f:length> </f:table> Now there will be no name conflict because the two documents use a different name for their <table> element (<h:table> and <f:table>). By using a prefix, we have created two different types of <table> elements. Using Namespaces This XML document carries information in a table: <h:table xmlns:h="http://www.w3.org/TR/html4/"> <h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr> </h:table> This XML document carries information about a piece of furniture: <f:table xmlns:f="http://www.w3schools.com/furniture"> <f:name>African Coffee Table</f:name> <f:width>80</f:width> <f:length>120</f:length> </f:table> Instead of using only prefixes, we have added an xmlns attribute to the <table> tag to give the prefix a qualified name associated with a namespace. The XML Namespace (xmlns) Attribute The XML namespace attribute is placed in the start tag of an element and has the following syntax: xmlns:namespace-prefix="namespaceURI" When a namespace is defined in the start tag of an element, all child elements with the same prefix are associated with the same namespace. Note that the address used to identify the namespace is not used by the parser to look up information. The only purpose is to give the namespace a unique name. However, very often companies use the namespace as a pointer to a real Web page containing information about the namespace. Default Namespaces Defining a default namespace for an element saves us from using prefixes in all the child elements. It has the following syntax: 184

xmlns="namespaceURI" This XML document carries information in a table: <table xmlns="http://www.w3.org/TR/html4/"> <tr> <td>Apples</td> <td>Bananas</td> </tr> </table> This XML document carries information about a piece of furniture: <table xmlns="http://www.w3schools.com/furniture"> <name>African Coffee Table</name> <width>80</width> <length>120</length> </table> Namespaces in Real Use When we start using XSL, we will soon see namespaces in real use. XSL style sheets are used to transform XML documents into other formats, like HTML. If we take a close look at the XSL document below, we will see that most of the tags are HTML tags. The tags that are not HTML tags have the prefix xsl, identified by the namespace "http://www.w3.org/1999/XSL/Transform": <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <table border="1"> <tr> <th align="left">Title</th> <th align="left">Artist</th> </tr> <xsl:for-each select="catalog/cd"> <tr> 185

<td><xsl:value-of select="title"/></td> <td><xsl:value-of select="artist"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>

9.9 - Introduction to DTD


A Document Type Definition defines the legal building blocks of an XML document. It defines the document structure with a list of legal elements. A DTD can be declared inline in our XML document, or as an external reference. Internal DOCTYPE declaration If the DTD is included in our XML source file, it should be wrapped in a DOCTYPE definition with the following syntax: <!DOCTYPE root-element [element-declarations]> Example XML document with a DTD: <?xml version="1.0"?> <!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend</body> </note>

186

The DTD above is interpreted like this: !DOCTYPE note (in line 2) defines that this is a document of the type note. !ELEMENT note (in line 3) defines the note element as having four elements: "to,from,heading,body". !ELEMENT to (in line 4) defines the to element to be of the type "#PCDATA". !ELEMENT from (in line 5) defines the from element to be of the type "#PCDATA" and so on..... External DOCTYPE declaration If the DTD is external to our XML source file, it should be wrapped in a DOCTYPE definition with the following syntax: <!DOCTYPE root-element SYSTEM "filename"> This is the same XML document as above, but with an external DTD: (Open it in IE5, and select view source) <?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd"> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> And this is a copy of the file "note.dtd" containing the DTD: <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>

187

Why use a DTD? With DTD, each of our XML files can carry a description of its own format with it. With a DTD, independent groups of people can agree to use a common DTD for interchanging data. Our application can use a standard DTD to verify that the data we receive from the outside world is valid. We can also use a DTD to verify our own data.

9.10 - DTD - XML building blocks


The main building blocks of both XML and HTML documents are tags like <body>....</body>. The building blocks of XML documents Seen from a DTD point of view, all XML documents (and HTML documents) are made up by the following simple building blocks:

Elements Attributes Entities PCDATA CDATA

The following is a brief explanation of each of the building blocks: Elements Elements are the main building blocks of both XML and HTML documents. Examples of HTML elements are "body" and "table". Examples of XML elements could be "note" and "message". Elements can contain text, other elements, or be empty. Examples of empty HTML elements are "hr", "br" and "img". Examples: <body>body text in between</body> <message>some message in between</message> Attributes Attributes provide extra information about elements. Attributes are always placed inside the starting tag of an element. Attributes always come in name/value pairs. The following "img" element has additional information about a source file: <img src="computer.gif" /> 188

The name of the element is "img". The name of the attribute is "src". The value of the attribute is "computer.gif". Since the element itself is empty it is closed by a " /". Entities Entities are variables used to define common text. Entity references are references to entities. Most of we will know the HTML entity reference: "&nbsp;". This "no-breaking-space" entity is used in HTML to insert an extra space in a document. Entities are expanded when a document is parsed by an XML parser. The following entities are predefined in XML: Entity References &lt; &gt; &amp; &quot; &apos; Character < > & " '

PCDATA PCDATA means parsed character data. Think of character data as the text found between the start tag and the end tag of an XML element. PCDATA is text that will be parsed by a parser. Tags inside the text will be treated as markup and entities will be expanded. CDATA CDATA also means character data. CDATA is text that will NOT be parsed by a parser. Tags inside the text will NOT be treated as markup and entities will not be expanded. Examples TV Schedule DTD <!DOCTYPE TVSCHEDULE [ <!ELEMENT TVSCHEDULE (CHANNEL+)> <!ELEMENT CHANNEL (BANNER,DAY+)> <!ELEMENT BANNER (#PCDATA)> <!ELEMENT DAY (DATE,(HOLIDAY|PROGRAMSLOT+)+)> <!ELEMENT HOLIDAY (#PCDATA)> <!ELEMENT DATE (#PCDATA)> <!ELEMENT PROGRAMSLOT (TIME,TITLE,DESCRIPTION?)> <!ELEMENT TIME (#PCDATA)> <!ELEMENT TITLE (#PCDATA)> <!ELEMENT DESCRIPTION (#PCDATA)> 189

<!ATTLIST TVSCHEDULE NAME CDATA #REQUIRED> <!ATTLIST CHANNEL CHAN CDATA #REQUIRED> <!ATTLIST PROGRAMSLOT VTR CDATA #IMPLIED> <!ATTLIST TITLE RATING CDATA #IMPLIED> <!ATTLIST TITLE LANGUAGE CDATA #IMPLIED> ]>

Newspaper Article DTD <!DOCTYPE NEWSPAPER [ <!ELEMENT NEWSPAPER (ARTICLE+)> <!ELEMENT ARTICLE (HEADLINE,BYLINE,LEAD,BODY,NOTES)> <!ELEMENT HEADLINE (#PCDATA)> <!ELEMENT BYLINE (#PCDATA)> <!ELEMENT LEAD (#PCDATA)> <!ELEMENT BODY (#PCDATA)> <!ELEMENT NOTES (#PCDATA)> <!ATTLIST ARTICLE AUTHOR CDATA #REQUIRED> <!ATTLIST ARTICLE EDITOR CDATA #IMPLIED> <!ATTLIST ARTICLE DATE CDATA #IMPLIED> <!ATTLIST ARTICLE EDITION CDATA #IMPLIED> <!ENTITY NEWSPAPER "Vervet Logic Times"> <!ENTITY PUBLISHER "Vervet Logic Press"> <!ENTITY COPYRIGHT "Copyright 1998 Vervet Logic Press"> ]>

9.11 - XML Schema


XML Schema is an XML based alternative to DTD. An XML schema describes the structure of an XML document. The XML Schema language is also referred to as XML Schema Definition (XSD). What We Should Already Know Before we continue we should have a basic understanding of the following:

HTML / XHTML XML and XML Namespaces A basic understanding of DTD

190

What is an XML Schema? The purpose of an XML Schema is to define the legal building blocks of an XML document, just like a DTD.An XML Schema:

defines elements that can appear in a document defines attributes that can appear in a document defines which elements are child elements defines the order of child elements defines the number of child elements defines whether an element is empty or can include text defines data types for elements and attributes defines default and fixed values for elements and attributes

XML Schemas are the Successors of DTDs We think that very soon XML Schemas will be used in most Web applications as a replacement for DTDs. Here are some reasons:

XML Schemas are extensible to future additions XML Schemas are richer and more powerful than DTDs XML Schemas are written in XML XML Schemas support data types XML Schemas support namespaces

XML Schema is a W3C Recommendation XML Schema was originally proposed by Microsoft, but became an official W3C recommendation in May 2001.The specification is now stable and has been reviewed by the W3C Membership. Why Use XML Schemas? XML Schemas are much more powerful than DTDs. XML Schemas Support Data Types One of the greatest strength of XML Schemas is the support for data types. With support for data types:

It is easier to describe allowable document content It is easier to validate the correctness of data It is easier to work with data from a database It is easier to define data facets (restrictions on data) It is easier to define data patterns (data formats) It is easier to convert data between different data types 191

XML Schemas use XML Syntax Another great strength about XML Schemas is that they are written in XML. Some benefits of that XML Schemas are written in XML:

We don't have to learn a new language We can use our XML editor to edit our Schema files We can use our XML parser to parse our Schema files We can manipulate our Schema with the XML DOM We can transform our Schema with XSLT

XML Schemas Secure Data Communication When sending data from a sender to a receiver, it is essential that both parts have the same "expectations" about the content. With XML Schemas, the sender can describe the data in a way that the receiver will understand. A date like: "03-11-2004" will, in some countries, be interpreted as 3.November and in other countries as 11.March. However, an XML element with a data type like this: <date type="date">2004-03-11</date> ensures a mutual understanding of the content, because the XML data type "date" requires the format "YYYY-MM-DD". XML Schemas are Extensible XML Schemas are extensible, because they are written in XML. With an extensible Schema definition we can:

Reuse our Schema in other Schemas Create our own data types derived from the standard types Reference multiple schemas in the same document

Well-Formed is not Enough A well-formed XML document is a document that conforms to the XML syntax rules, like:

it must begin with the XML declaration it must have one unique root element start-tags must have matching end-tags elements are case sensitive all elements must be closed all elements must be properly nested 192

all attribute values must be quoted entities must be used for special characters

Even if documents are well-formed they can still contain errors, and those errors can have serious consequences. Think of the following situation: we order 5 gross of laser printers, instead of 5 laser printers. With XML Schemas, most of these errors can be caught by our validating software. XSD How To? XML documents can have a reference to a DTD or to an XML Schema. A Simple XML Document Look at this simple XML document called "note.xml": <?xml version="1.0"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> A DTD File The following example is a DTD file called "note.dtd" that defines the elements of the XML document above ("note.xml"): <!ELEMENT note (to, from, heading, body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> The first line defines the note element to have four child elements: "to, from, heading, body". Line 2-5 defines the to, from, heading, body elements to be of type "#PCDATA". An XML Schema The following example is an XML Schema file called "note.xsd" that defines the elements of the XML document above ("note.xml"): <?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" 193

xmlns="http://www.w3schools.com" elementFormDefault="qualified"> <xs:element name="note"> <xs:complexType> <xs:sequence> <xs:element name="to" type="xs:string"/> <xs:element name="from" type="xs:string"/> <xs:element name="heading" type="xs:string"/> <xs:element name="body" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> The note element is a complex type because it contains other elements. The other elements (to, from, heading, body) are simple types because they do not contain other elements. We will learn more about simple and complex types in the following chapters. A Reference to a DTD This XML document has a reference to a DTD: <?xml version="1.0"?> <!DOCTYPE note SYSTEM "http://www.w3schools.com/dtd/note.dtd"> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>

A Reference to an XML Schema This XML document has a reference to an XML Schema: <?xml version="1.0"?> <note xmlns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com note.xsd"> <to>Tove</to> <from>Jani</from> 194

<heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>

195

CHAPTER - 10. SUPPORTING TECHNOLOGIES 10.1 Introduction to SQL queries


SQL Server I What is Database?
A database is a collection of information stored in a computer in a systematic way, such that a computer program can consult it to answer questions. The software used to manage and query a database is known as a database management system (DBMS).

Introduction to SQL
SQL stands for Structured Query Language. SQL is a standard computer language for accessing and manipulating databases. SQL commands can be divided into two main sublanguages. The Data Definition Language (DDL) contains the commands used to create and destroy databases and database objects. After the database structure is defined with DDL, database administrators and users can utilize the Data Manipulation Language to insert, retrieve and modify the data contained within it. SQL Data Manipulation Language (DML) SQL (Structured Query Language) is syntax for executing queries. But the SQL language also includes syntax to update, insert, and delete records. These query and update commands together form the Data Manipulation Language (DML) part of SQL:

SELECT - extracts data from a database table UPDATE - updates data in a database table DELETE - deletes data from a database table INSERT INTO - inserts new data into a database table

SQL Data Definition Language (DDL) The Data Definition Language (DDL) part of SQL permits database tables to be created or deleted. We can also define indexes (keys), specify links between tables, and impose constraints between database tables. The most important DDL statements in SQL are:

CREATE TABLE - creates a new database table 196

ALTER TABLE - alters (changes) a database table DROP TABLE - deletes a database table CREATE INDEX - creates an index (search key) DROP INDEX - deletes an index

SQL Data Control Language (DCL) Data control commands in SQL allow us to control access to data within the database. These DCL commands are normally used to create objects related to user access and also control the distribution of privileges among users. Some data control commands are as follows:
ALTER PASSWORD GRANT REVOKE CREATE SYNONYM

How to create a Database? Let's use the CREATE DATABASE command to set up our database: Syntax: CREATE DATABASE databasename
Example: CREATE DATABASE product

This Command creates an empty database named "product" on our DBMS. After creating the database, our next step is to create tables that will contain data.
Create a Table: Syntax: CREATE TABLE table_name ( Columnname1 datatype(size), Columnname2 datatype(size), Columnname3 datatype(size) ) This example demonstrates how we can create a table named "purchase_details", with six columns. Example: CREATE TABLE purchase_details ( purchase_id integer, product_id varchar(10), product_name varchar(20), quantity integer, amount float, date datetime )

197

The data type specifies what type of data the column can hold. The table below contains the most common data types in SQL:
Data Type integer(size) int(size) smallint(size) tinyint(size) decimal(size,d) numeric(size,d) char(size) varchar(size) date(yyyymmdd) Description Hold integers only. The maximum number of digits are specified in parenthesis.

Hold numbers with fractions. The maximum number of digits are specified in "size". The maximum number of digits to the right of the decimal is specified in "d". Holds a fixed length string (can contain letters, numbers, and special characters). The fixed size is specified in parenthesis. Holds a variable length string (can contain letters, numbers, and special characters). The maximum size is specified in parenthesis. Holds a date

Inserting values in a table:

The INSERT command in SQL is used to add records to an existing table. Returning to the purchase_details example from the previous section, let's imagine that we need to add a new purchase order to our database. Syntax: INSERT INTO table_name VALUES (value1, value2 ) Example: INSERT INTO purchase_details VALUES (1, 'p1','pen', 10, 7.00,'07-20-2006') We can also specify the columns for which we want to insert data: INSERT INTO table_name (column1, column2,...) VALUES (value1, value2 ...) INSERT INTO purchase_details (product_id, product_name) VALUES ('b1','box') SELECTING VALUES The SELECT command is the most commonly used command in SQL. It allows database users to retrieve the specific information they desire from an operational database. The command shown below retrieves all of the information contained within the purchase_details table. Note that the asterisk is used as a wildcard in SQL. This literally means "Select everything from the purchase_details table." Syntax: SELECT * FROM table_name Example: SELECT * FROM purchase_details

198

Alternatively, if users want to limit the attributes that are retrieved from the database, say they require a list of the product ids of all products. The following SQL command would retrieve only that information: SELECT product_id FROM purchase_details UPDATE The UPDATE command can be used to modify information contained within a table, either in bulk or individually. Syntax: UPDATE table_name SET column_name=value1 WHERE column_name=value2 Example: update purchase_details set amount=8.50 where product_id='p1' ALTER The ALTER command can be used to modify the structures of table, either adding new columns or modify existing column. Syntax: ALTER TABLE table_name ADD newcolumnname datatype(size) Example: ALTER TABLE purchase_details ADD product_total varchar(20) CONSTRAINTS A Constraint is a property assigned to a column or the set of columns in a table that prevents certain types of inconsistent data values from being placed in the column(s). Constraints are used to enforce the data integrity. This ensures the accuracy and reliability of the data in the database. TYPES OF CONSTRAINTS PRIMARY KEY UNIQUE FOREIGN KEY CHECK NOT NULL PRIMARY KEY: A PRIMARY KEY constraint is a unique identifier for a row within a database table. Every table should have a primary key constraint to uniquely identify each row and only one primary key constraint can be created for each table. The primary key constraints are used to enforce entity integrity.

199

Syntax: columnname datatype(size) PRIMARY KEY Example:


CREATE TABLE purchase_details ( purchase_id integer PRIMARY KEY not null, product_id varchar(10), product_name varchar(20), quantity integer, amount float, date datetime ) In case of existing table: Syntax: ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY(columnname) Example: ALTER TABLE purchase_details ADD CONSTRAINT pk PRIMARY KEY(purchase_id)

FOREIGN KEY A FOREIGN KEY constraint prevents any actions that would destroy link between tables with the corresponding data values. A foreign key in one table points to a primary key in another table. Foreign keys prevent actions that would leave rows with foreign key values when there are no primary keys with that value. The foreign key constraints are used to enforce referential integrity. Syntax: columnname datatype(size) FOREIGN KEY REFERENCES table_name(columnname) Example: CREATE TABLE stock_details ( stock_id integer PRIMARY KEY not null, purchase_id integer FOREIGN KEY REFERENCES purchase_details1(purchase_id), stock integer ) UNIQUE A UNIQUE constraint enforces the uniqueness of the values in a set of columns, so no duplicate values are entered. The unique key constraints are used to enforce entity integrity as the primary key constraints.

200

Syntax: columnname datatype(size) CONSTRAINT constraintname UNIQUE Example: CREATE TABLE book_detail ( bookid integer CONSTRAINT unq unique, bookname varchar(20) ) CHECK A CHECK constraint is used to limit the values that can be placed in a column. The check constraints are used to enforce domain integrity. Syntax: columnname datatype(size) CHECK(logical expression) Example: CREATE TABLE book_publishers ( bookid integer, publishers varchar(30) CHECK(publishers in('wrox','Tata Mc-graw Hill')) ) NOT NULL A NOT NULL constraint enforces that the column will not accept null values. The not null constraints are used to enforce domain integrity, as the check constraints. Syntax: columnname datatype(size) NOT NULL Example: CREATE TABLE book_publishers ( bookid integer NOT NULL, publishers varchar(30) ) How to drop a table? Syntax: DROP TABLE table_name Example: DROP TABLE book_detail

201

SQL Server II STORED PROCEDURES Microsoft SQL Server provides the stored procedure mechanism to simplify the database development process by grouping Transact-SQL statements into manageable blocks. Benefits

Precompiled execution. SQL Server compiles each stored procedure once and then reutilizes the execution plan. This results in tremendous performance boosts when stored procedures are called repeatedly. Reduced client/server traffic. If network bandwidth is a concern in our environment, we'll be happy to learn that stored procedures can reduce long SQL queries to a single line that is transmitted over the wire. Efficient reuse of code and programming abstraction . Stored procedures can be used by multiple users and client programs. If we utilize them in a planned manner, we'll find the development cycle takes less time. Enhanced security controls. We can grant users permission to execute a stored procedure independently of underlying table permissions.

Structure Stored procedures are extremely similar to the constructs seen in other programming languages. They accept data in the form of input parameters that are specified at execution time. These input parameters (if implemented) are utilized in the execution of a series of statements that produce some result. This result is returned to the calling environment through the use of a record set, output parameters and a return code. That may sound like a mouthful, but we'll find that stored procedures are actually quite simple. Let's take a look at a practical example. Example Assume we have the following table named Inventory: Stock_ID 1 2 3 4 5 6 Purchase_ID P1 B1 E1 C1 D1 F1 Stock 100 200 140 180 80 85

This information is updated in real-time and managers are constantly checking the quantity of products stored in their stock. In the past, each manager would run queries similar to the following:

202

SELECT Stock FROM Stock_details WHERE purchase_id='p1' This resulted in very inefficient performance at the SQL Server. Each time a manager executed the query, the database server was forced to recompile the query and execute it from scratch. It also required the manager to have knowledge of SQL and appropriate permissions to access the table information. We can simplify this process through the use of a stored procedure. Let's create a procedure called sp_getstock that retrieves the stock levels. Here's the SQL code: CREATE PROCEDURE sp_getstock @pid integer AS SELECT stock FROM Stock_details WHERE purchase_id= @pid Now to execute the stored procedure: EXECUTE sp_getstock 1 Granted, this is a simple example, but the benefits of abstraction can be seen here. The manager does not need to understand SQL or the inner workings of the procedure. Insert values using Stored Procedures: CREATE PROCEDURE usp_insert @bookid integer,@bookname varchar(20) AS INSERT INTO book_details VALUES(@bookid,@bookname) Update values using Stored Procedures: CREATE PROCEDURE usp_update @bookid integer,@bookname varchar(20) AS UPDATE book_details SET bookname=@bookname WHERE bookid=@bookid TRIGGERS A trigger is a database object that is bound to a table. In many aspects, it is similar to a stored procedure. As a matter of fact, triggers are often referred to as a "special kind of stored procedure".

203

SQL Server 2000 has many types of triggers: 1. 2. 3. 4. After Trigger Multiple After Triggers Instead Of Triggers Mixing Triggers Type

After Triggers
Triggers that run after an update, insert, or delete can be used in several ways:

Triggers can update, insert, or delete data in the same or other tables. This is useful to maintain relationships between data or to keep audit trail information. Triggers can check data against values of data in the rest of the table or in other tables. This is useful when we cannot use RI constraints or check constraints because of references to data from other rows from this or other tables. Triggers can use user-defined functions to activate non-database operations. This is useful, for example, for issuing alerts or updating information outside the database.

Note: An AFTER trigger can be created only on tables, not on views.

How to Create After Triggers


CREATE TRIGGER trig_Update ON purchase_details FOR INSERT AS UPDATE stock_details SET stock_details.stock=s.stock + i.quantity FROM stock_details s JOIN inserted i ON s.purchase_id = i.purchase_id We created INSERT trigger that referenced the logical inserted table. Whenever we insert a new record in the purchase_details table now, the corresponding record in the stock_details table will be updated to add the quantity with the quantity in the stock column of the stock_details table. INSTEAD OF TRIGGERS Instead Of Triggers fire instead of the operation that fires the trigger, so if we define an Instead Of trigger on a table for the Delete operation, they try to delete rows, they will not actually get deleted (unless we issue another delete instruction from within the trigger) as in this simple example:

204

CREATE TRIGGER tr_book ON book_details INSTEAD OF DELETE AS PRINT 'Sorry - we cannot delete this data' Now we try to delete the records, we cant delete. Multiple After Triggers More than one trigger can now be defined on a table for each Insert/Update/Delete. Although in general, we might not want to do this , there are situations where this is ideal. One example that springs to mind is that we can split our triggers up into two categories:

Application based triggers (cascading deletes or validation, for example). Auditing triggers (for recording details of changes to critical data).

This would allow us to alter triggers of one type without fear of accidentally breaking the other. If we are using multiple triggers, it is of course essential to know which order they fire in. A new stored procedure called sp_settriggerorder allows we to set a trigger to be either the "first" or "last" to fire.

10.2 Intoduction to HTML


HTML It is a special kind of text document that is used by Web browsers to present text and graphics. The text includes markup tags such as <p> to indicate the start of a paragraph, and </p> to indicate the end of a paragraph. HTML documents are often refered to as "Web pages". The browser retrieves Web pages from Web servers that thanks to the Internet, can be pretty much anywhere in World. What is an HTML File?

HTML stands for Hyper Text Markup Language An HTML file is a text file containing small markup tags The markup tags tell the Web browser how to display the page An HTML file must have an htm or html file extension An HTML file can be created using a simple text editor

Do We Want to Try It? If we are running Windows, start Notepad. Type in the following text: 205

<html> <head> <title>Title of page</title> </head> <body> This is my first homepage. <b>This text is bold</b> </body> </html> Save the file as "mypage.htm". Start our Internet browser. Select "Open" (or "Open Page") in the File menu of our browser. A dialog box will appear. Select "Browse" (or "Choose File") and locate the HTML file we just created - "mypage.htm" - select it and click "Open". Now we should see an address in the dialog box, for example "C:\MyDocuments\mypage.htm". Click OK, and the browser will display the page. Example Explained The first tag in our HTML document is <html>. This tag tells our browser that this is the start of an HTML document. The last tag in our document is </html>. This tag tells our browser that this is the end of the HTML document. The text between the <head> tag and the </head> tag is header information. Header information is not displayed in the browser window. The text between the <title> tags is the title of our document. The title is displayed in our browser's caption. The text between the <body> tags is the text that will be displayed in our browser. The text between the <b> and </b> tags will be displayed in a bold font. HTM or HTML Extension? When we save an HTML file, we can use either the .htm or the .html extension. We have used .htm in our examples. It might be a bad habit inherited from the past when some of the commonly used software only allowed three letter extensions. With newer software we think it will be perfectly safe to use .html. HTML Elements HTML documents are text files made up of HTML elements. HTML elements are defined using HTML tags. HTML Tags

HTML tags are used to mark-up HTML elements HTML tags are surrounded by the two characters < and > The surrounding characters are called angle brackets HTML tags normally come in pairs like <b> and </b> The first tag in a pair is the start tag, the second tag is the end tag The text between the start and end tags is the element content 206

HTML tags are not case sensitive, <b> means the same as <B>

HTML Elements Remember the HTML example from the previous page: <html> <head> <title>Title of page</title> </head> <body> This is my first homepage. <b>This text is bold</b> </body> </html> This is an HTML element: <b>This text is bold</b> The HTML element starts with a start tag: <b>. The content of the HTML element is: This text is boldThe HTML element ends with an end tag: </b> The purpose of the <b> tag is to define an HTML element that should be displayed as bold. This is also an HTML element: <body> This is my first homepage. <b>This text is bold</b> </body> This HTML element starts with the start tag <body>, and ends with the end tag </body>. The purpose of the <body> tag is to define the HTML element that contains the body of the HTML document. Why do We Use Lowercase Tags? We have just said that HTML tags are not case sensitive: <B> means the same as <b>. When we surf the Web, we will notice that most tutorials use uppercase HTML tags in their examples. We always use lowercase tags. Why? If we want to prepare ourself for the next generations of HTML, we should start using lowercase tags. The World Wide Web Consortium (W3C) recommends lowercase tags in their HTML 4 recommendation, and XHTML (the next generation HTML) demands lowercase tags. Tag Attributes Tags can have attributes. Attributes can provide additional information about the HTML elements on our page.

207

This tag defines the body element of our HTML page: <body>. With an added bgcolor attribute, we can tell the browser that the background color of our page should be red, like this: <body bgcolor="red">. This tag defines an HTML table: <table>. With an added border attribute, we can tell the browser that the table should have no borders: <table border="0"> Attributes always come in name/value pairs like this: name="value". Attributes are always added to the start tag of an HTML element. Quote Styles, "red" or 'red'? Attribute values should always be enclosed in quotes. Double style quotes are the most common, but single style quotes are also allowed. In some rare situations, like when the attribute value itself contains quotes, it is necessary to use single quotes: name='John "ShotGun" Nelson' Basic HTML Tags The most important tags in HTML are tags that define headings, paragraphs and line breaks. The best way to learn HTML is to work with examples. We have created a very nice HTML editor for us. With this editor, we can edit the HTML source code if we like, and click on a test button to view the result. Headings Headings are defined with the <h1> to <h6> tags. <h1> defines the largest heading. <h6> defines the smallest heading. <h1>This is a heading</h1> <h2>This is a heading</h2> <h3>This is a heading</h3> <h4>This is a heading</h4> <h5>This is a heading</h5> <h6>This is a heading</h6> HTML automatically adds an extra blank line before and after a heading. Example: <html> <body> <h1>This is heading 1</h1> <h2>This is heading 2</h2> <h3>This is heading 3</h3> 208

<h4>This is heading 4</h4> <h5>This is heading 5</h5> <h6>This is heading 6</h6> <p>Use heading tags only for headings. Don't use them just to make something bold. Use other tags for that.</p> </body> </html> Output : This is heading 1 This is heading 2 This is heading 3 This is heading 4 This is heading 5 This is heading 6 Paragraphs Paragraphs are defined with the <p> tag. <p>This is a paragraph</p> <p>This is another paragraph</p> HTML automatically adds an extra blank line before and after a paragraph. Example : <html><body> <p>This is a paragraph.</p> <p>This is a paragraph.</p> <p>This is a paragraph.</p> <p>Paragraph elements are defined by the p tag.</p> </body></html> Output : This is a paragraph. This is a paragraph. This is a paragraph. Paragraph elements are defined by the p tag Line Breaks The <br> tag is used when we want to end a line, but don't want to start a new paragraph. The <br> tag forces a line break wherever we place it. 209

<p>This <br> is a para<br>graph with line breaks</p> The <br> tag is an empty tag. It has no closing tag. Comments in HTML The comment tag is used to insert a comment in the HTML source code. A comment will be ignored by the browser. We can use comments to explain our code, which can help we when we edit the source code at a later date. <!-- This is a comment --> Note that we need an exclamation point after the opening bracket, but not before the closing bracket. Basic Notes - Useful Tips When we write HTML text, we can never be sure how the text is displayed in another browser. Some people have large computer displays, some have small. The text will be reformatted every time the user resizes his window. Never try to format the text in our editor by adding empty lines and spaces to the text. HTML will truncate the spaces in our text. Any number of spaces count as one. Some extra information: In HTML a new line counts as one space. Basic HTML Tags Tag <html> <body> <h1> to <h6> <p> <br> <hr> <!--> HTML Text Formatting HTML defines a lot of elements for formatting output, like bold or italic text. Below are a lot of examples that we can try out ourself: How to View HTML Source Have we ever seen a Web page and wondered "How do they do that?" To find out, simply click on the VIEW option in our browsers toolbar and select SOURCE or PAGE SOURCE. This will open a window that shows we the actual HTML of the page. 210 Description Defines an HTML document Defines the document's body Defines header 1 to header 6 Defines a paragraph Inserts a single line break Defines a horizontal rule Defines a comment

Text Formatting Tags Tag <b> <big> <em> <i> <small> <strong> <sub> <sup> <ins> <del> Description Defines bold text Defines big text Defines emphasized text Defines italic text Defines small text Defines strong text Defines subscripted text Defines superscripted text Defines inserted text Defines deleted text

HTML Links HTML uses a hyperlink to link to another document on the Web. The Anchor Tag and the Href Attribute HTML uses the <a> (anchor) tag to create a link to another document. An anchor can point to any resource on the Web: an HTML page, an image, a sound file, a movie, etc. The syntax of creating an anchor: <a href="url">Text to be displayed</a> The <a> tag is used to create an anchor to link from, the href attribute is used to address the document to link to, and the words between the open and close of the anchor tag will be displayed as a hyperlink. This anchor defines a link to CegonSoft <a href="http://www.cegonsoft.com/">Visit cegonsoft!</a> The line above will look like this in a browser: The Target Attribute With the target attribute, we can define where the linked document will be opened. The line below will open the document in a new browser window: <a href="http://www.cegonsoft.com/" target="_blank">Visit cegonsoft!</a> The Anchor Tag and the Name Attribute 211

The name attribute is used to create a named anchor. When using named anchors we can create links that can jump directly into a specific section on a page, instead of letting the user scroll around to find what he/she is looking for. Below is the syntax of a named anchor: <a name="label">Text to be displayed</a> The name attribute is used to create a named anchor. The name of the anchor can be any text we care to use. The line below defines a named anchor: <a name="tips">Useful Tips Section</a> We should notice that a named anchor is not displayed in a special way. To link directly to the "tips" section, add a # sign and the name of the anchor to the end of a URL, like this: <a href="http://www.cegonsoft.com/html_links.asp#tips"> Jump to the Useful Tips Section</a> A hyperlink to the Useful Tips Section from WITHIN the file "html_links.asp" will look like this: <a href="#tips">Jump to the Useful Tips Section</a> Link Tags Tag <a> HTML Frames With frames, we can display more than one Web page in the same browser window. Frames With frames, we can display more than one HTML document in the same browser window. Each HTML document is called a frame, and each frame is independent of the others. The disadvantages of using frames are: The web developer must keep track of more HTML documents It is difficult to print the entire page The Frameset Tag

Description Defines an anchor

The <frameset> tag defines how to divide the window into frames Each frameset defines a set of rows or columns The values of the rows/columns indicate the amount of screen area each row/column will occupy 212

The Frame Tag The <frame> tag defines what HTML document to put into each frame In the example below we have a frameset with two columns. The first column is set to 25% of the width of the browser window. The second column is set to 75% of the width of the browser window. The HTML document "frame_a.htm" is put into the first column, and the HTML document "frame_b.htm" is put into the second column:

<frameset cols="25%,75%"> <frame src="frame_a.htm"> <frame src="frame_b.htm"> </frameset> Basic Notes - Useful Tips If a frame has visible borders, the user can resize it by dragging the border. To prevent a user from doing this, we can add noresize="noresize" to the <frame> tag. Add the <noframes> tag for browsers that do not support frames. Important: We cannot use the <body></body> tags together with the <frameset></frameset> tags! However, if we add a <noframes> tag containing some text for browsers that do not support frames, we will have to enclose the text in <body></body> tags! See how it is done in the first example below. Frame Tags Tag <frameset> <frame> <noframes> <iframe> Description Defines a set of frames Defines a sub window (a frame) Defines a noframe section for browsers that do not handle frames Defines an inline sub window (frame)

HTML Tables With HTML we can create tables. Tables Tables are defined with the <table> tag. A table is divided into rows (with the <tr> tag), and each row is divided into data cells (with the <td> tag). The letters td stands for "table data," which is the content of a data cell. A data cell can contain text, images, lists, paragraphs, forms, horizontal rules, tables, etc.

213

<table border="1"> <tr> <td>row 1, cell 1</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> </tr> </table> How it looks in a browser: row 1, cell 1 row 1, cell 2 row 2, cell 1 row 2, cell 2 Tables and the Border Attribute If we do not specify a border attribute the table will be displayed without any borders. Sometimes this can be useful, but most of the time, we want the borders to show. To display a table with borders, we will have to use the border attribute: <table border="1"> <tr> <td>Row 1, cell 1</td> <td>Row 1, cell 2</td> </tr> </table> Headings in a Table Headings in a table are defined with the <th> tag. <table border="1"> <tr> <th>Heading</th> <th>Another Heading</th> </tr> <tr> <td>row 1, cell 1</td> <td>row 1, cell 2</td> </tr>

214

<tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> </tr> </table> How it looks in a browser: Heading Another Heading

row 1, cell 1 row 1, cell 2 row 2, cell 1 row 2, cell 2 HTML Lists HTML supports ordered, unordered and definition lists. Unordered Lists An unordered list is a list of items. The list items are marked with bullets (typically small black circles). An unordered list starts with the <ul> tag. Each list item starts with the <li> tag. <ul> <li>Coffee</li> <li>Milk</li> </ul> Here is how it looks in a browser: Coffee Milk Inside a list item we can put paragraphs, line breaks, images, links, other lists, etc. Ordered Lists An ordered list is also a list of items. The list items are marked with numbers. An ordered list starts with the <ol> tag. Each list item starts with the <li> tag. <ol> <li>Coffee</li> <li>Milk</li> </ol> Here is how it looks in a browser: 1. Coffee 215

2. Milk Inside a list item we can put paragraphs, line breaks, images, links, other lists, etc. Definition Lists A definition list is not a list of items. This is a list of terms and explanation of the terms. A definition list starts with the <dl> tag. Each definition-list term starts with the <dt> tag. Each definition-list definition starts with the <dd> tag. <dl> <dt>Coffee</dt> <dd>Black hot drink</dd> <dt>Milk</dt> <dd>White cold drink</dd> </dl> Here is how it looks in a browser: Coffee Black hot drink Milk White cold drink Inside a definition-list definition (the <dd> tag) we can put paragraphs, line breaks, images, links, other lists, etc.

HTML Forms and Input HTML Forms are used to select different kinds of user input. Forms A form is an area that can contain form elements. Form elements are elements that allow the user to enter information (like text fields, textarea fields, drop-down menus, radio buttons, checkboxes, etc.) in a form. A form is defined with the <form> tag. <form> <input> <input> </form> Input The most used form tag is the <input> tag. The type of input is specified with the type attribute. The most commonly used input types are explained below. 216

Text Fields Text fields are used when we want the user to type letters, numbers, etc. in a form. <form> First name: <input type="text" name="firstname"> <br> Last name: <input type="text" name="lastname"> </form> How it looks in a browser: First

name:

Last name: Note that the form itself is not visible. Also note that in most browsers, the width of the text field is 20 characters by default. Radio Buttons Radio Buttons are used when we want the user to select one of a limited number of choices. <form> <input type="radio" name="sex" value="male"> Male <br> <input type="radio" name="sex" value="female"> Female </form> How it looks in a browser: Male Female Note that only one option can be chosen. Checkboxes Checkboxes are used when we want the user to select one or more options of a limited number of choices. <form> <input type="checkbox" name="bike"> I have a bike <br>

217

<input type="checkbox" name="car"> I have a car </form> How it looks in a browser: I have a bike I have a car The Form's Action Attribute and the Submit Button When the user clicks on the "Submit" button, the content of the form is sent to another file. The form's action attribute defines the name of the file to send the content to. The file defined in the action attribute usually does something with the received input. <form name="input" action="html_form_action.asp" method="get"> Username: <input type="text" name="user"> <input type="submit" value="Submit"> </form> How it looks in a browser: Username: If we type some characters in the text field above, and click the "Submit" button, we will send our input to a page called "html_form_action.asp". That page will show we the received input. Form Tags Tag <form> <input> <textarea> <label> <fieldset> <legend> <select> <optgroup> <option> Description Defines a form for user input Defines an input field Defines a text-area (a multi-line text input control) Defines a label to a control Defines a fieldset Defines a caption for a fieldset Defines a selectable list (a drop-down box) Defines an option group Defines an option in the drop-down box

Submit

218

<button>

Defines a push button

HTML Images With HTML we can display images in a document. The Image Tag and the Src Attribute In HTML, images are defined with the <img> tag. The <img> tag is empty, which means that it contains attributes only and it has no closing tag. To display an image on a page, we need to use the src attribute. Src stands for "source". The value of the src attribute is the URL of the image we want to display on our page. The syntax of defining an image: <img src="url"> The browser puts the image where the image tag occurs in the document. If we put an image tag between two paragraphs, the browser shows the first paragraph, then the image, and then the second paragraph.

219

The Alt Attribute The alt attribute is used to define an "alternate text" for an image. The value of the alt attribute is an author-defined text: <img src="boat.gif" alt="Big Boat"> The "alt" attribute tells the reader what he or she is missing on a page if the browser can't load images. The browser will then display the alternate text instead of the image. It is a good practice to include the "alt" attribute for each image on a page, to improve the display and usefulness of our document for people who have text-only browsers. HTML Backgrounds A good background can make a Web site look really great. Backgrounds The <body> tag has two attributes where we can specify backgrounds. The background can be a color or an image. Bgcolor The bgcolor attribute specifies a background-color for an HTML page. The value of this attribute can be a hexadecimal number, an RGB value, or a color name: <body bgcolor="#000000"> <body bgcolor="rgb(0,0,0)"> <body bgcolor="black"> The lines above all set the background-color to black. Background The background attribute specifies a background-image for an HTML page. The value of this attribute is the URL of the image we want to use. If the image is smaller than the browser window, the image will repeat itself until it fills the entire browser window. <body background="clouds.gif"> <body background="http://www.cegonsoft.com/clouds.gif"> The URL can be relative (as in the first line above) or absolute (as in the second line above). Note: If we want to use a background image, we should keep in mind: Will the background image increase the loading time too much? Will the background image look good with other images on the page? Will the background image look good with the text colors on the page? Will the background image look good when it is repeated on the page? 220

Will the background image take away the focus from the text?

HTML Colors Colors are displayed combining RED, GREEN, and BLUE light sources. Color Values Colors are defined using a hexadecimal notation for the combination of Red, Green, and Blue color values (RGB). The lowest value that can be given to one light source is 0 (hex #00). The highest value is 255 (hex #FF). This table shows the result of combining Red, Green, and Blue light sources:. Color Color HEX #000000 #FF0000 #00FF00 #0000FF #FFFF00 #00FFFF #FF00FF #C0C0C0 #FFFFFF Color Names A collection of color names is supported by most browsers. Note: Only 16 color names are supported by the W3C HTML 4.0 standard (aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, purple, red, silver, teal, white, and yellow). For all other colors we should use the Color HEX value. Color Color HEX #F0F8FF #7FFFD4 #000000 #0000FF #8A2BE2 #A52A2A HTML Fonts 221 Color Name AliceBlue Aquamarine Black Blue BlueViolet Brown Color RGB rgb(0,0,0) rgb(255,0,0) rgb(0,255,0) rgb(0,0,255) rgb(255,255,0) rgb(0,255,255) rgb(255,0,255) rgb(192,192,192) rgb(255,255,255)

The <font> tag in HTML is deprecated. It is supposed to be removed in a future version of HTML. Even if a lot of people are using it, we should try to avoid it, and use styles instead. The HTML <font> Tag With HTML code like this, we can specify both the size and the type of the browser output : <p> <font size="2" face="Verdana"> This is a paragraph. </font> </p> <p> <font size="3" face="Times"> This is another paragraph. </font> </p> Font Attributes Attribute size="number" size="+number" size="-number" face="face-name" color="color-value" color="color-name" Exercise 1) 2) 3) 4) 5) Create a vertical frameset with 3 different documents with noresize. Create a navigation frame jump to a specified section within that frame. Create a table with Background image for each cell with caption and heading. Design a form with Label, Textbox and a Submit Button. Design a form with Checkboxes and a Submit Button. Example size="2" size="+1" size="-1" face="Times" color="#eeff00" color="red" Purpose Defines the font size Increases the font size Decreases the font size Defines the font-name Defines the font color Defines the font color

10.3 Introduction to CSS

222

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Introduction to CSS CSS Syntax CSS Classes CSS IDs CSS Divisions CSS Spans CSS Margin CSS Padding CSS Text Properties CSS Font Properties CSS Anchors, Links CSS Backgrounds CSS Borders CSS width and Height Properties Classification Exercise

1 - Introduction to CSS
A CSS (cascading style sheet) file allows us to separate our web sites (X)HTML content from it's style. As always we use our (X)HTML file to arrange the content, but all of the presentation (fonts, colors, background, borders, text formatting, link effects & so on...) are accomplished within a CSS.At this point we have some choices of how to use the CSS, either internally or externally.

Internal Stylesheet
First we will explore the internal method. This way we are simply placing the CSS code within the <head></head> tags of each (X)HTML file we want to style with the CSS. The format for this is shown in the example below. <head> <title></title> <style type="text/css"> CSS Content Goes Here </style> </head> With this method each (X)HTML file contains the CSS code needed to style the page. Meaning that any changes we want to make to one page, will have to be made to all. This method can be good if we need to style only one page, or if we want different pages to have varying styles.

External Stylesheet

223

Next we will explore the external method. An external CSS file can be created with any text or HTML editor such as "Notepad" or "Dreamweaver". A CSS file contains no (X)HTML, only CSS. We simply save it with the .css file extension. We can link to the file externally by placing one of the following links in the head section of every (X)HTML file we want to style with the CSS file. <link rel="stylesheet" type="text/css" href="Path To stylesheet.css" /> <head> <title><title> <link rel="stylesheet" type="text/css"href="style.css" /> </head> <body> By using an external style sheet, all of our (X)HTML files link to one CSS file in order to style the pages. This means, that if we need to alter the design of all our pages, we only need to edit one .css file to make global changes to our entire website.Here are a few reasons this is better.

Easier Maintenance Reduced File Size Reduced Bandwidth Improved Flexibility

We can have both internal, external.

Inline Styles
Inline styles are defined right in the (X)HTML file along side the element we want to style. See example below. <p style="color: #ff0000;">Some red text</p> Some red text Inline styles will NOT allow the user to change styles of elements or text formatted this way

So, which is better?


So with all these various ways of inserting CSS into our (X)HTML files, we may now be asking well which is better, and if I use more than one method, in what order do these different ways load into my browser? All the various methods will cascade into a new "pseudo" stylesheet in the following order: 1. Inline Style (inside (X)HTML element) 2. Internal Style Sheet (inside the <head> tag) 3. External Style Sheet As far as which way is better, it depends on what we want to do. If we have only one file to style then placing it within the <head></head> tags (internal) will work fine. Though if we are planning on styling multiple files then the external file method is the way to go. 224

2 - CSS Syntax
The syntax for CSS is different than that of (X)HTML markup. Though it is not too confusing, once we take a look at it. It consists of only 3 parts. selector { property: value } The selector is the (X)HTML element that we want to style. The property is the actual property title, and the value is the style we apply to that property.Each selector can have multiple properties, and each property within that selector can have independent values. The property and value are seperated with a colon and contained within curly brackets. Multiple properties are seperated by a semi colon. Multiple values within a property are sperated by commas, and if an individual value contains more than one word we surround it with quotation marks. As shown below. body { background: #eeeeee; font-family: "Trebuchet MS", Verdana, Arial, serif; } As we can see in the above code I have seperated the color from the font-family with a semi-colon, seperated the various fonts with commas and contained the "Trebuchet MS" within quotations marks. The final result sets the body color to light grey, and sets the font to ones that most users will have installed on there computer.

Inheritance
When we nest one element inside another, the nested element will inherit the properties assigned to the containing element. Unless we modify the inner elements values independently. For example, a font declared in the body will be inherited by all text in the file no matter the containing element, unless we declare another font for a specific nested element. body {font-family: Verdana, serif;} Now all text within the (X)HTML file will be set to Verdana.If we wanted to style certain text with another font, like an h1 or a paragraph then we could do the following. h1 {font-family: Georgia, sans-serif;} p {font-family: Tahoma, serif;} Now all <h1> tags within the file will be set to Georgia and all <p> tags are set to Tahoma, leaving text within other elements unchanged from the body declaration of Verdana.

225

Combining Selectors
We can combine elements within one selector in the following fashion. h1, h2, h3, h4, h5, h6 { color: #009900; font-family: Georgia, sans-serif; } As we can see in the above code, I have grouped all the header elements into one selector. Each one is seperated by a comma. The final result of the above code sets all headers to green and to the specified font. If the user does not have the first font I declared it will go to another sans-serif font the user has installed on there computer.

Comment tags
Comments can be used to explain why we added certain selectors within our css file. So as to help others who may see our file, or to help us remember what we we're thinking at a later date. We can add comments that will be ignored by browsers in the following manner. /* This is a comment */ We will note that it begins with a / (forward slash) and than an * (asterisks) then the comment, then the closing tag which is just backward from the opening tag * (asterisks) then the / (forward slash).

3: CSS Classes
The class selector allows us to style items within the same (X)HTML element differently. Similiar to what I mentioned in the introduction about inline styles. Except with classes the style can be overwritten by changing out stylesheets. We can use the same class selector again and again within an (X)HTML file.To put it more simply, this sentence we are reading is defined in my CSS file with the following. p{ font-size: small; color: #333333 } Pretty simple, but lets say that I wanted to change the word "sentence" to green bold text, while leaving the rest of the sentence untouched. I would do the following to my (X)HTML file. <p> To put it more simply, this <span class="greenboldtext">sentence</span> we are reading is styled in my CSS file by the following. </p> Then in my CSS file I would add this style selector: .greenboldtext{ font-size: small; 226

color: #008080; font-weight: bold; } The final result would look like the following: To put it more simply, this sentence we are reading is styled in my CSS file by the following. Please note that a class selector begins with a (.) period. The reason I named it "greenboldtext" is for example purposes, we can name it whatever we want.

4: CSS IDs
IDs are similar to classes, except once a specific id has been declared it cannot be used again within the same (X)HTML file. I generally use IDs to style the layout elements of a page that will only be needed once, whereas I use classes to style text and such that may be declared multiple times.The main container for this page is defined by the following. <div id="container"> Everything within my document is inside this division. </div> I have chosen the id selector for the "container" division over a class, because I only need to use it one time within this file. Then is my CSS file I have the following: #container{ width: 80%; margin: auto; padding: 20px; border: 1px solid #666; background: #ffffff; } We will notice that the id selector begins with a (#) number sign instead of a (.) period, as the class selector does.

5: CSS Divisions
Divisions are a block level (X)HTML element used to define sections of an (X)HTML file. A division can contain all the parts that make up our website. Including additional divisions, spans, images, text and so on.We define a division within an (X)HTML file by placing the following between the <body></body> tags: <div> Site contents go here </div> Though most likely we will want to add some style to it. We can do that in the following fashion: <div id="container"> Site contents go here </div> 227

The CSS file contains this: #container{ width: 70%; margin: auto; padding: 20px; border: 1px solid #666; background: #ffffff; } Now everything within that division will be styled by the "container" style rule, I defined within my CSS file. A division creates a linebreak by default. We can use both classes and IDs with a division tag to style sections of our website.

6: CSS Spans
Spans are very similar to divisions except they are an inline element versus a block level element. No linebreak is created when a span is declared. We can use the span tag to style certain areas of text, as shown in the following: <span class="italic">This text is italic</span> Then in my CSS file: .italic{ font-style: italic; } The final result is: This text is italic.

7: CSS Margins
Inherited: No
As we may have guessed, the margin property declares the margin between an (X)HTML element and the elements around it. The margin property can be set for the top, left, right and bottom of an element. (see example below) margin-top: length percentage or auto; margin-left: length percentage or auto; margin-right: length percentage or auto; margin-bottom: length percentage or auto; As we can also see in the above example we have 3 choices of values for the margin property

length percentage auto

We can also declare all the margins of an element in a single property as follows: margin: 10px 10px 10px 10px; 228

If we declare all 4 values as I have above, the order is as follows: 1. top 2. right 3. bottom 4. left If only one value is declared, it sets the margin on all sides. (see below) margin: 10px; If we only declare two or three values, the undeclared values are taken from the opposing side. (see below) margin: 10px 10px; /* 2 values */ margin: 10px 10px 10px; /* 3 values */ We can see in the example below, the elements for this site are set to be 20px (pixels) from the body body{ margin: 20px; background: #eeeeee; font-size: small; font-family: Tahoma, Arial, "Trebuchet MS", Helvetica, sans-serif; text-align: left; }

8: CSS Padding
Inherited: No
Padding is the distance between the border of an (X)HTML element and the content within it.Most of the rules for margins also apply to padding, except there is no "auto" value, and negative values cannot be declared for padding. padding-top: length percentage; padding-left: length percentage; padding-right: length percentage; padding-bottom: length percentage; As we can also see in the above example we have 2 choices of values for the padding property

length percentage

We can also declare all the padding of an element in a single property as follows: padding: 10px 10px 10px 10px; If we declare all 4 values as I have above, the order is as follows:

229

1. top 2. right 3. bottom 4. left If we do not declare the padding value of an element, the padding is 0 (zero). Note: We do not have to add px (pixels) or whatever units we use, if the value is 0 (zero). We can see in the example below, the main container for this site has 30px (pixels) of padding between the border and the text. #container{ width: 70%; margin: auto; padding: 30px; border: 1px solid #666; background: #ffffff; }

9: CSS Text Properties


Inherited: Yes

Color
We can set the color of text with the following: color: value; Possible values are

color name - example:(red, black...) hexadecimal number - example:(#ff0000, #000000) RGB color code - example:(rgb(255, 0, 0), rgb(0, 0, 0))

Text Align
We can align text with the following: text-align: value; Possible values are

left right center justify

Text Decoration
230

We can decorate text with the following: text-decoration: value; Possible values are

none underline overline line through blink

10: CSS Font Properties


Inherited: Yes

Font
The font property can set the style, weight, variant, size, line height and font: font: italic bold normal small/1.4em Verdana, sans-serif; The above would set the text of an element to an italic style a bold weight a normal variant a relative size a line height of 1.4em and the font to Verdana or another sans-serif typeface.

Font-Family
We can set what font will be displayed in an element with the font-family property.There are 2 choices for values:

family-name

generic family

If we set a family name it is best to also add the generic family at the end. As this is a priortized list. So if the user does not have the specified font name it will use the same generic family. (see below) font-family: Verdana, sans-serif;

Font Size
We can set the size of the text used in an element by using the font-size property. font-size: value; There are alot of choices for values:

xx-large x-large larger 231

large medium small smaller x-small xx-small length % (percent)

Font Style
We can set the style of text in a element with the font-style property font-style: value; Possible values are

normal itailc oblique

11: CSS Anchors, Links


Below are the various ways we can use CSS to style links. a:link {color: #009900;} a:visited {color: #999999;} a:hover {color: #333333;} a:focus {color: #333333;} a:active {color: #009900;} Now lets take a look at what each one of the above link styles actually does. The first on the list sets the color of a link when no event is occuring. The second sets the color a link changes to, when the user has already visited that url. The third sets the color a link changes to as the user places their mouse pointer over the link. The fourth is primarilly for the same purpose as the last one, but this one is for users that are not using a mouse and are tabbing through the links via there keyboards tab key, it sets the color a link changes to as the user tabs through the links. The fifth on the list sets the color a link changes to as it is pressed. We must declare the a:link and a:visited before we declare a:hover. Furthermore, we must declare a:hover before we can declare a:active.

12: CSS Backgrounds


Inherited: No
232

Background
We can style the background of an element in one declaration with the background property. background: #ffffff url(path_to_image) top left no-repeat fixed; Values:

attachment color image position repeat

Or we can set each property individually

Background Attachment
If we are using an image as a background. We can set whether the background scrolls with the page or is fixed when the user scrolls down the page with the background-attachment property background-attachment: value; Values:

fixed scroll

Background Color
We can specifically declare a color for the background of an element using the background-color property. background-color: value; Values:

color name hexadecimal number RGB color code transparent

Background Image
We can set an image for the background of an element using the background-image property. background-image: url(path_to_image); Values: 233


[[

url none

Background Position
We can position an image used for the background of an element using the backgroundposition property. background-position: value; Values:

top left top center top right center left center center center right bottom left bottom center bottom right x-% y-% x-pos y-pos

Background Repeat
We can set if an image set as a background of an element is to repeat (across=x and/or down=y) the screen using the background-repeat property. background-repeat: value; Values:

no-repeat repeat repeat-x repeat-y

13: CSS Borders


Inherited: No

Border

234

We can set the color, style and width of the borders around an element in one declaration by using the border property. border: 1px solid #333333; Values:

color style width

Or we can set each property individually

Border Color
We can set the color of a border independently with the border-color property. border-color: value; Values:

color name hexadecimal number RGB color code transparent

235

Border Style
We can set the style of a border independently with the border-style property. border-style: value; Values:

dashed dotted double groove hidden inset none outset ridge solid

Border Width
We can set the width of a border independently with the border-width property. border-width: value; Values:

Length Thin Medium Thick

Or we can set the elements for each borders side individually

Border Bottom
We can set the color, style and width of the bottom border around an element in one declaration with the border-bottom property. border-bottom: 1px solid #333333; Values:

color style width

236

Or we can set each value individually border-bottom-color: value; border-bottom-style: value; border-bottom-width: value;

Border Left
We can set the color, style and width of the left border around an element with the border-left property. border-left: 1px solid #333333; Values:

color style width

Or we can set each value individually border-left-color: value; border-left-style: value; border-left-width: value;

Border Right
We can set the color, style and width of the right border around an element in one declaration with the border-right property. border-right: 1px solid #333333; Values:

color style width

Or we can set each value individually border-right-color: value; border-right-style: value; border-right-width: value;

Border Top
We can set the color, style and width of the top border around an element in one declaration with the border-top property. border-top: 1px solid #333333;

237

Values:

color style width

Or we can set each value individually border-top-color: value; border-top-style: value; border-top-width: value;

14 - CSS Width and Height Properties


Inherited: No

Height
We can control the height of an element with the height property height: value; Values:

auto length percentage

Line Height
We can control the height between lines with the line-height property line-height: value; Values:

normal number length percentage

Max Height
We can control the maximum height of an element with the max-height property max-height: value; Values:

none length 238

percentage

Min Height
We can control the minimum height of an element with the min-height property min-height: value; Values:

length percentage

Width
We can control the width of an element with the width property width: value; Values:

auto length percentage

Max Width
We can control the maximum width of an element with the max-width property max-width: value; Values:

none length percentage

Min Width
We can control the minimum width of an element with the min-width property min-width: value; Values:

length percentage

239

15 - CSS Classification
Inherited: No

Clear
We can control if an element allows floated elements to its sides with the clear property clear: value; Values:

none both left right

Now, what does all that mean?

None
This is the default setting, floated elements can appear on either side of the element set to clear: none;

Both
Setting the value to both, causes no floated elements to appear on either side of the element set to clear: both;

Left
Setting the value to left, causes no floated elements to appear to the left side of the element set to clear: left;

Right
Setting the value to right, causes no floated elements to appear to the right side of the element set to clear: right;

Display
We can control how an element is displayed with the display property display: value; Values:

block inline list-item none

Now, what does all that mean?

240

Block
Creates a line break before and after the element

Inline
No line break is created

List Item
Creates a line break before and after the element and adds a list item marker

None
Makes an element not display on the page

Exercise : Create a web Page with the following Properties


Set an image as the background Set the color of the text Decorate the text Set the size and style of the font Set different borders on each side Set the color and width of the four borders Set the left, right, top, bottom margin of a text

241

10.4 Introduction to javascript


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Introduction to JavaScript JavaScript How to JavaScript Where to Variables If..Else Statements Switch Statements Operators Popup Boxes Functions JavaScript Loops Break & Continue Events JavaScript Guidelines JavaScript Object Introduction String Object Date Object Array Object Math Object DOM Object

1 - Introduction to JavaScript JavaScript is used in millions of Web pages to improve the design, validate forms, detect browsers, create cookies, and much more. JavaScript is the most popular scripting language on the internet, and works in all major browsers, such as Internet Explorer, Mozilla, Firefox, Netscape, Opera. What We Should Already Know Before we continue we should have a basic understanding of the following: HTML / XHTML What is JavaScript? JavaScript was designed to add interactivity to HTML pages JavaScript is a scripting language (a scripting language is a lightweight programming language) A JavaScript consists of lines of executable computer code

242

A JavaScript is usually embedded directly into HTML pages JavaScript is an interpreted language (means that scripts execute without preliminary compilation) Everyone can use JavaScript without purchasing a license Are Java and JavaScript the Same? NO! Java and JavaScript are two completely different languages in both concept and design! Java (developed by Sun Microsystems) is a powerful and much more complex programming language - in the same category as C and C++. What can a JavaScript Do? JavaScript gives HTML designers a programming tool - HTML authors are normally not programmers, but JavaScript is a scripting language with a very simple syntax! Almost anyone can put small "snippets" of code into their HTML pages JavaScript can put dynamic text into an HTML page - A JavaScript statement like this: document.write("<h1>" + name + "</h1>") can write a variable text into an HTML page JavaScript can react to events - A JavaScript can be set to execute when something happens, like when a page has finished loading or when a user clicks on an HTML element JavaScript can read and write HTML elements - A JavaScript can read and change the content of an HTML element JavaScript can be used to validate data - A JavaScript can be used to validate form data before it is submitted to a server, this will save the server from extra processing JavaScript can be used to detect the visitor's browser - A JavaScript can be used to detect the visitor's browser, and - depending on the browser - load another page specifically designed for that browser JavaScript can be used to create cookies - A JavaScript can be used to store and retrieve information on the visitor's computer

2 - JavaScript How To ... How to Put a JavaScript Into an HTML Page <html> <body> <script type="text/javascript"> document.write("Hello World!") </script> </body> </html> The code above will produce this output on an HTML page:

243

Hello World! Example Explained To insert a JavaScript into an HTML page, we use the <script> tag (also use the type attribute to define the scripting language). So, the <script type="text/javascript"> and </script> tells where the JavaScript starts and ends: <html> <body> <script type="text/javascript"> ... </script> </body> </html> The word document.write is a standard JavaScript command for writing output to a page. By entering the document.write command between the <script type="text/javascript"> and </script> tags, the browser will recognize it as a JavaScript command and execute the code line. In this case the browser will write Hello World! to the page: <html> <body> <script type="text/javascript"> document.write("Hello World!") </script> </body> </html> Note: If we had not entered the <script> tag, the browser would have treated the document.write("Hello World!") command as pure text, and just write the entire line on the page. Ending Statements With a Semicolon? With traditional programming languages, like C++ and Java, each code statement has to end with a semicolon. Many programmers continue this habit when writing JavaScript, but in general, semicolons are optional! However, semicolons are required if we want to put more than one statement on a single line. How to Handle Older Browsers Browsers that do not support JavaScript will display the script as page content. To prevent them from doing this, we may use the HTML comment tag: <script type="text/javascript"> <!--

244

document.write("Hello World!") //--> </script> The two forward slashes at the end of comment line (//) are a JavaScript comment symbol. This prevents the JavaScript compiler from compiling the line. 3 - JavaScript Where To ... JavaScripts in the body section will be executed WHILE the page loads. JavaScripts in the head section will be executed when CALLED. Where to Put the JavaScript JavaScripts in a page will be executed immediately while the page loads into the browser. This is not always what we want. Sometimes we want to execute a script when a page loads, other times when a user triggers an event. Scripts in the head section: Scripts to be executed when they are called, or when an event is triggered, go in the head section. When we place a script in the head section, we will ensure that the script is loaded before anyone uses it. <html> <head> <script type="text/javascript"> .... </script> </head> Scripts in the body section: Scripts to be executed when the page loads go in the body section. When we place a script in the body section it generates the content of the page. <html> <head> </head> <body> <script type="text/javascript"> .... </script> </body>

245

Scripts in both the body and the head section: We can place an unlimited number of scripts in our document, so we can have scripts in both the body and the head section. <html> <head> <script type="text/javascript"> .... </script> </head> <body> <script type="text/javascript"> .... </script> </body> Using an External JavaScript Sometimes we might want to run the same JavaScript on several pages, without having to write the same script on every page. To simplify this, we can write a JavaScript in an external file. Save the external JavaScript file with a .js file extension. Note: The external script cannot contain the <script> tag! To use the external script, point to the .js file in the "src" attribute of the <script> tag: <html> <head> <script src="xxx.js"></script> </head> <body> </body> </html> Note: Remember to place the script exactly where we normally would write the script! A variable is a "container" for information we want to store. 4 Variables A variable is a "container" for information we want to store. A variable's value can change during the script. We can refer to a variable by name to see its value or to change its value. Rules for variable names: 246

Variable names are case sensitive They must begin with a letter or the underscore character IMPORTANT! JavaScript is case-sensitive! A variable named strname is not the same as a variable named STRNAME! Declare a Variable We can create a variable with the var statement:

var strname = some value We can also create a variable without the var statement: strname = some value Assign a Value to a Variable We can assign a value to a variable like this: var strname = "Hege" Or like this: strname = "Hege" The variable name is on the left side of the expression and the value we want to assign to the variable is on the right. Now the variable "strname" has the value "Hege". Lifetime of Variables When we declare a variable within a function, the variable can only be accessed within that function. When we exit the function, the variable is destroyed. These variables are called local variables. We can have local variables with the same name in different functions, because each is recognized only by the function in which it is declared. If we declare a variable outside a function, all the functions on our page can access it. The lifetime of these variables starts when they are declared, and ends when the page is closed. 5 - JavaScript If...Else Statements Conditional statements in JavaScript are used to perform different actions based on different conditions. Conditional Statements Very often when we write code, we want to perform different actions for different decisions. We can use conditional statements in our code to do this. In JavaScript we have the following conditional statements: if statement - use this statement if we want to execute some code only if a specified condition is true if...else statement - use this statement if we want to execute some code if the condition is true and another code if the condition is false 247

if...else if....else statement - use this statement if we want to select one of many blocks of code to be executed switch statement - use this statement if we want to select one of many blocks of code to be executed If Statement We should use the if statement if we want to execute some code only if a specified condition is true.

Syntax: if (condition) { code to be executed if condition is true } Note that if is written in lowercase letters. Using uppercase letters (IF) will generate a JavaScript error! Example <script type="text/javascript"> //Write a "Good morning" greeting if //the time is less than 10 var d=new Date() var time=d.getHours() if (time<10) { document.write("<b>Good morning</b>") } </script> Note: When comparing variables we must always use two equals signs next to each other (==)! Notice that there is no ..else.. in this syntax. We just tell the code to execute some code only if the specified condition is true. If...else Statement If we want to execute some code if a condition is true and another code if the condition is not true, use the if....else statement.

248

Syntax if (condition) { code to be executed if condition is true } else { code to be executed if condition is not true } Example <script type="text/javascript"> //If the time is less than 10, //we will get a "Good morning" greeting. //Otherwise we will get a "Good day" greeting. var d = new Date() var time = d.getHours() if (time < 10) { document.write("Good morning!") } else { document.write("Good day!") } </script> If...else if...else Statement We should use the if....else if...else statement if we want to select one of many sets of lines to execute. Syntax if (condition1) { code to be executed if condition1 is true

249

} else if (condition2) { code to be executed if condition2 is true } else { code to be executed if condition1 and condition2 are not true } Example <script type="text/javascript"> var d = new Date() var time = d.getHours() if (time<10) { document.write("<b>Good morning</b>") } else if (time>10 && time<16) { document.write("<b>Good day</b>") } else { document.write("<b>Hello World!</b>") } </script> 6 - JavaScript Switch Statement Conditional statements in JavaScript are used to perform different actions based on different conditions. The JavaScript Switch Statement We should use the switch statement if we want to select one of many blocks of code to be executed. 250

Syntax switch(n) { case 1: execute code block 1 break case 2: execute code block 2 break default: code to be executed if n is different from case 1 and 2 } This is how it works: First we have a single expression n (most often a variable), that is evaluated once. The value of the expression is then compared with the values for each case in the structure. If there is a match, the block of code associated with that case is executed. Use break to prevent the code from running into the next case automatically. Example <script type="text/javascript"> //We will receive a different greeting based //on what day it is. Note that Sunday=0, //Monday=1, Tuesday=2, etc. var d=new Date() theDay=d.getDay() switch (theDay) { case 5: document.write("Finally Friday") break case 6: document.write("Super Saturday") break case 0: document.write("Sleepy Sunday") break

251

default: document.write("I'm looking forward to this weekend!") } </script> 7 - JavaScript Operators Arithmetic Operators Operator + Description Addition Example x=2 y=2 x+y x=5 y=2 x-y x=5 y=4 x*y 15/5 5/2 5%2 10%8 10%2 x=5 x++ x=5 x-Result 4

Subtraction

Multiplication

20

/ %

Division Modulus (division remainder)

3 2.5 1 2 0 x=6 x=4

++ --

Increment Decrement

Assignment Operators Operator = += -= *= Example x=y x+=y x-=y x*=y Is The Same As x=y x=x+y x=x-y x=x*y

252

/= %=

x/=y x%=y

x=x/y x=x%y

Comparison Operators Operator == === Description is equal to Example 5==8 returns false

is equal to (checks for both value and type) x=5 y="5" x==y returns x===y returns false is not equal is greater than is less than is greater than or equal to is less than or equal to 5!=8 returns true 5>8 returns false 5<8 returns true 5>=8 returns false 5<=8 returns true

true

!= > < >= <=

253

Logical Operators Operator && Description and Example x=6 y=3 (x < 10 && y > 1) returns true x=6 y=3 (x==5 || y==5) returns false x=6 y=3 !(x==y) returns true

||

or

not

String Operator A string is most often text, for example "Hello World!". To stick two or more string variables together, use the + operator. txt1="What a very" txt2="nice day!" txt3=txt1+txt2 The variable txt3 now contains "What a verynice day!". To add a space between two string variables, insert a space into the expression, OR in one of the strings. txt1="What a very" txt2="nice day!" txt3=txt1+" "+txt2 or txt1="What a very " txt2="nice day!" txt3=txt1+txt2 The variable txt3 now contains "What a very nice day!".

254

Conditional Operator JavaScript also contains a conditional operator that assigns a value to a variable based on some condition. Syntax variablename=(condition)?value1:value2 Example greeting=(visitor=="PRES")?"Dear President ":"Dear " If the variable visitor is equal to PRES, then put the string "Dear President " in the variable named greeting. If the variable visitor is not equal to PRES, then put the string "Dear " into the variable named greeting. 8 - JavaScript Popup Boxes In JavaScript we can create three kinds of popup boxes: Alert box, Confirm box, and Prompt box. Alert Box An alert box is often used if we want to make sure information comes through to the user. When an alert box pops up, the user will have to click "OK" to proceed. Syntax: alert("sometext") Confirm Box A confirm box is often used if we want the user to verify or accept something. When a confirm box pops up, the user will have to click either "OK" or "Cancel" to proceed. If the user clicks "OK", the box returns true. If the user clicks "Cancel", the box returns false. Syntax: confirm("sometext") Prompt Box A prompt box is often used if we want the user to input a value before entering a page. When a prompt box pops up, the user will have to click either "OK" or "Cancel" to proceed after entering an input value. If the user clicks "OK" the box returns the input value. If the user clicks "Cancel" the box returns null. Syntax: prompt("sometext","defaultvalue")

255

Chapter 9 - JavaScript Functions A function is a reusable code-block that will be executed by an event, or when the function is called. JavaScript Functions To keep the browser from executing a script as soon as the page is loaded, we can write our script as a function. A function contains some code that will be executed only by an event or by a call to that function. We may call a function from anywhere within the page (or even from other pages if the function is embedded in an external .js file). Functions are defined at the beginning of a page, in the <head> section. Example <html> <head> <script type="text/javascript"> function displaymessage() { alert("Hello World!") } </script> </head> <body> <form> <input type="button" value="Click me!" onclick="displaymessage()" > </form> </body> </html> If the line: alert("Hello world!!"), in the example above had not been written within a function, it would have been executed as soon as the line was loaded. Now, the script is not executed before the user hits the button. We have added an onClick event to the button that will execute the function displaymessage() when the button is clicked. How to Define a Function The syntax for creating a function is: function functionname(var1,var2,...,varX) { 256

some code } var1, var2, etc are variables or values passed into the function. The { and the } defines the start and end of the function. Note: A function with no parameters must include the parentheses () after the function name: function functionname() { some code } Note: Do not forget about the importance of capitals in JavaScript! The word function must be written in lowercase letters, otherwise a JavaScript error occurs! Also note that we must call a function with the exact same capitals as in the function name. The return Statement The return statement is used to specify the value that is returned from the function. So, functions that are going to return a value must use the return statement. Example The function below should return the product of two numbers (a and b): function prod(a,b) { x=a*b return x } When we call the function above, we must pass along two parameters: product=prod(2,3) The returned value from the prod() function is 6, and it will be stored in the variable called product.

10 JavaScript Loops Loops in JavaScript are used to execute the same block of code a specified number of times or while a specified condition is true. JavaScript Loops

257

Very often when we write code, we want the same block of code to run over and over again in a row. Instead of adding several almost equal lines in a script we can use loops to perform a task like this. In JavaScript there are two different kind of loops: for - loops through a block of code a specified number of times while - loops through a block of code while a specified condition is true The for Loop The for loop is used when we know in advance how many times the script should run. Syntax for (var=startvalue;var<=endvalue;var=var+increment) { code to be executed } Example Explanation: The example below defines a loop that starts with i=0. The loop will continue to run as long as i is less than, or equal to 10. i will increase by 1 each time the loop runs. Note: The increment parameter could also be negative, and the <= could be any comparing statement. <html> <body> <script type="text/javascript"> var i=0 for (i=0;i<=10;i++) { document.write("The number is " + i) document.write("<br />") } </script> </body> </html> Result The number is 0 The number is 1 The number is 2 The number is 3 The number is 4 258

The number is 5 The number is 6 The number is 7 The number is 8 The number is 9 The number is 10 JavaScript While Loop Loops in JavaScript are used to execute the same block of code a specified number of times or while a specified condition is true. The while loop The while loop is used when we want the loop to execute and continue executing while the specified condition is true. while (var<=endvalue) { code to be executed } Note: The <= could be any comparing statement. Example Explanation: The example below defines a loop that starts with i=0. The loop will continue to run as long as i is less than, or equal to 10. i will increase by 1 each time the loop runs. <html> <body> <script type="text/javascript"> var i=0 while (i<=10) { document.write("The number is " + i) document.write("<br />") i=i+1 } </script> </body> </html> Result 259

The number is 0 The number is 1 The number is 2 The number is 3 The number is 4 The number is 5 The number is 6 The number is 7 The number is 8 The number is 9 The number is 10 The do...while Loop The do...while loop is a variant of the while loop. This loop will always execute a block of code ONCE, and then it will repeat the loop as long as the specified condition is true. This loop will always be executed at least once, even if the condition is false, because the code is executed before the condition is tested. do { code to be executed } while (var<=endvalue) Example <html> <body> <script type="text/javascript"> var i=0 do { document.write("The number is " + i) document.write("<br />") i=i+1 } while (i<0) </script> </body> 260

</html> Result The number is 0 11 - JavaScript Break and Continue There are two special statements that can be used inside loops: break and continue. JavaScript break and continue Statements There are two special statements that can be used inside loops: break and continue. Break The break command will break the loop and continue executing the code that follows after the loop (if any). Example <html> <body> <script type="text/javascript"> var i=0 for (i=0;i<=10;i++) { if (i==3){break} document.write("The number is " + i) document.write("<br />") } </script> </body> </html> Result The number is 0 The number is 1 The number is 2 Continue The continue command will break the current loop and continue with the next value. Example

261

<html> <body> <script type="text/javascript"> var i=0 for (i=0;i<=10;i++) { if (i==3){continue} document.write("The number is " + i) document.write("<br />") } </script> </body> </html> Result The number is 0 The number is 1 The number is 2 The number is 4 The number is 5 The number is 6 The number is 7 The number is 8 The number is 9 The number is 10

JavaScript For...In Statement The for...in statement is used to loop (iterate) through the elements of an array or through the properties of an object. JavaScript For...In Statement The for...in statement is used to loop (iterate) through the elements of an array or through the properties of an object. The code in the body of the for ... in loop is executed once for each element/property. Syntax for (variable in object) 262

{ code to be executed } The variable argument can be a named variable, an array element, or a property of an object. Example Using for...in to loop through an array: <html> <body> <script type="text/javascript"> var x var mycars = new Array() mycars[0] = "Saab" mycars[1] = "Volvo" mycars[2] = "BMW" for (x in mycars) { document.write(mycars[x] + "<br />") } </script> </body> </html>

263

12 - JavaScript Events Events are actions that can be detected by JavaScript. Events By using JavaScript, we have the ability to create dynamic web pages. Events are actions that can be detected by JavaScript.Every element on a web page has certain events which can trigger JavaScript functions. For example, we can use the onClick event of a button element to indicate that a function will run when a user clicks on the button. We define the events in the HTML tags. Examples of events: A mouse click A web page or an image loading Mousing over a hot spot on the web page Selecting an input box in an HTML form Submitting an HTML form A keystroke The following table lists the events recognized by JavaScript: Note: Events are normally used in combination with functions, and the function will not be executed before the event occurs! onload and onUnload The onload and onUnload events are triggered when the user enters or leaves the page. The onload event is often used to check the visitor's browser type and browser version, and load the proper version of the web page based on the information. Both the onload and onUnload events are also often used to deal with cookies that should be set when a user enters or leaves a page. For example, we could have a popup asking for the user's name upon his first arrival to our page. The name is then stored in a cookie. Next time the visitor arrives at our page, we could have another popup saying something like: "Welcome John Doe!". onFocus, onBlur and onChange The onFocus, onBlur and onChange events are often used in combination with validation of form fields. Below is an example of how to use the onChange event. The checkEmail() function will be called whenever the user changes the content of the field: <input type="text" size="30" id="email" onchange="checkEmail()">; onSubmit The onSubmit event is used to validate ALL form fields before submitting it. Below is an example of how to use the onSubmit event. The checkForm() function will be called when the user clicks the submit button in the form. If the field values are not accepted, the submit should be cancelled. The function checkForm() returns either true or false. If it returns true the form will be submitted, otherwise the submit will be cancelled: 264

<form method="post" action="xxx.htm" onsubmit="return checkForm()"> onMouseOver and onMouseOut onMouseOver and onMouseOut are often used to create "animated" buttons. Below is an example of an onMouseOver event. An alert box appears when an onMouseOver event is detected: <a href="http://www.w3schools.com" onmouseover="alert('An onMouseOver event');return false"> <img src="cegon.gif" width="100" height="30"> </a> 13 - JavaScript Guidelines Some other important things to know when scripting with JavaScript. JavaScript is Case Sensitive A function named "myfunction" is not the same as "myFunction" and a variable named "myVar" is not the same as "myvar". JavaScript is case sensitive - therefore watch our capitalization closely when we create or call variables, objects and functions. White Space JavaScript ignores extra spaces. We can add white space to our script to make it more readable. The following lines are equivalent: name="Hege" name = "Hege"

265

Break up a Code Line We can break up a code line within a text string with a backslash. The example below will be displayed properly: document.write("Hello \ World!") However, we cannot break up a code line like this: document.write \ ("Hello World!") Comments We can add comments to our script by using two slashes //: //this is a comment document.write("Hello World!") or by using /* and */ (this creates a multi-line comment block): /* This is a comment block. It contains several lines */ document.write("Hello World!") 14 - JavaScript Objects Introduction JavaScript is an Object Oriented Programming (OOP) language. An OOP language allows us to define our own objects and make our own variable types. Object Oriented Programming JavaScript is an Object Oriented Programming (OOP) language. An OOP language allows us to define our own objects and make our own variable types. However, creating our own objects will be explained later, in the Advanced JavaScript section. We will start by looking at the built-in JavaScript objects, and how they are used. The next pages will explain each built-in JavaScript object in detail. Note that an object is just a special kind of data. An object has properties and methods. Properties Properties are the values associated with an object. In the following example we are using the length property of the String object to return the number of characters in a string: <script type="text/javascript"> var txt="Hello World!"

266

document.write(txt.length) </script> The output of the code above will be: 12 Methods Methods are the actions that can be performed on objects. In the following example we are using the toUpperCase() method of the String object to display a text in uppercase letters: <script type="text/javascript"> var str="Hello world!" document.write(str.toUpperCase()) </script> The output of the code above will be: HELLO WORLD! 15 - JavaScript String Object The String object is used to manipulate a stored piece of text. String object The String object is used to manipulate a stored piece of text. Examples of use: The following example uses the length property of the String object to find the length of a string: var txt="Hello world!" document.write(txt.length) The code above will result in the following output: 12 The following example uses the toUpperCase() method of the String object to convert a string to uppercase letters: var txt="Hello world!" document.write(txt.toUpperCase()) The code above will result in the following output: HELLO WORLD! 267

Complete String Object Reference The reference contains a brief description and examples of use for each property and method! 16 - JavaScript Date Object The Date object is used to work with dates and times. Defining Dates The Date object is used to work with dates and times. We define a Date object with the new keyword. The following code line defines a Date object called myDate: var myDate=new Date() Note: The Date object will automatically hold the current date and time as its initial value! Manipulate Dates We can easily manipulate the date by using the methods available for the Date object. In the example below we set a Date object to a specific date (14th January 2010): var myDate=new Date() myDate.setFullYear(2010,0,14) And in the following example we set a Date object to be 5 days into the future: var myDate=new Date() myDate.setDate(myDate.getDate()+5) Note: If adding five days to a date shifts the month or year, the changes are handled automatically by the Date object itself! Comparing Dates The Date object is also used to compare two dates. The following example compares today's date with the 14th January 2010: var myDate=new Date() myDate.setFullYear(2010,0,14) var today = new Date() if (myDate>today) alert("Today is before 14th January 2010") else alert("Today is after 14th January 2010") 17 - JavaScript Array Object

268

The Array object is used to store a set of values in a single variable name. Defining Arrays The Array object is used to store a set of values in a single variable name. We define an Array object with the new keyword. The following code line defines an Array object called myArray: var myArray=new Array() There are two ways of adding values to an array (we can add as many values as we need to define as many variables we require). 1: var mycars=new Array() mycars[0]="Saab" mycars[1]="Volvo" mycars[2]="BMW" We could also pass an integer argument to control the array's size: var mycars=new Array(3) mycars[0]="Saab" mycars[1]="Volvo" mycars[2]="BMW" 2: var mycars=new Array("Saab","Volvo","BMW") Note: If we specify numbers or true/false values inside the array then the type of variables will be numeric or Boolean instead of string. Accessing Arrays We can refer to a particular element in an array by referring to the name of the array and the index number. The index number starts at 0. The following code line: document.write(mycars[0]) will result in the following output: Saab Modify Values in Existing Arrays To modify a value in an existing array, just add a new value to the array with a specified index number: mycars[0]="Opel" Now, the following code line: 269

document.write(mycars[0]) will result in the following output: Opel 18 - JavaScript Math Object The Math object allows us to perform common mathematical tasks. Math Object The Math object allows us to perform common mathematical tasks. The Math object includes several mathematical values and functions. We do not need to define the Math object before using it. Mathematical Values JavaScript provides eight mathematical values (constants) that can be accessed from the Math object. These are: E, PI, square root of 2, square root of 1/2, natural log of 2, natural log of 10, base-2 log of E, and base-10 log of E. We may reference these values from our JavaScript like this: Math.E Math.PI Math.SQRT2 Math.SQRT1_2 Math.LN2 Math.LN10 Math.LOG2E Math.LOG10E Mathematical Methods In addition to the mathematical values that can be accessed from the Math object there are also several functions (methods) available. Examples of functions (methods): The following example uses the round() method of the Math object to round a number to the nearest integer: document.write(Math.round(4.7)) The code above will result in the following output: 5

270

The following example uses the random() method of the Math object to return a random number between 0 and 1: document.write(Math.random()) The code above can result in the following output: 0.2623696985200651 The following example uses the floor() and random() methods of the Math object to return a random number between 0 and 10: document.write(Math.floor(Math.random()*11)) The code above can result in the following output: 1 19 - JavaScript HTML DOM Objects In addition to the built-in JavaScript objects, we can also access and manipulate all of the HTML DOM objects with JavaScript. The HTML DOM The HTML DOM is a W3C standard and it is an abbreviation for the Document Object Model for HTML. The HTML DOM defines a standard set of objects for HTML, and a standard way to access and manipulate HTML documents. All HTML elements, along with their containing text and attributes, can be accessed through the DOM. The contents can be modified or deleted, and new elements can be created. The HTML DOM is platform and language independent. It can be used by any programming language like Java, JavaScript, and VBScript. Follow the links below to learn more about how to access and manipulate each DOM object with JavaScript: Object Anchor Applet Area Base Basefont Body Button Description Represents an HTML a element (a hyperlink) Represents an HTML applet element. The applet element is used to place executable content on a page Represents an area of an image-map. An image-map is an image with clickable regions Represents an HTML base element Represents an HTML basefont element Represents the body of the document (the HTML body) Represents a push button on an HTML form. For each instance of an 271

HTML <input type="button"> tag on an HTML form, a Button object is created Checkbox Represents a checkbox on an HTML form. For each instance of an HTML <input type="checkbox"> tag on an HTML form, a Checkbox object is created Used to access all elements in a page Represents the state of an event, such as the element in which the event occurred, the state of the keyboard keys, the location of the mouse, and the state of the mouse buttons For each instance of an HTML <input type="file"> tag on a form, a FileUpload object is created Forms are used to prompt users for input. Represents an HTML form element Represents an HTML frame Represents an HTML frameset Represents a hidden field on an HTML form. For each instance of an HTML <input type="hidden"> tag on a form, a Hidden object is created A predefined object which can be accessed through the history property of the Window object. This object consists of an array of URLs. These URLs are all the URLs the user has visited within a browser window Represents an HTML inline-frame Represents an HTML img element Represents an HTML link element. The link element can only be used within the <head> tag Contains information about the current URL Represents an HTML meta element Contains information about the client browser Represents an option in a selection list on an HTML form. For each instance of an HTML <option> tag in a selection list on a form, an Option object is created Represents a password field on an HTML form. For each instance of an HTML <input type="password"> tag on a form, a Password object is

Document Event

FileUpload Form Frame Frameset Hidden History

Iframe Image Link Location Meta Navigator Option

Password

272

created Radio Reset Screen Select Style Submit Table TableData TableHeader TableRow Text Textarea Window Represents radio buttons on an HTML form. For each instance of an HTML <input type="radio"> tag on a form, a Radio object is created Represents a reset button on an HTML form. For each instance of an HTML <input type="reset"> tag on a form, a Reset object is created Automatically created by the JavaScript runtime engine and it contains information about the client's display screen Represents a selection list on an HTML form. For each instance of an HTML <select> tag on a form, a Select object is created Represents an individual style statement. This object can be accessed from the document or from the elements to which that style is applied Represents a submit button on an HTML form. For each instance of an HTML <input type="submit"> tag on a form, a Submit object is created Represents an HTML table element Represents an HTML td element Represents an HTML th element Represents an HTML tr element Represents a text field on an HTML form. For each instance of an HTML <input type="text"> tag on a form, a Text object is created Represents an HTML textarea element Corresponds to the browser window. A Window object is created automatically with every instance of a <body> or <frameset> tag

10.5 UML
The heart of object-oriented problem solving is the construction of a model. The model abstracts the essential details of the underlying problem from its usually complicated real world. Several modeling tools are wrapped under the heading of the UML, which stands for Unified Modeling Language. The purpose of this course is to present important highlights of the UML. At the center of the UML are its nine kinds of modeling diagrams, which we describe here.

Use case diagrams Class diagrams Object diagrams

273

Sequence diagrams Collaboration diagrams Statechart diagrams Activity diagrams Component diagrams Deployment diagrams

Why is UML important?

Let's look at this question from the point of view of the construction trade. Architects design buildings. Builders use the designs to create buildings. The more complicated the building, the more critical the communication between architect and builder. Blueprints are the standard graphical language that both architects and builders must learn as part of their trade. Writing software is not unlike constructing a building. The more complicated the underlying system, the more critical the communication among everyone involved in creating and deploying the software. In the past decade, the UML has emerged as the software blueprint language for analysts, designers, and programmers alike. It is now part of the software trade. The UML gives everyone from business analyst to designer to programmer a common vocabulary to talk about software design. The UML is applicable to object-oriented problem solving. Anyone interested in learning UML must be familiar with the underlying tenet of object-oriented problem solving -- it all begins with the construction of a model. A model is an abstraction of the underlying problem. The domain is the actual world from which the problem comes. Models consist of objects that interact by sending each other messages. Think of an object as "alive." Objects have things they know (attributes) and things they can do (behaviors or operations). The values of an object's attributes determine its state. Classes are the "blueprints" for objects. A class wraps attributes (data) and behaviors (methods or functions) into a single distinct entity. Objects are instances of classes.

Use case diagrams


Use case diagrams describe what a system does from the standpoint of an external observer. The emphasis is on what a system does rather than how. Use case diagrams are closely connected to scenarios. A scenario is an example of what happens when someone interacts with the system. Here is a scenario for a medical clinic. "A patient calls the clinic to make an appointment for a yearly checkup. The receptionist finds the nearest empty time slot in the appointment book and schedules the appointment for that time slot. "

274

A use case is a summary of scenarios for a single task or goal. An actor is who or what initiates the events involved in that task. Actors are simply roles that people or objects play. The picture below is a Make Appointment use case for the medical clinic. The actor is a Patient. The connection between actor and use case is a communication association (or communication for short).

Actors are stick figures. Use cases are ovals. Communications are lines that link actors to use cases. A use case diagram is a collection of actors, use cases, and their communications. We've put Make Appointment as part of a diagram with four actors and four use cases. Notice that a single use case can have multiple actors.

Use case diagrams are helpful in three areas.


determining features (requirements). New use cases often generate new requirements as the system is analyzed and the design takes shape. communicating with clients. Their notational simplicity makes use case diagrams a good way for developers to communicate with clients. generating test cases. The collection of scenarios for a use case may suggest a suite of test cases for those scenarios.

Class diagrams

275

A Class diagram gives an overview of a system by showing its classes and the relationships among them. Class diagrams are static -- they display what interacts but not what happens when they do interact. The class diagram below models a customer order from a retail catalog. The central class is the Order. Associated with it are the Customer making the purchase and the Payment. A Payment is one of three kinds: Cash, Check, or Credit. The order contains OrderDetails (line items), each with its associated Item.

UML class notation is a rectangle divided into three parts: class name, attributes, and operations. Names of abstract classes, such as Payment, are in italics. Relationships between classes are the connecting links. Our class diagram has three kinds of relationships.

association -- a relationship between instances of the two classes. There is an association between two classes if an instance of one class must know about the other in order to perform its work. In a diagram, an association is a link connecting two classes. aggregation -- an association in which one class belongs to a collection. An aggregation has a diamond end pointing to the part containing the whole. In our diagram, Order has a collection of OrderDetails. generalization -- an inheritance link indicating one class is a superclass of the other. A generalization has a triangle pointing to the superclass. Payment is a superclass of Cash, Check, and Credit.

276

An association has two ends. An end may have a role name to clarify the nature of the association. For example, an OrderDetail is a line item of each Order. A navigability arrow on an association shows which direction the association can be traversed or queried. An OrderDetail can be queried about its Item, but not the other way around. The arrow also lets us know who "owns" the association's implementation; in this case, OrderDetail has an Item. Associations with no navigability arrows are bi-directional. The multiplicity of an association end is the number of possible instances of the class associated with a single instance of the other end. Multiplicities are single numbers or ranges of numbers. In our example, there can be only one Customer for each Order, but a Customer can have any number of Orders. This table gives the most common multiplicities. Multiplicities Meaning 0..1 zero or one instance. The notation n . . m indicates n to m instances. 0..* or * no limit on the number of instances (including none). 1 exactly one instance 1..* at least one instance Every class diagram has classes, associations, and multiplicities. Navigability and roles are optional items placed in a diagram to provide clarity. Packages and object diagrams To simplify complex class diagrams, we can group classes into packages. A package is a collection of logically related UML elements. The diagram below is a business model in which the classes are grouped into packages.

277

Packages appear as rectangles with small tabs at the top. The package name is on the tab or inside the rectangle. The dotted arrows are dependencies. One package depends on another if changes in the other could possibly force changes in the first. Object diagrams show instances instead of classes. They are useful for explaining small pieces with complicated relationships, especially recursive relationships. This small class diagram shows that a university Department can contain lots of other Departments.

The object diagram below instantiates the class diagram, replacing it by a concrete example.

Each rectangle in the object diagram corresponds to a single instance. Instance names are underlined in UML diagrams. Class or instance names may be omitted from object diagrams as long as the diagram meaning is still clear. Sequence diagrams Class and object diagrams are static model views. Interaction diagrams are dynamic. They describe how objects collaborate. A sequence diagram is an interaction diagram that details how operations are carried out -- what messages are sent and when. Sequence diagrams are organized according to time. The time progresses as we go down the page. The objects involved in the operation are listed from left to right according to when they take part in the message sequence. 278

Below is a sequence diagram for making a hotel reservation. The object initiating the sequence of messages is a Reservation window.

The Reservation window sends a makeReservation() message to a HotelChain. The HotelChain then sends a makeReservation() message to a Hotel. If the Hotel has available rooms, then it makes a Reservation and a Confirmation. Each vertical dotted line is a lifeline, representing the time that an object exists. Each arrow is a message call. An arrow goes from the sender to the top of the activation bar of the message on the receiver's lifeline. The activation bar represents the duration of execution of the message. In our diagram, the Hotel issues a self call to determine if a room is available. If so, then the Hotel creates a Reservation and a Confirmation. The asterisk on the self call means iteration (to make sure there is available room for each day of the stay in the hotel). The expression in square brackets, [ ], is a condition. The diagram has a clarifying note, which is text inside a dog-eared rectangle. Notes can be put into any kind of UML diagram. Collaboration diagrams

279

Collaboration diagrams are also interaction diagrams. They convey the same information as sequence diagrams, but they focus on object roles instead of the times that messages are sent. In a sequence diagram, object roles are the vertices and messages are the connecting links.

The object-role rectangles are labeled with either class or object names (or both). Class names are preceded by colons ( : ). Each message in a collaboration diagram has a sequence number. The top-level message is numbered 1. Messages at the same level (sent during the same call) have the same decimal prefix but suffixes of 1, 2, etc. according to when they occur. Statechart diagrams Objects have behaviors and state. The state of an object depends on its current activity or condition. A statechart diagram shows the possible states of the object and the transitions that cause a change in state. Our example diagram models the login part of an online banking system. Logging in consists of entering a valid social security number and personal id number, then submitting the information for validation. Logging in can be factored into four non-overlapping states: Getting SSN, Getting PIN, Validating, and Rejecting. From each state comes a complete set of transitions that determine the subsequent state. 280

States are rounded rectangles. Transitions are arrows from one state to another. Events or conditions that trigger transitions are written beside the arrows. Our diagram has two selftransition, one on Getting SSN and another on Getting PIN. The initial state (black circle) is a dummy to start the action. Final states are also dummy states that terminate the action. The action that occurs as a result of an event or condition is expressed in the form /action. While in its Validating state, the object does not wait for an outside event to trigger a transition. Instead, it performs an activity. The result of that activity determines its subsequent state. Activity diagrams An activity diagram is essentially a fancy flowchart. Activity diagrams and statechart diagrams are related. While a statechart diagram focuses attention on an object undergoing a process (or on a process as an object), an activity diagram focuses on the flow of activities involved in a single process. The activity diagram shows the how those activities depend on one another. For our example, we used the following process."Withdraw money from a bank account through an ATM." The three involved classes (people, etc.) of the activity are Customer, ATM, and Bank. The process begins at the black start circle at the top and ends at the concentric white/black stop

281

circles at the bottom. The activities are rounded rectangles.

Activity diagrams can be divided into object swimlanes that determine which object is responsible for which activity. A single transition comes out of each activity, connecting it to the next activity. A transition may branch into two or more mutually exclusive transitions. Guard expressions (inside [ ]) label the transitions coming out of a branch. A branch and its subsequent merge marking the end of the branch appear in the diagram as hollow diamonds. A transition may fork into two or more parallel activities. The fork and the subsequent join of the threads coming out of the fork appear in the diagram as solid bars. 282

Component and deployment diagrams A component is a code module. Component diagrams are physical analogs of class diagram. Deployment diagrams show the physical configurations of software and hardware. The following deployment diagram shows the relationships among software and hardware components involved in real estate transactions.

The physical hardware is made up of nodes. Each component belongs on a node. Components are shown as rectangles with two tabs at the upper left.

283

You might also like