Web Technology -III Unit - Notes

Web Technology -III Unit - Notes


Host Objects: Browsers and the DOM-Introduction to the Document Object Model DOM History and Levels-Intrinsic Event Handling-Modifying Element Style-The Document Tree-DOM Event Handling-Accommodating Noncompliant Browsers Properties of window-Case Study. Server-Side Programming: Java Servlets- Architecture -Overview-A Servelet-Generating Dynamic  Content-Life Cycle-Parameter Data-Sessions-Cookies- URL Rewriting-Other Capabilities-Data Storage Servlets and Concurrency-Case Study- Related Technologies.

HOST OBJECTS
3.1 INTRODUCTION TO THE DOCUMENT OBJECT MODEL

The Document Object Model (DOM) is the model that describes how all elements in an HTML page, like input fields, images, paragraphs etc., are related to the topmost structure: the document itself. By calling the element by its proper DOM name, we can influence it. The Document Object Model, or DOM, is the interface that allows you to programmatically access and manipulate the contents of a web page (or document). It provides a structured, object-oriented representation of the individual elements and content in a page with   methods for retrieving and setting the properties of those objects. It also provides methods for adding and removing such objects, allowing you to create dynamic content. The DOM also provides an interface for dealing with events, allowing you to capture and respond to user or browser actions. This feature is briefly covered here but the details are saved for another article. For this one, the discussion will be on the DOM representation of a document and the methods it provides to access those objects.

Nodes

The DOM is a Document Object Model, a model of how the various objects of a document are related to each other. In the Level 1 DOM, each object, whatever it may be exactly, is a Node. So if you do <P>This is a paragraph</P> you have created two nodes: an element P and a text node with content 'This is a paragraph'. The text node is inside the element, so it is considered a child node of the element. Conversely, the element is considered the parent node of the text node. <P> <-- element node | | This is a paragraph <-- text node If you do <P>This is a <B>paragraph</B></P> the element node P has two children, one of which has a child of its own: <P> | -------------- | |

This is a <B> | | paragraph Finally there are attribute nodes. (Confusingly, they are not counted as children of an element node. In fact, while writing this page I've done a few tests that seem to indicate that Explorer 5 on Windows doesn't see attributes as nodes at all.).So <P ALIGN="right">This is a <B>paragraph</B></P> would give something like <P> ---- ------------ | | -------------- ALIGN | | | This is a <B> | | right | paragraph So these are element nodes, text nodes and attribute nodes. They constitute about 99% of the content of an HTML page and you'll usually busy yourself with manipulating them. There are more kinds of nodes, but I skip them for the moment. As you'll understand, the element node P also has its own parent; this is usually the document, sometimes another element like a DIV. So the whole HTML document can be seen as a tree consisting of a lot of nodes, most of them having child nodes (and these, too, can have children).
<BODY> | |------------------------------------- | | <P> ---------------- lots more nodes | | -------------- ALIGN | | | This is a <B> | | right | paragraph



Walking through the DOM tree

Knowing the exact structure of the DOM tree, you can walk through it in search of the element you want to influence. For instance, assume the element node P has been stored in the variable x (later on I'll explain how you do this). Then if we want to access the BODY we do x.parentNode We take the parent node of x and do something with it. To reach the B node: x.childNodes[1] childNodes is an array that contains all children of the node x. Of course numbering starts at zero, so childNodes[0] is the text node 'This is a' and childNodes[1] is the element node B. Two special cases: x.firstChild accesses the first child of x (the text node), while x.lastChild accesses the last child of x (the element node B). So supposing the P is the first child of the body, which in turn is the first child of the document, you can reach the element node B by either of these commands:  

document.firstChild.firstChild.lastChild;document.firstChild.childNodes[0].lastChild; document.firstChild.childNodes[0].childNodes[1]; etc. or even (though it's a bit silly) document.firstChild.childNodes[0].parentNode.firstChild.childNodes[1];

3.2 DOM Levels and history

A short history lesson in order. When JavaScript was first introduced in browsers, some sort of interface was required to allow elements on the page to be accessed via scripting. Each vendor had their own implementation but de facto standards emerged to produce a fairly simple model common to most. For example, most browsers used an array of Image objects to represent all IMG tags on a page. These could then be accessed and manipulated via JavaScript. A simple image rollover might use code like this:
document.images[3].src = "graphics/button2.gif"
These early models were limited. They only provided access to a few types of element and attributes, like images, links or form elements. As vendors released new versions of browsers, they expanded on the model. But they also were often at odds with one another, leading to compatibility problems among different browsers as vendors tried to outdo each other by adding their own new features.
Fortunately, most vendors started adopting the DOM standard set by the World Wide Web Consortium, notably Internet Explorer, Netscape and Opera. In order to provide some backward compatibility, different levels of the DOM standard are defined. You might find references to DOM Level 0 (or "DOM0") which corresponds to the model used by the first, scriptable browsers - mainly Internet Explorer and Netscape prior to version 4 of each. Then there is DOM1 which was adopted in 1998 and covers some of the features introduced in version 4 browsers. Most of the current browsers (version 5 and up) support the DOM2 standard, or at least a good part of it. They may also continue to support some features of the earlier DOM levels, or their own proprietary extensions, so that they are compatible with older web pages.
This article will focus just the current, DOM2 standard. While this standard applies to XML (extended markup language) documents in general, it discusses how the standard applies to HTML in particular (it being a subset of XML).The good news is that, given the current industry trend, you can expect future versions of browsers to follow this standard. The bad news is that for now, you may find it difficult to code pages that work with both old and new browsers. One such example is Netscape 6.0, which drops support for many of the proprietary features of Netscape 4, such as the LAYER tag and its corresponding Layer object.
They are not recognized in version 6 as they were never adopted as part of the standard. Also note that Internet Explorer's document. all construct is a proprietary feature, not part of any standard. While it may be supported in many versions of IE - even the latest version - it's generally not supported by other browsers. You should keep in mind that the DOM coding is also indirectly dependent on the standards for HTML and CSS, since the DOM reflects the tags and attributes defined by those standards. It also depends on a standard for JavaScript since the DOM is essentially and API for client-side scripting.

3.3 INTRINSIC EVENT HANDLING

Event Handling has been part of JavaScript since the language's inception. As described in our event handler tutorial, they refer to specific, user imitated actions within the webpage, such as the moving of your mouse over a link, the clicking on a link, or submission of a form. Thanks to event handling, our scripts are more interactive and are able to perform certain actions depending on the users.

The 2 traditional ways of assigning event handlers

Let's first review (for most of us, at least) the 2 common and conventional ways of setting up an event handler- via HTML, or scripting. In both cases, a function or code is attached at the end, which is executed when the handler detects the specified event.

1)   Via HTML, using attribues

We can define an event handler directly inside the relevant HTML tag, by embedding it as a attribute. A piece of JavaScript is also included to tell the browser to perform something when the event occurs. For example,

<a href="http://freewarejava.com" onMouseover="window.status='Click here for Java
applets';return true" onMouseout="window.status=''">Freewarejava.com</a>

Here the event handler (onMouseover) is directly added inside the desired element (A),   along with the JavaScript to execute.

2)   Via scripting

You can also assign and set up event handlers to elements using scripting, and inside your script . This allows for the event handlers to be dynamically set up, without having to mess around with the HTML codes on the page.
<a ID="test"
href="http://freewarejava.com">Freewarejava.com</a> <script type="text/javascript">
function changestatus(){ window.status="Click here for Java applets" return true } function
changebackstatus(){ window.status='' }
document.getElementById("test").onmouseover=changestatus
document.getElementById("test").onmouseout=changebackstatus </script>

Notice how we attached the two functions to execute for the two events- the function names without the parenthesis. This is called a reference call to the function. When assigning a function to an event via scripting, always use a function call. If you were to include the parenthesis of the function inside the definition, an error will be generated.



3.4 MODIFYING ELEMENT STYLE

HTML elements can be changed using JavaScript, the HTML DOM and events.

Change an HTML Element

HTML DOM and JavaScript can change the inner content and attributes of HTML elements. The following example changes the background color of the <body> element:
Example
<html> <body> <script type="text/javascript"> document.body.bgColor="lavender";
</script> </body> </html>

Change the Text of an HTML Element – innerHTML

The easiest way to get or modify the content of an element is by using the innerHTML property. The following example changes the text of a <p> element:

Example

<html> <body> <p id="p1">Hello World!</p> <script type="text/javascript">
document.getElementById("p1").innerHTML="New text!";
</script> </body> </html>

An event handler allows you to execute code when an event occurs. Events are generated by the browser when the user clicks an element, when the page loads, when a form is submitted, etc. The following example changes the background color of the <body> element when a button is clicked:

Example

<html> <body> <input type="button" onclick="document.body.bgColor='lavender';"
value="Change background color" /> </body> </html>

Change the Text of an Element - with a Function
The following example uses a function to change the text of the <p> element when a button is clicked:

Example

<html> <head> <script type="text/javascript"> function ChangeText()
{
document.getElementById("p1").innerHTML="New text!";
}
 </script> </head> <body>
<p id="p1">Hello world!</p> <input type="button" onclick="ChangeText()" value="Change
text" /> </body> </html>



Using the Style Object

The Style object of each HTML element represents its individual style. The following example uses a function to change the style of the <body> element when a button is clicked:
Example
<html> <head> <script type="text/javascript"> function ChangeBackground()
{
document.body.style.backgroundColor="lavender";
}
</script> </head> <body>
<input type="button" onclick="ChangeBackground()" value="Change background color" />
</body> </html>

Change the font and color of an Element
The following example uses a function to change the style of the <p> element when a button is clicked:

Example

<html> <head> <script type="text/javascript"> function ChangeStyle() {
document.getElementById("p1").style.color="blue";
document.getElementById("p1").style.fontFamily="Arial"; } </script> </head> <body> <p
id="p1">Hello world!</p> <input type="button" onclick="ChangeStyle()" value="Change
style" /> </body> </html>


3.5 THE DOCUMENT TREE

When a browser loads a page, it creates a hierarchical representation of its contents which closely resembles its HTML structure. These results in a tree-like organization of nodes, each are representing an element, an attribute, content or some other object.

Nodes
Each of these different object types will have their own unique methods and properties. But each also implements the Node interface. This is a common set of methods and properties related to the document tree structure. To understand this interface better, take a look the diagram below which represents a simple node tree. The Node object provides several properties to reflect this structure and allow you to traverse the tree. Here are some relationships using the example above:
NodeA.firstChild = NodeA1
NodeA.lastChild = NodeA3
NodeA.childNodes.length = 3
NodeA.childNodes[0] = NodeA1
NodeA.childNodes[1] = NodeA2
NodeA.childNodes[2] = NodeA3

The Node interface also provides methods for dynamically adding, updating and removing nodes such as:
insertBefore()
replaceChild()
removeChild()
appendChild()
cloneNode()
These will be covered later. But for now let's look how the document tree reflects the contents of a web page.

The Document Root

The document object serves as the root of this node tree. It too implements the Node interface. It will have child nodes but no parent node or sibling nodes, as it is the starting node. In addition to being a Node, it also implements the Document interface.
This interface provides methods for accessing and creating other nodes in the document tree.

Some methods are:
getElementById()
getElementsByTagName()
createElement()
createAttribute()
   createTextNode()
Note that unlike other nodes, there is only one document object in a page. All of the above methods (except getElementsByTagName()) can only be used against the document object, i.e., using the syntax document.methodName().These properties are intended to provide some backward compatibility so that pages designed for older browsers will still work properly with newer versions. They can still be used in scripts but they may not be supported in future versions.

Traversing the Document Tree

As mentioned, the document tree reflects the structure of a page's HTML code. Every tag or tag pair is represented by a element node with other nodes representing attributes or character data (i.e., text). Technically speaking, the document object has only one child element, given by document.documentElement. For web pages, this represents the outer HTML tag and it acts as the root element of the document tree. It will have child elements for HEAD and BODY tags which in turn will have other child elements. Using this, and the methods of the Node interface, you can traverse the document tree to access individual node within the tree. Consider the following:
<html> <head> <title></title> </head>
<body><p>This is a sample paragraph.</p></body> </html> and this code:
alert(document.documentElement.lastChild.firstChild.tagName);

which would display "P", the name of the tag represented by that node. The code breaks down as follows:
document.documentElement - gives the page's HTML tag.
.lastChild - gives the BODY tag.
.firstChild - gives the first element in the BODY.
.tagName - gives that element's tag name, "P" in this case.

There are some obvious problems with accessing nodes like this. For one, a simple change to the page source, like adding text or formatting elements or images, will change the tree structure. The path used before may no longer point to the intended node. Less obvious are some browser compatibility issues. Note that in the sample HTML above, there is no spacing between the BODY tag and the P tag. If some simple line breaks are added,
<html>
<head>
<title> </title>
</head> <body>
 <p>This is a sample paragraph.</p>  
</body>
</html>

Netscape will add a node for this data, while IE will not. So in Netscape, the JavaScript code shown above would display "undefined" as it now points to the text node for this white space. Since it's not an element node, it has no tag name. IE, on the other hand, does not add nodes for white space like this, so it would still point to the P tag.

Accessing Elements Directly

This is where the document.getElementById() method comes in handy. By adding an ID attribute to the paragraph tag (or any tag for that matter), you can reference it directly.

<p id="myParagraph">This is a sample paragraph.</p> ...

alert(document.getElementById("myParagraph").tagName); This way, you can avoid compatibility issues and update the page contents at will without worrying about where the node for the paragraph tag is in the document tree. Just remember that each ID needs to be unique to the page. A less direct method to access element nodes is provided by document.getElementsByTagName(). This returns an array of nodes representing all of the elements on a page with the specified HTML tag. For example, you could change color of every link on a page with the following.

var nodeList = document.getElementsByTagName("A");
for (var i = 0; i < nodeList.length; i++) nodeList[i].style.color = "#ff0000";

This simply updates each link’s inline style to set the color parameter to red. Give it a try.

Node Types

Before going further, it's probably a good time to explain node types in more detail. As mentioned, there are several types of nodes defined in the document object model, but the ones you'll mostly deal with for web pages are element, text and attribute. Element nodes, as we've seen, correspond to individual tags or tag pairs in the HTML code. They can have child nodes, which may be other elements or text nodes. Text nodes represent content, or character data. They will have a parent node and possibly sibling nodes, but they cannot have child nodes. Attribute nodes are a special case. They are not considered a part of the document tree - they do not have a parent, children or siblings. Instead, they are used to allow access to an element node's attributes. That is, they represent the attributes defined in an element's HTML tag, such as the HREF attribute of the A tag or the SRC attribute on the IMG tag. Note that attribute values are always text strings.

Attributes vs. Attribute Nodes

There are several ways to reference the attributes of an element. The reason for this is that the DOM2 standard was designed for many types of structured documents (i.e., XML documents), not just HTML. So it defines a formal node type for attributes. But for all documents it also provides some more convenient methods for accessing, adding and modifying attributes, as described next. The document.createAttribute() allows you to create a new attribute node, which you can then set a value for and assign to an element node.
Var attr = document.createAttribute("myAttribute"); attr.value = "myValue";
var el = document.getElementById("myParagraph"); el.setAttributeNode(attr);
However, it's usually easier to access an element's attributes directly using the element getAttribute() and setAttribute() methods instead.

var el = document.getElementById("myParagraph");
el.setAttribute("myAttribute", "myValue");

An element's attributes are also represented as properties of the element node. In other words, you can simply use
var el = document.getElementById("myParagraph"); el.myAttribute = "myValue";

It's also interesting to note that you can define your own attributes in the HTML tag itself. For example,
<p id="myParagraph" myAttribute="myValue">This is a sample paragraph.</p> ...
alert(document.getElementById("myParagraph").getAttribute("myAttribute"));

Will display "myAttribute." But note that you should use element.getAttribute(attributeName) instead of element.attributeName to get the value as some browsers may not register user-defined attributes as a properties of the element. Attributes can also be removed from an element node, using either the removeAttribute() or removeAttributeNode() methods or setting by setting element.attributeName to a null string (""). Altering attributes is one way to create dynamic effects. Below is a sample paragraph. Use the links to alter it's ALIGN attribute.


Text in a paragraph element.

Align Left | Align Right The code is fairly simple:
<p id="sample1" align="left">Text in a paragraph element.</p>
 ... code for the links ...
document.getElementById('sample1').setAttribute('align', 'left');
document.getElementById('sample1').setAttribute('align', 'right');

Style Attributes

Most attributes for HTML tags are fairly simple, they define a single value for a property specific to that tag. Styles are a little more involved. As you know, CSS can be used to apply style parameters to an individual tag, all tags of a given type or assigned using classes. Likewise, styles for a particular element can be inherited from any of these sources.

You can also alter these styles at various levels. For example, you can change the STYLE attribute of an HTML tag, or it's CLASS attribute. But these methods will alter all of the element's style parameters. Often, you may want to change just a single style parameter, or a select few, while retaining the others. Fortunately, the style attribute of and element node is defined as an object with properties for every possible style parameter. You can access and update these individual parameters as you wish. Here's an example similar to the previous one. Text in a paragraph element. Align Left | Align Right But in this case, the text alignment is defined and altered using a style parameter instead of the ALIGN attribute. Here's the code behind it:
<p id="sample2" style="text-align:left;">Text in a paragraph element.</p>
... code for the links ...
 document.getElementById('sample2').style.textAlign = 'left';
document.getElementById('sample2').style.textAlign = 'right';

3.6 THE DOM EVENT HANDLING

One of the keys to creating dynamic web pages is the use of event handlers. These allow you to execute specific script code in response to user or system initiated actions. Most events relate to the browser GUI, such as mouse movements, button or key clicks and updates to form inputs. These are usually tied to a specific page element. Others relate to browser actions such as when a document or image completes loading. Some objects have default actions defined for certain events, such as clicking on a hypertext link. The browser's normal action in that event is to load the URL associated with the link. In any case, all events follow the same model. The DOM provides methods for capturing events so you can perform your own actions in response to them. It also provides an Event object which contains information specific to a given event that can be used by your event processing code.

Assigning Event Handlers

There are several ways to set up the capture of an event on an object using either HTML or scripting. In each case, you assign a function to handle the specific event when it occurs.

HTML Tag Attributes

Many HTML tags have intrinsic events associated with them. You can define script code to be executed when one of these events occurs using the event name as an attribute. For example,
<span style="background-color:yellow;"
onmouseover="this.style.backgroundColor='black';this.style.color='white'"
onmouseout="this.style.backgroundColor='yellow';this.style.color=''">  

Sample element with mouse event handlers.

</span> Here, two different events are captured, mouse over and mouseout. the value assigned to the corresponding attributes is a string containing JavaScript code. Note the use of single quotes (') for string constants within the double quotes (") used to delimit the attribute value. The script code for both events simply changes the text and background colors on the element's style. The keyword this keyword refers to the object that fired the event. Here it refers to the SPAN element. It was stated before that when you set up capturing for an event, you assign a function to be called to handle that event. This seems to contradict the example above where the event code is simply a couple of JavaScript statements. However, the browser actually creates an anonymous function for the handler with those statements in it. You should see an alert box with a function definition. The actual definition will vary according to browser but it will contain a single statement, the one defined in the HTML:

function name(argument_list)
{
alert(this.onclick);
}
This corresponds to the code set on the ONCLICK attribute:
<span style="background-color:yellow;"
onclick="alert(this.onclick)">
Sample element with an onclick event handler.
</span>

Scripting

You can also assign event handlers to elements in the DOM using client-side scripting. Like other element attributes, events are represented as properties of the element object. So you can set their value just like any other attribute. The main difference is that unlike most attributes, which take a string value, event handlers must be set using a function reference. Here's an example,
<span id="sample1" style="background-color:yellow;">Sample element
with mouse event handlers.</span> ... JavaScript code ... function highlight(event)
{
this.style.backgroundColor='black'; this.style.color='white';
 }
function normal(event)
{
this.style.backgroundColor='yellow'; this.style.color='';
}
document.getElementById('sample1').onmouseover = highlight;
document.getElementById('sample1').onmouseout = normal;

Note that the onmouseover property is set to highlight, i.e., the name of the function without parenthesis. This represents the Function object for highlight which is what the event property expects, a reference to the function to call when the event is fired. If highlight() had been used instead, the browser would call the function and assign whatever value it returned as the event handler. In this particular case, an error would result in the function execution because this has no meaning in the given context.

Event Listeners

DOM objects can also be registered as event listeners. This feature can be used to assign multiple handlers for a given event. It also allows you to capture events during either one of two phases in the event flow, capture or bubble. The difference between these two phases will be covered later on in the discussion on event flow. But for now we'll just look at how to register an event listener. The basic methods and syntax are,
node.addEventListener(eventType, function, useCapture);
node.removeEventListener(eventType, function);

Where eventType is a predefined event name such as "mouseover" or "click" (the same as the corresponding event attribute but without the preceding "on"), function is the name of the handler function and useCapture is a boolean flag which specifies which phase of the event flow the handler will be called on. To demonstrate, the previous example could have assigned event handlers for the sample paragraph element with the following:

var el =document.getElementById('sample1');
el.addEventListener("mouseover", highlight, false);
el.addEventListener("mouseout", normal, false);

Additional handlers could also be assigned for a given event:
el.addEventListener("mouseover", highlight2, true);
el.addEventListener("mouseover", highlight3, false);
Individual event listeners can be subsequently removed by specifying the same arguments:
el.removeEventListener("mouseover", highlight2, true);
el.removeEventListener("mouseover", highlight3, false);

Note that you must specify the same useCapture value when removing a listener as when it was added. This is because,

el.addEventListener("mouseover", highlight, true);
el.addEventListener("mouseover", highlight, false);
defines two unique event listeners, calling the same function for the same event on the same element but which activate during different phases. One advantage of this method is that event listeners can be assigned to any node, even text nodes which you could not normally assign event handlers to as they have no attributes.

Event Flow

Before going into event processing, it's helpful to understand event flow in the DOM.  HTML documents (and XML or XHTML documents) are hierarchical in nature. Elements and text are nested within other elements. Because of this, when an event occurs on a particular object, it effectively occurs on any containing objects as well. To illustrate, consider the following HTML:
 <div>
<p>Some text in a paragraph element.</p>
<p>Another paragraph element with text.</p>
<p>Yet another paragraph with text and also a <a href="blank.html">link</a>.</p>
</div>
If you click on the link defined in this code sample, it will trigger a onclick event on the A tag. But you're also clicking on the paragraph that contains that link, and the DIV that contains that P element and so on up to the document object itself.Any of the elements in this chain can have an event handler assigned to it to capture the onclick event, regardless of which element it originated at.




Event Bubbling

The DOM event model provides for this using a concept called event bubbling. For example, suppose an onclick event handler were assigned to the DIV tag above. Clicking on the link would fire the event first on the A element, it would then "bubble" up to the containing P element and then up to the DIV where the handler function would be called. It's possible for the handler to cancel the event, but assuming it doesn't the event would continue bubbling on up to the document root and finally, the browser would follow the default action of loading the link's URL in the window.Note that the P element could also have had an onclick event handler set, as could any elements above the DIV in the document tree. All of these handlers would be called in turn as the event bubbles up to the document root. This is known as the bubble phase in the DOM event model. Not all events bubble, for example onfocus and onblur do not. Likewise, not all bubbling events can be canceled, stopping the propagation. You can determine which events bubble and can be canceled either by looking up the documentation for the event or, as we'll see, using the Event object.

Event Capture

You can also catch events during the capture phase using the event listener detailed previously. The capture phase compliments the bubble phase. The capture phase runs first.
The event flows down from the root of the document tree to the target element, and then it bubbles back up. In this phase, outer elements will receive the event before it reaches its intended target. This can be useful if you want to intercept an event for some element even if it was initially targeted at one of its children or other descendants. It should be noted that the term "event capture" is often used loosely to describe the act of setting an event handler or listener, during either phase. Here it specifically means intercepting an event during this downward phase of the event flow, before it reaches its intended target.

Event Flow Example

The full process can be illustrated with a demo. Below is a set of nested DIV tags the onclick event is caught for each element both on the capture phase (if supported by the browser) and the bubble phase. Click anywhere on the boxes and the path of the event will be traced in the text box below it.
DIV A DIV B DIV C Clear Clicking on the innermost DIV fires six event handlers, three going down the document tree and three as it bubble back up.

In this example, the same function happens to be used for all six. But each could be assigned a unique handler function. In the trace, the "Target" element is the one that the event initiates from while the "Current" element is the one that has the event listener attached. Both of these values are derived using the Event object passed to the handler.

The Event Object

Within an event handler, you can do pretty much anything you want with your script code. Chances are, you'll want to perform some action related to that event depending on one or more factors. Recall that event handlers are passed one argument, an Event object. It provides several properties describing the event and its current state. You can use these to determine where an event originated from and where it currently is in the event flow. Or use the methods it provides to stop the event from flowing on and/or cancel the event.

Mouse Events
Mouse-related events include:
click
mousedown
mouseup
mouseover
mouseout
mousemove
For these events, additional information is provided in the Event object. Mouse Event

Properties
  • altKey, ctrlKey, metaKey, shiftKey Boolean values. If true, the associated key was depressed when the event fired.
  • button An integer indicating which mouse button was pressed or released, 1 = left, 2 = middle, 3 = right. A one-button mouse will return only 1, a two-button mouse could return either 1 or 3.
  • clientX, clientY Give the pixel coordinates of the mouse relative to the client area of the browser, i.e., relative to the viewport, when the event fired.
  • relatedTarget On a mouseover this indicates the node that the mouse has left. On a mouseout it indicates the node the mouse has moved onto.
  • screenX, screenY Give the pixel coordinates of the mouse relative to the screen when the event fired.

Keyboard Events

The DOM2 Event Model does not include specifications for key events. However, the HTML 4 standard does permit the keyup, keydown and keypress events for many elements. Both Netscape 6 and IE 5.5 support these and include properties in the Event object to reflect information on what key or keys were pressed.In Netscape, the ASCII value of the key is given by the charCode property on keypress events and in the keyCode property for keydown and keyup events.Internet Explorer stores the Unicode value of the key in the event keyCode property for all three key events. In both, the keydown and keyup events will fire when any modifier key is pressed, such as ALT, CTRL and SHIFT. The keypress event can be used instead capture combinations such as SHIFT-A.Some example key combinations with the relevant property values for each key event type are shown below, arranged by browser.

3.7 ADDITIONAL PROPERTIES OF WINDOWS

Window Object

The window object represents an open window in a browser. If a document contain frames (<frame> or <iframe> tags), the browser creates one window object for the HTML document, and one additional window object for each frame.

Note: There is no public standard that applies to the Window object, but all major browsers support it.

Window Object Properties
Property
Description

Closed Returns a Boolean value indicating whether a window has been closed or not defaultStatus Sets or returns the default text in the statusbar of a window document Returns the Document object for the window (See Document object) frames Returns an array of all the frames (including iframes) in the current window history Returns the History object for the window (See History object) innerHeight Sets or returns the the inner height of a window's content area innerWidth Sets or returns the the inner width of a window's content area length Returns the number of frames (including iframes) in a window location Returns the Location object for the window (See Location object) name Sets or returns the name of a window navigator Returns the Navigator object for the window (See Navigator object) opener Returns a reference to the window that created the window outerHeight Sets or returns the outer height of a window, including toolbars/scrollbars outerWidth Sets or returns the outer width of a window, including toolbars/scrollbars pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window parent Returns the parent window of the current window screen Returns the Screen object for the window screenLeft Returns the x coordinate of the window relative to the screen screenTop Returns the y coordinate of the window relative to the screen screenX Returns the x coordinate of the window relative to the screen screenY Returns the y coordinate of the window relative to the screen self Returns the current window status Sets the text in the statusbar of a window top Returns the topmost browser window setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds

The DOM API provided by the Web browser contains a object called "window", which has the following features:

The "window" object is a browser built-in object that represents the browser window that contains the current HTML document. The "window" object offers a number of properties and methods to allow you The "document" object and its "node" objects offers various methods to allow you to manipulate the window.

To illustrate some nice features of the "document" object, I wrote this JavaScript tutorial example:

<html>
<!-- Window_Object.html Copyright (c) 2008 by Dr. Herong Yang,
http://www.herongyang.com/ -->
<head> <title>Window Object</title>
<script type="text/javascript"> var sizeID = 0; function changeSize() { if (sizeID == 0 )
window.resizeTo(300,300);
else if (sizeID == 1 )
window.resizeTo(400,400);
else if (sizeID == 2 )
window.resizeTo(500,500);
else if (sizeID == 3 )
window.resizeTo(600,600);
sizeID = (sizeID+1)%4; }
</script>
</head>
<body>
<p>Hello World!</p>
<p><form>
<input type="button" value="Change" onClick="changeSize();"/> </form></p>
</body> </html>

3.8 CASE STUDY
Dynamic Content

Changing textual content is relatively simple. Every continuous string of character data in  the body of an HTML page is represented by a text node. The nodeValue property of these nodes is the text itself. Changing that value will change the text on the page.

Text Nodes

Here's another example using a simple paragraph tag. Use the links to change the text: This is the initial text. Change Text 1 | Change Text 2 Now look at the code behind it:  
<p id="sample1">This is the initial text.</p>
... code for the links ...
document.getElementById('sample1').firstChild.nodeValue = 'Once upon a time...';
document.getElementById('sample1').firstChild.nodeValue = '...in a galaxy far, far away';

There are a couple of important things to note here. First, text nodes do not have an ID attribute like element nodes can. So they cannot be accessed directly using methods like document.getElementById() or document.getElementsByTagName(). Instead, the code references the text using the parent node, in this case it's the paragraph element with the ID
"sample1". This element node has one child node, the text node we want to update. You can see this in the diagram below.

It's important to remember that text nodes contain just that, text. Even simple markup tags like B or I within a string of text will create a sub tree of element and text nodes. For example, using the example above and adding tags make the word "initial" bold:

<p id="sample2">This is the <b>initial</b> text.</p>

now gives the "sample2" paragraph element three children instead of one. There is a text node for "This is the ", an element node for the B tag pair and a text node for " text.". The node for the B element has one child node, a text node for "initial". You can see the structure in the diagram below. To see how this affects scripting code, here's the same example used above but with the additional bold markup: This is the initial text. Change Text 1 | Change Text 2 Changing firstChild of the P element now only affects the text "This is the ". Conversely, if you attempt to add markup to the value of a text node, the browser will treat it as plain text, as demonstrated below: This is the initial text. Change Text 1 | Change Text 2

Adding Nodes

Nodes can also be added to the DOM. You've already seen how attribute nodes can be created and applied to an element so let's look at adding element and text nodes within the document tree (without using the innerHTML property). The first step is to create a node object of the type you want using one of document.createElement(), document.createAttribute() or document.createTextNode(). For attributes, however, you'll probably just want to create an element node and assign it attributes directly (recall that IE, as of version 5.5, doesn't support createAttribute()).

Working with Text Nodes

Let's start with a text node. Below is some sample code showing how to create a text node and assign it a value. var myTextNode = document.createTextNode("my text"); Now you have a text node. But it's not part of the document tree. To make it appear on the page, you need to add it as a child to an existing node within the tree. Since text nodes cannot have children, you can't attach it to another text node. Attributes nodes are not part of the document tree, so you don't want to attach it to one of them. That leaves element nodes. Since element nodes can several children, there are a few different methods provided that allows you to specify where to add the new node among its existing children. These are best illustrated by example. Here, the appendChild() method is used to add new text to a paragraph element.

It also allows you to remove the last node added using the removeChild() method: Initial text
within a paragraph element. Add Text Node | Remove Text Node Now take a look at the code:
<p id="sample1">Initial text within a paragraph element.</p>
...code to add a text node ...
var text = document.createTextNode(" new text " + (++counter1));
var el = document.getElementById("sample1");
el.appendChild(text);
... code to remove the last child node ...
var el = document.getElementById("sample1");
if (el.hasChildNodes())
el.removeChild(el.lastChild);
Adding text is easy, the code creates a new text node, locates the paragraph element node and calls appendChild() to insert it at the end of it's childNodes array. A global counter variable is used on the text itself so you can distinguish each new node in the browser display. Removing text is almost as easy, using a call to removeChildNode(). The only difference in the addition of a reference node, to indicate which of the element's children is to be removed. Here we use the element's lastChild property which always points to the last node of the element's childNodes array. Note that it will even remove the initial text hard coded in the P tag if that is the only child. Also note the use of the hasChildNodes() method which simply returns true or false to indicate if the given node currently has any children. Here it's used to prevent an error by calling removeChild when there are no children left.

3.9 SERVER-SIDE PROGRAMMING: JAVA SERVLETS
What is a Servlet?

Servlets are modules of Java code that run in a server application (hence the name "Servlets", similar to "Applets" on the client side) to answer client requests. Servlets are not tied to a specific client-server protocol but they are most commonly used with HTTP and the word "Servlet" is often used in the meaning of "HTTP Servlet". Servlets make use of the Java standard extension classes in the packages javax.servlet (the basic Servlet framework) and javax.servlet.http (extensions of the Servlet framework for Servlets that answer HTTP requests). Since Servlets are written in the highly portable Java language and follow a standard framework, they provide a means to create sophisticated server extensions in a server and operating system independent way. Typical uses for HTTP Servlets include:
Processing and/or storing data submitted by an HTML form. Providing dynamic content, e.g. returning the results of a database query to the client. Managing state information on top of the stateless HTTP, e.g. for an online shopping cart system which manages shopping carts for many concurrent customers and maps every request to the right customer.

Servlets vs CGI

The traditional way of adding functionality to a Web Server is the Common Gateway Interface (CGI), a language-independent interface that allows a server to start an external process which gets information about a request through environment variables, the command line and its standard input stream and writes response data to its standard output stream. Each request is answered in a separate process by a separate instance of the CGI program, or CGI script (as it is often called because CGI programs are usually written in interpreted languages like Perl). Servlets have several advantages over CGI:

A Servlet does not run in a separate process. This removes the overhead of creating a new
process for each request. A Servlet stays in memory between requests. A CGI program (and probably also an extensive runtime system or interpreter) needs to be loaded and started for each CGI request. There is only a single instance which answers all requests concurrently. This saves memory and allows a Servlet to easily manage persistent data. A Servlet can be run by a Servlet Engine in a restrictive Sandbox (just like an Applet runs in a Web Browser's Sandbox) which allows secure use of untrusted and potentially harmful Servlets.

3.10 THE BASIC SERVLET ARCHITECTURE

A Servlet, in its most general form, is an instance of a class which implements the javax.servlet.Servlet interface. Most Servlets, however, extend one of the standard implementations of that interface, namely javax.servlet.GenericServlet and javax.servlet.http.HttpServlet. In this tutorial we'll be discussing only HTTP Servlets which extend the javax.servlet.http.HttpServlet class. In order to initialize a Servlet, a server application loads the Servlet class (and probably other classes which are referenced by the Servlet) and creates an instance by calling the no-args constructor. Then it calls the  Servlet's init(ServletConfig config) method. The Servlet should performe one-time setup procedures in this method and store the ServletConfig object so that it can be retrieved later by calling the Servlet's getServletConfig() method. This is handled by GenericServlet. Servlets which extend GenericServlet (or its subclass HttpServlet) should call super.init(config) at the beginning of the init method to make use of this feature. The ServletConfig object contains Servlet parameters and a reference to the Servlet's ServletContext. The init method is guaranteed to be called only once during the Servlet's lifecycle. It does not need to be threadsafe because the service method will not be called until the call to init returns.

When the Servlet is initialized, its service(ServletRequest req, ServletResponse res) method is called for every request to the Servlet. The method is called concurrently (i.e. multiple threads may call this method at the same time) so it should be implemented in a thread-safe manner. Techniques for ensuring that the service method is not called concurrently, for the cases where this is not possible, are described in section 4.1. When the Servlet needs to be unloaded (e.g. because a new version should be loaded or the server is shutting down) the destroy() method is called. There may still be threads that execute the service method when destroy is called, so destroy has to be thread-safe. All resources which were allocated in init should be released in destroy. This method is guaranteed to be called only once during the Servlet's lifecycle.

HTTP

Before we can start writing the first Servlet, we need to know some basics of HTTP ("HyperText Transfer Protocol"), the protocol which is used by a WWW client (e.g. a browser) to send a request to a Web Server. HTTP is a request-response oriented protocol. An HTTP request consists of a request method, a URI, header fields and a body (which can be empty). An HTTP response contains a result code and again header fields and a body. The service method of HttpServlet dispatches a request to different Java methods for different HTTP request methods. It recognizes the standard HTTP/1.1 methods and should not be overridden in subclasses unless you need to implement additional methods. The recognized methods are GET, HEAD, PUT, POST, DELETE, OPTIONS and TRACE. Other methods are answered with a Bad Request HTTP error.

An HTTP method XXX is dispatched to a Java method doXxx, e.g. GET -> doGet. All these methods expect the parameters "(HttpServletRequest req, HttpServletResponse res)". The methods doOptions and doTrace have suitable default implementations and are usually not overridden. The HEAD method (which is supposed to return the same header lines that a GET method would return, but doesn't include a body) is performed by calling doGet and ignoring any output that is written by this method. That leaves us with the methods doGet, doPut, doPost and doDelete whose default implementations in HttpServlet return a Bad Request HTTP error.

A subclass of HttpServlet overrides one or more of these methods to provide a meaningful implementation. The request data is passed to all methods through the first argument of type HttpServletRequest (which is a subclass of the more general ServletRequest class). The response can be created with methods of the second argument of type HttpServletResponse (a subclass of ServletResponse). When you request a URL in a Web Browser, the GET method is used for the request. A GET request does not have a body (i.e.the body is empty). The response should contain a body with the response data and header fields which describe the body (especially Content-Type and Content-Encoding). When you send an HTML form, either GET or POST can be used. With a GET request the parameters are encoded in the URL, with a POST request they are transmited in the body. HTML editors and upload tools use PUT requests to upload resources to a Web Server and DELETE requests to delete resources. The complete HTTP specifications can be found in RFCs 1945 (HTTP/1.0) and 2068 (HTTP/1.1).

3.11. A"HELLO WORLD" SERVLET
Hello World!

This section shows how to use the framework that makes up a simple Servlet write a Servlet that provides static content (i.e. it produces the same output every time it is called by a client)
We start our venture into Servlet programming with the well-known "Hello World" example, this time named more suitably "Hello Client":

HelloClientServlet.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloClientServlet extends HttpServlet
{
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("<HTML><HEAD><TITLE>HelloClient!</TITLE>"+"</HEAD><BODY>Hello Client!</BODY></HTML>");
 out.close();
 }
public String getServletInfo()
{
return "HelloClientServlet 1.0 by Stefan Zeiger";
}
 }

Then you compile this Servlet and run it by requesting a URL which is assigned to it in a Web Browser it produces the following output:
Let's have a look at how the Servlet works. Lines 1 to 3 import some packages which contain many classes which are used by the Servlet (almost every Servlet needs classes from these packages).

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

The Servlet class is declared in line 5. Our Servlet extends javax.servlet.http.HttpServlet, the standard base class for HTTP Servlets. public class HelloClientServlet extends HttpServlet In lines 7 through 16 HttpServlet's doGet method is getting overridden. protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException : { ... } In line 11 we use a method of the HttpServletResponse object to set the content type of the response that we are going to send. All response headers must be set before a PrintWriter or ServletOutputStream is requested to write body data to the response. res.setContentType("text/html"); In line 12 we request a PrintWriter object to write text to the response message. PrintWriter out = res.getWriter(); In lines 13 and 14 we use the PrintWriter to write the text of type text/html (as specified through the content type).

out.println("<HTML><HEAD><TITLE>Hello Client!</TITLE>"+
"</HEAD><BODY>HelloClient!</BODY></HTML>");

The PrintWriter gets closed in line 15 when we are finished writing to it. out.close(); This line is included for completeness. It is not strictly necessary. The Web Server closes the PrintWriter or ServletOutputStream automatically when a service call returns. An explicit call to close() is useful when you want to do some post-processing after the response to the client has been fully written. Calling close() tells the Web Server that the response is finished and the connection to the client may be closed as well. In lines 18 through 21 we override the getServletInfo() method which is supposed to return information about the Servlet, e.g. the Servlet name, version, author and copyright notice.

This is not required for the function of the HelloClientServlet but can provide valuable information to the user of a Servlet who sees the returned text in the administration tool of the Web Server.
public String getServletInfo()
{
return "HelloClientServlet 1.0 by Stefan Zeiger";
}
Powered

3.12 SERVLETS GENERATING DYNAMIC CONTENT

This section shows how to process form data manage persistent data use init parameters The next Servlet that we are going to write provides a user interface to a mailing list through HTML forms. A user should be able to enter an email address in a text field and press a button to subscribe to the list or another button to unsubscribe. The Servlet consists of two major parts: Data managment and client interaction.

Data management

The data management is rather straight-forward for an experienced Java programmer. We use a java.lang.Vector object which contains the email addresses as Strings. Since a Servlet can have data which persists between requests we load the address list only once, when the Servlet is initialized, and save it every time it has been changed by a request. An alternative approach would be keeping the list in memory while the Servlet is active and writing it to disk in the destroy method. This would avoid the overhead of saving the address list after every change but is less fail-safe. If for some reason the address file can't be written to disk or the server crashes and cannot destroy the Servlet, all changes to the list will be lost even though the users who submitted the requests to change the list received positive responses. The following parts of the Servlet are related to data management: private Vector addresses;

private String filename;
 public void init(ServletConfig config) throws ServletException
{
super.init(config);
filename = config.getInitParameter("addressfile");

if(filename == null) throw new UnavailableException(this, "The \"addressfile\" property "+ "must be set to a file name");
 try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));
addresses= (Vector)in.readObject(); in.close();
}
catch(FileNotFoundException e)
 {
addresses = new Vector();
}
 catch(Exception e)
{
 throw new UnavailableException(this, "Error reading address file: "+e);
 }
}
private synchronized boolean subscribe(String email) throws IOException
{
if(addresses.contains(email)) return false;
addresses.addElement(email);
save();
return true;
}
private synchronized boolean unsubscribe(String email) throws IOException
{
if(!addresses.removeElement(email))
 return false; save();
return true;
}
private void save() throws IOException
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename)); out.writeObject(addresses);
out.close();
}

In init we first call super.init(config) to leave the ServletConfig management to the superclass (HttpServlet), then we get the name of the address file from an init parameter (which is set up in the Web Server configuration). If the parameter is not available the Servlet throws a javax.servlet.UnavailableException (a subclass of javax.servlet. ServletException) which indicates that a Servlet is temporarily (if a duration is specified) or permanently (as in this case) unavailable. Finally, the init method deserializes the address file or creates an empty Vector if the address file does not exist yet. All exceptions that occur during the deserialization are transformed into UnavailableExceptions.

Client interaction

The client interaction is handled by two of the standard HttpServlet methods, doGet and doPost. The doGet method replies to GET requests by sending an HTML page which contains the list of the currently subscribed addresses and the form that is used to subscribe or unsubscribe an address:
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
res.setContentType("text/html");
res.setHeader("pragma", "no-cache");
PrintWriter out = res.getWriter();
out.print("<HTML><HEAD><TITLE>List Manager</TITLE></HEAD>");
out.print("<BODY><H3>Members:</H3><UL>");
for(int i=0; i<addresses.size(); i++)
out.print("<LI>" + addresses.elementAt(i));
out.print("</UL><HR><FORM METHOD=POST>");
out.print("Enter your email address: <INPUT TYPE=TEXT NAME=email><BR>");
out.print("<INPUT TYPE=SUBMIT NAME=action VALUE=subscribe>");
out.print("<INPUT TYPE=SUBMIT NAME=action VALUE=unsubscribe>");
out.print("</FORM></BODY></HTML>");
out.close();
}

The response content type is again set to text/html and the response is marked as not cacheable to proxy servers and clients (because it is dynamically created) by setting an HTTP header "pragma: no-cache". The form asks the client to use the POST method for submitting form data. Here is a typical output by this method:

3.13 SERVLET LIFE CYCLE

The life cycle of a servlet is controlled by the container in which the servlet has been deployed. When a request is mapped to a servlet, the container performs the following steps.
1. If an instance of the servlet does not exist, the Web container
a. Loads the servlet class.
b. Creates an instance of the servlet class.
c. Initializes the servlet instance by calling the init method. Initialization is covered in Initializing a Servlet.
2. Invokes the service method, passing a request and response object. Service methods are discussed in the section Writing Service Methods.

If the container needs to remove the servlet, it finalizes the servlet by calling the servlet's destroy method. Finalization is discussed in Finalizing a Servlet.

Handling Servlet Life-Cycle Events

You can monitor and react to events in a servlet's life cycle by defining listener objects whose methods get invoked when life cycle events occur. To use these listener objects, you must define the listener class and specify the listener class.

Defining The Listener Class

You define a listener class as an implementation of a listener interface. Table 10-3 lists the events that can be monitored and the corresponding interface that must be implemented. When a listener method is invoked, it is passed an event that contains information appropriate to the event. For example, the methods in the HttpSessionListener interface are passed an HttpSessionEvent, which contains an HttpSession.







Servlet Life-Cycle Events

Object Event Listener Interface and Event Class

Web context (See Accessing the Web Context) Initialization and destruction javax.servlet.ServletContextListener and ServletContextEvent Attribute added, removed, or replaced javax.servlet.ServletContextAttributeListener and ServletContextAttributeEvent Session (See Maintaining Client State) Creation, invalidation, and timeout javax.servlet.http.Htt pSessionListener and HttpSessionEvent Attribute added, removed, or replaced javax.servlet.http.HttpSessionAttributeListener and HttpSessionBindingEvent

3.14 PARAMETER DATA
Reading Parameters

Here's a simple example that reads parameters named param1, param2, and param3, listing their values in a bulleted list. Note that, although you are required to specify response settings (content type, status line, other HTTP headings) before beginning to generate the content, there is no requirement that you read the request parameters at any particular time. Also note you can easily make servlets that can handle both GET and POST data, simply by having its doPost method call doGet or by overriding service (which calls doGet, doPost, doHead, etc.). This is good standard practice, since it requires very little extra work and permits flexibility on the part of the client. If you're used to the traditional CGI approach where you read POST data via the standard input, you should note that there is a similar way with servlets by first calling getReader or getInputStream on the HttpServletRequest. This is a bad idea for regular parameters, but might be of use for uploaded files or POST data being sent by custom clients rather than via HTML forms. Note, however, that if you read the POST data in that manner, it might no longer be found by getParameter.

ThreeParams.java

You can also download the source or try it on-line. Note: also uses ServletUtilities.java, shown earlier.
package hall;

import java.io.*;
 import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
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>\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<UL>\n" + " <LI>param1: " + request.getParameter("param1") + "\n" + "<LI>param2: " + request.getParameter("param2") + "\n" + " <LI>param3: " + request.getParameter("param3") + "\n" + "</UL>\n" + "</BODY></HTML>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
}

ThreeParams Output

3. Example: Listing All Form Data

Here's an example that looks up all the parameter names that were sent and puts them in a table. It highlights parameters that have zero values as well as ones that have multiple values. First, it looks up all the parameter names via the getParameterNames method of HttpServletRequest. This returns an Enumeration. Next, it loops down the Enumeration in the standard manner, using hasMoreElements to determine when to stop and using nextElement to get each entry. Since nextElement returns an Object, it casts the result to a String and passes that to getParameterValues, yielding an array of Strings. If that array is one entry long and contains only an empty string, then the parameter had no values, and the servlet generates an italicized "No Value" entry. If the array is more than one entry long, then the parameter had multiple values, and they are displayed in a bulleted list. Otherwise the one main value is just placed into the table.

ShowParameters.java

You can also download the source or try it on-line.
Note: also uses ServletUtilities.java, shown earlier.
package hall;
import java.io.*;
import javax.servlet.*;
 import javax.servlet.http.*;
import java.util.*;
public class ShowParameters extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOExceptionresponse.setContentType("text/html");
 PrintWriter out = response.getWriter();
Stringn title = "Reading All Request Parameters";
out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<TABLE BORDER=1 ALIGN=CENTER>\n" + "<TR BGCOLOR=\"#FFAD00\">\n" + "<TH>Parameter Name<TH>Parameter Value(s)");
 EnumerationparamNames = request.getParameterNames(); while(paramNames.hasMoreElements())
{
String paramName = (String)paramNames.nextElement();
 out.println("<TR><TD>" + paramName + "\n<TD>");
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length == 1)
{
String paramValue = paramValues[0];
if (paramValue.length() == 0)
out.print("<I>No Value</I>");
else out.print(paramValue);
 }
 else
{
out.println("<UL>");
for(int i=0;i<paramValues.length; i++)
{
out.println("<LI>" + paramValues[i]);
}
out.println("</UL>");
 }
}
out.println("</TABLE>\n</BODY></HTML>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException
{
doGet(request, response);
}
}

Front End to ShowParameters

Here's an HTML form that sends a number of parameters to this servlet. Right click on the source code link to download the HTML. Left click on the link to try it out on-line. It uses POST to send the data (as should all forms that have PASSWORD entries), demonstrating the value of having servlets include both a doGet and a doPost. However, just for the sake of illustration, a version using GET can also be downloaded or tried out on-line.

PostForm.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML> <HEAD> <TITLE>A Sample FORM using POST</TITLE> </HEAD> <BODY
BGCOLOR="#FDF5E6"> <H1 ALIGN="CENTER">A Sample FORM using POST</H1>
<FORM ACTION="/servlet/hall.ShowParameters" METHOD="POST"> Item Number:
<INPUT TYPE="TEXT" NAME="itemNum"><BR> Quantity: <INPUT TYPE="TEXT"
NAME="quantity"><BR> Price Each: <INPUT TYPE="TEXT" NAME="price"
VALUE="$"><BR> <HR> First Name: <INPUT TYPE="TEXT"
NAME="firstName"><BR> Last Name: <INPUT TYPE="TEXT"
NAME="lastName"><BR> Middle Initial: <INPUT TYPE="TEXT"
NAME="initial"><BR> Shipping Address: <TEXTAREA NAME="address" ROWS=3
COLS=40></TEXTAREA><BR> Credit Card:<BR> <INPUT TYPE="RADIO"
NAME="cardType" VALUE="Visa">Visa<BR> <INPUT TYPE="RADIO"
NAME="cardType" VALUE="Master Card">Master Card<BR> <INPUT TYPE="RADIO"
NAME="cardType" VALUE="Amex">American Express<BR> <INPUT TYPE="RADIO"
NAME="cardType" VALUE="Discover">Discover<BR> <INPUT TYPE="RADIO"
NAME="cardType" VALUE="Java SmartCard">Java SmartCard<BR> Credit Card
Number: <INPUT TYPE="PASSWORD" NAME="cardNum"><BR> Repeat Credit Card
Number: <INPUT TYPE="PASSWORD" NAME="cardNum"><BR><BR> <CENTER> <INPUT
TYPE="SUBMIT" VALUE="Submit Order"> </CENTER> </FORM> </BODY> </HTML>

Submission Result
3.15 SESSIONS Session Tracking

This section shows how to use Session Tracking capabilities Session Tracking allows a Servlet to associate a request with a user. A session can extend across requests and connections of the stateless HTTP. Sessions can be maintained in two ways:

1. By using Cookies. A Cookie is a string (in this case that string is the session ID) which is sent to a client to start a session. If the client wants to continue the session it sends back the Cookie with subsequent requests. This is the most common way to implement session
tracking.

2. By rewriting URLs. All links and redirections which are created by a Servlet have to be encoded to include the session ID. This is a less elegant solution (both, for Servlet implementors and users) because the session cannot be maintained

3. by requesting a wellknown URL oder selecting a URL which was created in a different (or no) session. It also does not allow the use of static pages. All HTML pages which are sent within a session have to be created dynamically.

4. Our next Servlet manages a virtual shopping cart. Users can add various items to their shopping cart via HTML forms. The shopping cart contents are stored on the server and each user gets his own shopping cart which is selected automatically whenever he makes a request to the Servlet. In the simplified version that we implement in class ShoppingCartServlet there are only two kinds of items, named FOO and BAR.

5. By pressing a button in an HTML form a single FOO or BAR item can be put into the shopping cart. There's another button to see the current contents of the shopping cart and a button to order the selected items, thus clearing the shopping cart.

6. The first version of the Servlet, called ShoppingCartServlet, which works with Cookie-style sessions only, consists of the two standard methods, doGet and doPost: A form with the buttons is created by the Servlet's doGet method.

7. protected void doGet(HttpServletRequest req, HttpServletResponse res)

8: throws ServletException, IOException
9: { 10: res.setContentType("text/html");
11: PrintWriter out = res.getWriter();
12: out.print("<HTML><HEAD><TITLE>Online Shop</TITLE>"+
13: "</HEAD><BODY><FORM METHOD=POST>"+
14: "<INPUT TYPE=SUBMIT NAME=foo VALUE="+
15: "\"Put a FOO into the shopping cart\">"+
16: "<INPUT TYPE=SUBMIT NAME=bar VALUE="+
17: "\"Put a BAR into the shopping cart\">"+
18: "<INPUT TYPE=SUBMIT NAME=see VALUE="+
19: "\"See the shopping cart contents\">"+
20: "<INPUT TYPE=SUBMIT NAME=buy VALUE="+
21: "\"Buy the shopping cart contents\">"+
22: "</FORM></BODY></HTML>");
23: out.close();
24: }

First we get the HttpSession object which is associated with the request by calling req.getSession. The argument true forces the creation of a new session if the request doesn't contain a valid session key. If the session is indeed new (determined by calling HttpSession's isNew() method) we add some custom data to the session: Two counters, one for the FOOs and one for the BARs in the shopping cart. The session object can be used like a Dictionary. That means we can only add Objects, not instances of primitive types like int. We could use an instance of java.lang.Integer for each counter, but these objects are immutable which makes incrementing inefficient and difficult to implement. Instead we use an array of int (int[]) with only one element as a mutable wrapper object. The element is initialized to 0. Next we retrieve the values for "foo" and "bar" from the session, no matter if they were just added or carried over from a previous request. In the ListManagerServlet both buttons had the same name but different values so we could use getParameter to retrieve the value from the request and then do a string compare to the possible values. This time we use a different approach which can be implemented more efficiently. All buttons have different names and we can find out which button was used to submit the form by checking which name has a non-null value. A new FOO or BAR item can be put into the shopping cart by simply incrementing the counter in the array. Note that the array does not need to be put back into the session because it has not changed itself, only the contents have been modified. When the user chooses to buy the contents of the shopping cart we call session.invalidate() to delete the session on the server side and tell the client to remove the session ID Cookie. The session data is lost and when a new POST request is made to the Servlet, a new session will be created. The rest of the doPost method is basically the same as in the ListManagerServlet.

3.16 COOKIES

We've already used Cookies indirectly through Sessions. While session data is stored on the server side and only an index to the server-side data (the session ID) is transmitted to the client, Cookies can also be used directly to store data on the client side. The Servlet API provides the class javax.servlet.http.Cookie for a convenient object-oriented representation of Cookies so you don't need to compose and decompose Cookie and Set-Cookie HTTP headers yourself. Even if you don't care where the data is stored it is sometimes useful to manipulate Cookies directly via the Cookie class to get more control over Cookie parameters like Domain and Path, e.g. to share Cookies between different Servlets or even servers.

Example.

Imagine an authentication Servlet which receives a username and password from a login form via doPost and verifies them against a central authentication database. It then computes an authentiation string (e.g. a Base64-encoded "user:password" combination, as used by HTTP Basic Authentication). This string is now put into a Cookie and sent back to the client:

Cookie authCookie = new Cookie("xyz-Auth", credentials);
authCookie.setVersion(1);
authCookie.setDomain(".xyz.com");
res.addCookie(authCookie);

The Cookie's domain is set to ".xyz.com" so it will be sent to all hosts in domain "xyz.com" like "a.xyz.com" and "foo.xyz.com" (but not "c.d.xyz.com"). Note that the Domain attribute is supported by RFC2109-style Cookies (version 1) but not by old Netscape Cookies (version 0, the default for newly created Cookie objects). All Web Servers on hosts in xyz.com are running an instance of another Servlet which serves protected data after verifying the authentication credentials:
boolean verified = false;
Cookie[] cookies = req.getCookies();
for(int i=0; i<cookies.length; i++)
{
String n = cookies[i].getName(),
d = cookies[i].getDomain();
if(n != null && n.equals("xyz-Auth") &&d != null && d.equals(".xyz.com"))
{
String credentials = cookies[i].getValue();
verfied =verifyCredentials(credentials);
break;
}
}
if(!verified)
{
res.sendRedirect(...);
return;
}
The credentials are retrieved from the Cookie and verified by the authentication database. If the credentials are invalid or missing the client is redirected to the login page on the authentication server, otherwise the protected content is returned.

3.17 URL REWRITING

To make the Servlet usable with URL rewriting (for clients without Cookie support or with Cookie support turned off) we have to make some modifications. The formerly static "Online Shop" page which is created by doGet needs to be modified to include an ACTION URL which contains an encoded session ID in the HTML form. This is done with the encodeUrl method of HttpServletResponse. We also need to call req.getSession to keep the session alive. The additional code to check for a new session can be avoided by using getSession(false). If there is no session or an invalid session we do not force the creation of a new session. This is deferred until the doPost method is called. Finally, the response has to be marked as not cachable by calling res.setHeader("pragma", "no-cache"), as usual.

These changes lead us to the following revised implementation of doGet:
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
HttpSession session = req.getSession(false);
res.setContentType("text/html");
res.setHeader("pragma", "no-cache");
PrintWriter out = res.getWriter();
out.print("<HTML><HEAD><TITLE>OnlineShop</TITLE>"+"</HEAD><BODY><FORM METHOD=POST ACTION="+
out.print(res.encodeUrl(req.getRequestURI()));
out.print("><INPUT TYPE=SUBMIT
NAME=foo VALUE="+ "\"Put a FOO into the shopping cart\">"+ "<INPUT
TYPE=SUBMIT NAME=bar VALUE="+ "\"Put a BAR into the shopping cart\">"+
"<INPUT TYPE=SUBMIT NAME=see VALUE="+ "\"See the shopping cart contents\">"+
"<INPUT TYPE=SUBMIT NAME=buy VALUE="+ "\"Buy the shopping cart contents\">"+
"</FORM></BODY></HTML>");
out.close();
 }


3.18 OTHER SERVLETS CAPABILITIES
Data Storage Servlets and Concurrency

Let's implement our first servlet. A servlet is a Java class that implements the Servlet interface. This interface has three methods that define the servlet's life cycle:

public void init(ServletConfig config) throws ServletException
This method is called once when the servlet is loaded into the servlet engine, before the servlet is asked to process its first request.
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException This method is called to process a request. It can be called zero, one or many times until the servlet is unloaded. Multiple threads (one per request) can execute this method in parallel so it must be thread safe.

public void destroy() This method is called once just before the servlet is unloaded and taken out of service.

The init method has a ServletConfig attribute. The servlet can read its initialization arguments through the ServletConfig object. How the initialization arguments are set is servlet engine dependent but they are usually defined in a configuration file. A typical example of an initialization argument is a database identifier. A servlet can read this argument from the ServletConfig at initialization and then use it later to open a connection to the database during processing of a request:
... private String databaseURL;
public void init(ServletConfig config) throws ServletException
{
super.init(config);
databaseURL = config.getInitParameter("database");
}

The Servlet API is structured to make servlets that use a different protocol than HTTP possible. The javax.servlet package contains interfaces and classes intended to be protocol independent and the javax.servlet.http package contains HTTP specific interfaces and classes. Since this is just an introduction to servlets I will ignore this distinction here and focus on HTTP servlets. Our first servlet, named ReqInfoServlet, will therefore extend a class named HttpServlet. HttpServlet is part of the JSDK and implements the Servlet interface plus a number of convenience methods. We define our class like this:

import javax.servlet.*;
import javax.servlet.http.*;
public class ReqInfoServlet extends HttpServlet
{ ... }
An important set of methods in HttpServlet are the ones that specialize the servicemethod in the Servlet interface. The implementation of service in HttpServlet looks at the type of request it's asked to handle (GET, POST, HEAD, etc.) and calls a specific method for each type. This way the servlet developer is relieved from handling the details about obscure requests like HEAD, TRACE and OPTIONS and can focus on taking care of the more common request types, i.e. GET and POST. In this first example we will only implement the
doGet method.
protected void doGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException
{ ... }

Request and Response Objects

The doGet method has two interesting parameters: HttpServletRequest and HttpServletResponse. These two objects give you full access to all information about the request and let you control the output sent to the client as the response to the request. With CGI you read environment variables and stdin to get information about the request, but the names of the environment variables may vary between implementations and some are not provided by all Web servers. The HttpServletRequest object provides the same information as the CGI environment variables, plus more, in a standardized way. It also provides methods for extracting HTTP parameters from the query string or the request body depending on the type of request (GET or POST).

As a servlet developer you access parameters the same way for both types of requests. Other methods give you access to all request headers and help you parse date and cookie headers. Instead of writing the response to stdout as you do with CGI; you get an OutputStream or a PrintWriter from the HttpServletResponse. The OuputStream is intended for binary data, such as a GIF or JPEG image, and the PrintWriter for text output. You can also set all response headers and the status code, without having to rely on special Web server CGI configurations such as Non Parsed Headers (NPH). This makes your servlet easier to install. Let's implement the body of our doGet method and see how we can use these methods.

We will read most of the information we can get from the HttpServletRequest (saving some methods for the next example) and send the values as the response to the request. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
 {
response.setContentType("text/html");
PrintWriter out = response.getWriter(); // Print the HTML header
out.println("<HTML><HEAD><TITLE>"); out.println("Request info");
out.println("</TITLE></HEAD>"); // Print the HTML body
out.println("<BODY><H1>Request info</H1><PRE>");
out.println("getCharacterEncoding: " + request.getCharacterEncoding());
out.println("getContentLength: " + request.getContentLength());
out.println("getContentType: " + request.getContentType());
out.println("getProtocol: " + request.getProtocol());
out.println("getRemoteAddr: " + request.getRemoteAddr());
out.println("getRemoteHost: " + request.getRemoteHost());
out.println("getScheme: " + request.getScheme());
out.println("getServerName: " + request.getServerName());
out.println("getServerPort: " + request.getServerPort());
out.println("getAuthType: " + request.getAuthType());
out.println("getMethod: " + request.getMethod());
out.println("getPathInfo: " + request.getPathInfo());
out.println("getPathTranslated: " + request.getPathTranslated());
out.println("getQueryString: " + request.getQueryString());
out.println("getRemoteUser: " + request.getRemoteUser());
out.println("getRequestURI: " + request.getRequestURI());
out.println("getServletPath: " + request.getServletPath());
out.println(); out.println("Parameters:");
Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) { String name = (String)
paramNames.nextElement();String[] values =
request.getParameterValues(name); out.println(" " + name + ":");
for (int i = 0; i < values.length; i++) { out.println(" " + values[i]); } }
out.println(); out.println("Request headers:");
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements())
{
String name = (String) headerNames.nextElement();
String value =request.getHeader(name);
out.println(" " + name + " : " + value);
 }
out.println(); out.println("Cookies:");
Cookie[] cookies =request.getCookies();
for (int i = 0; i < cookies.length; i++)
{
String name = cookies[i].getName(); String value = cookies[i].getValue();
out.println(" " + name + " : " + value);
} // Print the HTML footer
out.println("</PRE></BODY></HTML>");
out.close();
 }

The doGet method above uses most of the methods in HttpServletRequest that provide information about the request. You can read all about them in the Servlet API documentation so here we'll just look at the most interesting ones. getParameterNames and getParameterValues help you access HTTP parameters no matter if the servlet was requested with the GET or the POST method. getParameterValues returns a String array because an HTTP parameter may have multiple values.
For instance, if you request the servlet with a URL like
You’ll see that the foo parameter has two values: bar and baz. The same is true if you use the same name for more than one HTML FORM element and use the POST method in the ACTION tag. If you're sure that an HTTP parameter only can have one value you can use the getParameter method instead of getParameterValues. It returns a single String and if there are multiple values it returns the first value received with the request. You have access to all HTTP request headers with the getHeaderNames and getHeader methods. getHeader returns the String value of the header.

If you know that the header has a date value or an integer value you can get help converting the header to an appropriate format. getDateHeader returns a date as the number of milliseconds since January 1, 1970, 00:00:00 GMT. This is the standard numeric representation of a timestamp in Java and you can use it to construct a Date object for further manipulation. getIntHeader returns the header value as an int. getCookies parses the Cookie header and returns all cookies as an array of Cookie objects. To add a cookie to a response the HttpServletResponse class provides an addCookie method that takes a Cookie object as its argument. This saves you from dealing with the format for different versions of cookie header strings. If you compile the ReqInfoServlet and install it in your servlet engine you can now invoke it through a browser with a URL like
http://company.com/servlet/ReqInfoServlet/foo/bar?fee=baz.
If everything goes as planned you will see something like this in your browser:

Comments