Previous     Contents     Index     DocHome     Next     
iPlanet Application Server Programmer's Guide (Java)



Chapter 3   Presenting Application Pages with JavaServer Pages


This chapter describes how to use JavaServer Pages (JSPs) as page templates in iPlanet Application Server (iAS) web applications.

This chapter contains the following sections:



Introducing JavaServer Pages

JavaServer Pages (JSPs) are browser pages in HTML or XML. They can optionally contain Java code, which enables them to perform complex processing, conditionalize output, and communicate with other objects in your application. JSPs in iAS 6.0 are based on the JSP 1.1 specification. The specifications are accessible from installdir/ias/docs/index.htm, where installdir is the location where you installed iAS.

In an iAS application, you use JSPs as the individual pages that make up your application. You can call a JSP from a servlet to handle the output from a user interaction, or, since JSPs have the same access to the application environment as any other application components, you can use a JSP as a destination from an interaction.



How JSPs Work



A JSP is made up of JSP elements and template data. Template data refers to anything not in the JSP specification, including text and HTML tags. For example, the minimal JSP, which requires no processing by the JSP engine, is a static HTML page.

The iAS compiles JSPs into HTTP servlets the first time they are called. This makes them available to the application environment as standard objects, and it also enables them to be called from a client using a URL.

JSPs run inside a Java process on the server. This process, called a JSP engine, is responsible for interpreting JSP-specific tags and performing the actions they specify in order to generate dynamic content. This content, along with any template data surrounding it, is assembled into a page for output and returned to the caller.

The response object contains a reference to the calling client, and this is where a JSP presents the page that it creates. If you call a JSP from a servlet using the forward() method from the RequestDispatcher interface, forward() provides the response object as a parameter to the JSP. If a JSP is invoked directly from a client, the response object is provided by the server that is managing the relationship with the caller.

In either case, the page is automatically returned to the client through the reference provided in the response object. You do not have to write any code to return a page to a client.

You can create JSPs that are not a part of any particular application. These JSPs are considered to be part of a generic application. JSPs can also run in the iPlanet Web Server (iWS) and other web servers, but these JSPs have no access to any application data, which makes their use limited.

JSPs and some other application components can be updated at run time without restarting the server, making it easy to change the look and feel of your application without stopping service. For more information, see Appendix B "Dynamic Reloading" in this Programmer's Guide.



Designing JSPs



This section describes some of the decisions you must consider when you write JSPs. Since JSPs are compiled into servlets, the design considerations for servlets are also relevantto JSPs. See Chapter 2 "Controlling Applications with Servlets".

The information on a page can loosely be categorized into page layout elements, which consists of tags and information pertaining to the structure of the page, as well as page content elements, which consists of the actual information your page presents to the user.

You design page layout as you would design any browser page, interleaving content elements where needed. For example, one page element might be a welcome message ("Welcome to our application!") at the top of the page. You could personalize this message with a call to the user's name after authentication ("Welcome to our application, Mr. Einstein!").

Since page layout is a more or less straightforward task, the design decisions you must make are related more to the way the JSP interacts with the rest of the application and how it is optimized.

The following sections describe specific design issues:


Choose a Component: Servlet or JSP

If the layout of a page is its main feature and there is little or no processing involved to generate the page, you may find it easier to use a JSP alone for the interaction.

Think of JSPs and servlets as opposite sides of the same coin. Each can perform all the tasks of the other, but each is designed to excel at one task at the expense of the other. The strength of servlets is in processing and adaptability, and since they are Java files you can take advantage of integrated development environments while you are writing them. However, performing HTML output from them involves many cumbersome println statements that must be coded by hand. Conversely, JSPs excel at layout tasks because they are simply HTML files and can be created with HTML editors, though performing computational or processing tasks with them can be awkward. Choose the tool that is right for the job you undertake.

For example, the following simple component is presented as both a JSP and a servlet for comparison. This component, which performs no complex content generation activities, works best as a JSP:

JSP:

<html><head><title>Feedback</title></head><body>
<h1>The name you typed is: <% request.getParameter("name"); %>.</h1>
</body></html>

Servlet:

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

public class myServlet extends HttpServlet {
    public void service (HttpServletRequest req,
                         HttpServletResponse res)
                throws ServletException, IOException
    {
    response.setContentType("text/html");
    PrintWriter output = response.getWriter();
    output.println("<html><head><title>Foo</title></head>"
                 + "<body>\n"
                 + "<h1>The name you typed is:"
                 + req.getParameter("name") + ".</h1>"
                 + "</body></html>";
    }
}

For more information on servlets, see Chapter 2 "Controlling Applications with Servlets".


Designing for Ease of Maintenance: How Many JSPs?

Each of your JSPs can call or include any number of other JSPs. For example, you could have a generic corporate banner, a standard navigation bar, and left-side column table of contents, each of which resides in a separate JSP that you include for each page you build. This type of page can also be constructed with a JSP functioning as an frameset, dynamically determining the pages to load into each of its sub-frames.

A JSP can be included when the JSP is compiled into a servlet or when a request arrives.


Designing for Portability: Generic JSPs

You can write JSPs that are completely portable between different applications and different servers. They have a disadvantage in that they have no knowledge of application data in particular, but this is only a problem if they require that kind of data.

One possible use for generic JSPs is as portable page elements, like navigation bars or corporate headers and footers, that are meant to be included in other JSPs. You can create a library of reusable generic page elements to use throughout your application, or even among several applications.

For example, the minimal generic JSP is a static HTML page with no JSP-specific tags. A slightly less minimal JSP might contain some Java code that operates on generic data, such as printing the date and time, or makes a change to the page's structure based on a standard value in the request object.



Creating JSPs



You create JSPs in much the same way that you create static HTML files, including using a WYSIWYG page editor if that is your preference. JSP elements, including directive elements, scripting elements, and action elements, as described in the following sections.

The following sections describe how to use JSP-specific tags in HTML files in order to create JSPs. If you use an HTML editor to create pages and edit their layout, you can create a JSP by inserting these tags into the raw source code at the appropriate points.

This section contains the following subsections:


General Syntax

JSPs that adhere to the JSP 1.1 specification follow XML syntax for the most part, which is consistent with HTML. In other words, tags are demarcated with < and >, constructs have a start tag (<tag>) and end tag (</tag>), and tags are case-sensitive, such that <tag> is different from <Tag> or <TAG>.

In general, you insert JSP tags inline in the file where they are required, as if they were standard HTML tags. For example, if the request contains a parameter name that contains the user's name, you could write a welcome sentence like this:

<p>Hello, <%= request.getParameter("name"); %>.</p>


JSP Tags

JSP tags use the form <jsp:tag>, a form taken from XML. Some tags (particularly scripting tags) have a shortcut for use in HTML files, generally starting with <% and ending with %>.

Note that these shortcuts are not valid for XML files.

Empty elements, tag constructs that have nothing between the start and end tags, can be shortened to one tag ending with />, as in this example:

<!-- include tag with no body: -->
<jsp:include page="/corporate/banner.jsp"></jsp:include>

<!-- include tag can also be written like this: -->
<jsp:include page="/corporate/banner.jsp" />

White space is not usually significant, although you should make sure to put a space character between the opening tag and any attributes. For example: <%= myExpression %> is valid, <%=myExpression %> is not.


Escape Characters

In attributes, where you may find difficulty with nested single and double quotes, use the following escape characters:

  • ` is quoted as \`

  • " is quoted as \"

  • %> is quoted as %\>

  • <% is quoted as <\%


Comments

There are two types of comments in JSPs:

  • comments to the JSP page itself, documenting what the page is doing

  • comments that appear in the generated document sent to the client


JSP Comments
A JSP comment is contained within <%-- and --%>, and can contain anything except the text --%>. The following example, therefore is incorrect:

<%-- anything but a closing --%> ... --%>

An alternative way to place a comment in a JSP is to use a Java comment. For example:

<% /** this is a comment ... **/ %>


Generating Comments in Output to Client
In order to generate comments that appear in the response output stream to the requesting client, use the HTML and XML comment syntax as in the following example:

<!-- comments ... -->

These comments are treated as uninterpreted template text by the JSP engine. If the generated comment is to have dynamic data, this can be obtained through an expression syntax, as in the following example:

<!-- comments <%= expression %> more comments ... -->


Java Directives

<%@ directive { attr="value" }* %>

Use directives to set preferences within the JSP. Each directive has a number of attributes that affect the behavior or state of the JSP.

Valid directives are:


<%@ page%>


Syntax
<%@ page language="java"
         extends="className"
         import="className{,+}"
         session="true|false"
         buffer="none|sizeInKB"
         autoFlush="true|false"
         isThreadSafe="true|false"
         info="text"
         errorPage="jspUrl"
         isErrorPage="true|false"
         contentType="mimeType{;charset=charset}"
%>


Description
Sets page-level preferences for the JSP.


Attributes
Valid attributes include the following:


Table 3-1 Java page Directive

Attribute

Valid Values

Description

language  

java  

Default: java. Scripting language for this JSP. Currently, iAS only supports java.  

extends  

valid Java class name  

Defines a specific superclass for this JSP. This restricts the JSP engine in many ways, and should be avoided if possible.  

import  

comma-separated list of valid Java class names  

Types and classes that are available to other methods in this JSP. This is identical to the import statement in a Java class.  

session  

true or false  

Default: true. Indicates that the page must participate in an HTTP session. If language=java and session=true, this option creates an implicit variable called session which points to or creates a session of type javax.servlet.http.HttpSession  

buffer  

none, or buffer size in kilobytes  

Defines an output buffer. If this is set to none, all output is written directly to the output stream (a PrintWriter object). If a size is provided, then either the buffer is flushed or an exception is raised when it is filled with output. The behavior is determined by the autoFlush attribute.  

autoFlush  

true or false  

Determines behavior when output buffer is full. If true, output is flushed to the output stream when buffer is full. If false, an exception is raised when the buffer is full.  

isThreadSafe  

true or false  

Default: false. Indicates the level of thread safety implemented in the page. The value determines behavior inside the JSP engine: if true, multiple requests can be made to the JSP instance simultaneously, otherwise multiple requests are handled serially. For the most part, you should ensure that your JSP is thread-safe regardless of this setting, as this setting has no effect on shared objects such as sessions or contexts.  

info  

text  

A string incorporated into the translated page that can subsequently be obtained from the page's implementation of the Servlet.getServletInfo() method.  

errorPage  

valid URL for a JSP error page  

Error page for this JSP. This error page must be a JSP. Any Throwable object that is thrown but not caught by the original page are forwarded to the error page. The error page has an implicit variable called exception that contains a reference to the un-caught exception. Note that if autoFlush=true, then if the contents of the initial JspWriter has been flushed to the ServletResponse output stream (i.e., if part of the page has already been sent to the client) then any subsequent attempt to invoke an error page may fail.  

isErrorPage  

true or false  

Default: false. Indicates whether the current JSP page is the possible target of another JSP page's errorPage. If true, then the implicit variable exception is defined and its value is a reference to the offending Throwable from the source JSP page in error.  

contentType  

content type, optionally with charset  

Default:
text/html;charset=ISO-8859-1
Defines the MIME type and character encoding for the response. Values are either of the form TYPE or
TYPE;charset=CHARSET
 


Examples
<%@ page errorpage="errorpg.htm" %>
<%@ page import="java.io.*,javax.naming.*" %>


<%@ include%>


Syntax
<%@ include file="file" %>


Description
The include directive enables you to include other JSPs (or static pages) when the JSP is compiled into a servlet. The resource is treated as if it were a part of the JSP.

There is another method for including other resources: the <jsp:include> action, which includes the resource at request-time. For more information on file inclusion, see Including Other Resources.


Attributes
The include directive has only one attribute, as described below:


Table 3-2 Java include Directive

Attribute

Valid Values

Description

file  

Valid URL (absolute) or URI (relative path)  

The file to be included.  

The file attribute can either be relative to the current JSP, or absolute to the application's context root. For relative file attributes, the file name should not begin with a backslash (`/'), but for absolute file attributes, the file name should begin with a backslash (`/').


Example
If Foo.jsp is a JSP file in the application MyApp (typically located in $installdir/ias/APPS/MyApp), and Foo.jsp contains the following tag:

<%@include file="/bar/baz.jsp"%>

then the system tries to include the file baz.jsp from $installdir/ias/APPS/MyApp/bar/baz.jsp.

If baz.jsp contains the following tag:

<%@include file="boo.jsp"%>

then the system will also include the file $installdir/ias/APPS/MyApps/bar/boo.jsp.


<%@ taglib... %>


Syntax
<%@ taglib uri="uriToTagLibrary" prefix="prefixString" %>

The taglib directive enables you to create your own custom tags. For more information on creating your own tags, see section Value-added Features.


Attributes
The taglib directive specifies two attributes, as described below:


Table 3-3 Java taglib Directive

Attribute

Valid Values

Description

uri  

Valid URI (relative path)  

The URI (Universal Resource Identifier) is either an absolute (from the application's context root) or a relative reference to a .tld XML file, that describes the tag library. The URI can also be an alias that is unaliased by the <taglib> entry in the web application descriptor of the JSP. (see JSP v1.1 specification section 5.2 Tag Library for more details)  

prefix  

String  

A prefix for the custom tag.  


Example

Consider the following JSP file, Foo.jsp, in the application MyApp, and a corresponding XML deployment file with a web-app section as follows:

<taglib>
   <taglib-uri> http://www.mytaglib.com/spTags </taglib-uri>
   <taglib-location> /foo/bar/baz.tld</taglib-location>
<taglib>

The JSP file contains the following:
<%@ taglib uri="http://www.mytaglib.com/spTags" prefix="mytags" %>
<mytags:specialTag attribute="value"> ... </mytag:specialTag>

The JSP engine looks inside the web app descriptor to find a matching taglib-location for "http://www.mytaglib.com/spTags". The engine locates /foo/bar/baz.tld, and therefore looks for an XML file $installdir/ias/APPS/MyApp/foo/bar/baz.tld. This is the Tag Library Descriptor file that describes the tags used in the file.

The URI, or taglib-location (if the URI is aliased), can also be relative. In this case the .tld file is searched for relative to the current directory. See JSP v1.1 specification, section 5.2 Tag Library for more details.


Java Scripting Elements

Scripting elements are made up of the following types of tags:

There are several implicit objects available to your scripts, including the request and response objects. For more information about implicit objects, see Implicit Objects.


Java Declarations <%! ... %>


Syntax
<%! declaration %>


Description
Use declarations to define variables that are valid throughout the JSP. You can declare anything legal in Java, including methods, as long as the declaration is complete. Nothing appears in the output stream as a result of a declaration.


Example
<%! int i=0; %>
<%! String scriptname="myScript"; %>
<%! private void myMethod () { ... } %>


Java Expressions <%= ... %>


Syntax
<%= expression %>


Description
Use expressions as variables to be evaluated. The value of the expression is substituted where the expression occurs. The result appears on the output stream.


Example
<p>My favorite color is <%= userBean.favColor %>.</p>


Java Scriptlets <%...%>


Syntax
<% script %>


Description
Use scriptlets to define blocks of code to be executed. Any legal code can appear here,


Example
<% int balance = request.getAttribute("balance");
   if (balance < LIMIT) {
      println (UNDERLIMIT_ALERT);
   }
   String balString = formatAsMoney(balance);
%>
Your current balance is <%= balance %>.


Java Actions

Actions, as the name implies, perform some activity, such as creating/loading a Java bean or setting or retrieving bean properties, including other JSPs, or specifying required plugins.

Some actions allow request-time expressions as parameters, enabling you to set values for these attributes dynamically for the request.For examples, see the attribute in question. The attributes that allow expressions as parameters are the value and name attributes of <jsp:setProperty> and the page attribute of <jsp:include> and <jsp:forward>.

Standard actions are described as follows:


<jsp:useBean>


Syntax
<jsp:useBean id="name" scope="scope"
             class="className" |
             class="className" type="typeName" |
             beanName="beanName" type="typeName" |
             type="typeName">
// optional body
</jsp:useBean>


Description
The <jsp:useBean> action tries to find a Java bean with the given name (id) and scope (scope). If one exists, it is made available, otherwise it is created using the provided name, scope, and type/class information. A variable called name, specified with the attribute id="name", is made available to the JSP so that you can access the object if the action succeeds.

<jsp:useBean> can be an empty tag, as in <jsp:useBean ... />, or it can contain other actions and close with the end tag </jsp:useBean>. Other actions that normally appear here are <jsp:setProperty> actions that set properties in the (possibly newly-created) bean. Template text, other scripts or declarations, etc. are treated normally. Note that the body of a <jsp:useBean> tag is executed only once, when the bean is created.

The <jsp:useBean> action must specify a unique id="name" attribute. If the action succeeds in creating or accessing an object, this name makes the object available to scripting tags further down in the JSP.


Attributes
Valid attributes are as follows:


Table 3-4 Attributes for <jsp:useBean>

Attribute

Description

id  

Unique identifying name for the object.  

scope  

Lifecycle for this object. One of the following:

page: Object is valid for this page only, even if the request encompasses more than one page. The object is not forwarded to other pages.

request: Object is bound to the request object (retrieve with getAttribute(name) where name is the object's id), and is thus available for the life of this request.

session: Object is bound to the session object (retrieve with getValue(name) where name is the object's id) and is thus available wherever the session is available, for the life of the session. A session must be active for this JSP in order to use this scope.

application: Object is bound to the ServletContext (retrieve with getAttribute(name) where name is the object's id) and is thus available for the existence of the application, unless it is specifically destroyed.  

class  

Valid classname for this bean, used to instantiate the bean if it does not exist. If type is specified, class must be assignable to type. beanName and class can not both be specified for the same bean.  

beanName  

Valid name of a bean, of the form a.b.c (classname) or a/b/c (resource name). beanName and class can not both be specified for the same bean. The beanName attribute can be an expression, evaluated at request-time.  

type  

Defined variable type for this bean. This attribute enables the type of the variable to be distinct from that of the implementation class specified. The type is required to be either the class itself, a superclass of the class, or an interface implemented by the class specified. If unspecified, the value is the same as the value of the class attribute.  


Examples
This example shows the creation of a bean, or access to a bean that already exists, called currentUser of type com.netscape.myApp.User:

<jsp:useBean id="currentUser" class="com.netscape.myApp.User" />

In this example, the object should have been present in the session. If so, it is given the local name wombat with WombatType. A ClassCastException may be raised if the object is of the wrong class, and an InstantiationException may be raised if the object is not defined.

<jsp:useBean id="currentUser"
             type="com.netscape.myApp.User"
             scope="session" />

Also see the Examples section for <jsp:setProperty>, below.


<jsp:setProperty>


Syntax
<jsp:setProperty name="beanName"
                 property="propertyName"
                 param="requestParameter" | value="value"
</jsp:setProperty>


Description
The <jsp:setProperty> action sets the value of properties in a bean. It is used in the body of a <jsp:useBean> tag to set bean properties. The property's value may be determined with an expression. It may also come directly from the request object.


Attributes
Valid attributes are as follows:


Table 3-5 Attributes for <jsp:setProperty>

Attribute

Description

name  

Name of the bean in which you want to set a property. The name must be defined previously in the file with <jsp:useBean>.  

property  

The name of the bean property whose value you want to set. The property must be a valid property in the bean. If propertyName="*" then the tag iterates over the parameters in the request object, matching parameter names and value type(s) to property names and setter method type(s) in the bean, setting each matched property to the value of the matching parameter. If a parameter has an empty value, the corresponding property is not modified. Note that any previous value for that parameter persists.  

param  

The name of the request object parameter whose value you want to give to a bean property. If you omit param, the request parameter name is assumed to be the same as the bean property name If the param is not set in the request object, or if it has an empty value, the <jsp:setProperty> action has no effect. A <jsp:setProperty> aaction may not have both param and value attributes.  

value  

The value to assign to the given property. This attribute can accept an expression as a value; the expression is evaluated at request-time. A <jsp:setProperty> action may not have both param and value attributes.  


Examples
In this example, the name and permissions properties are set:

<jsp:useBean id="currentUser" class="com.netscape.myApp.User" >
    <jsp:setProperty name="currentUser"
                     property="name"
                     param="name">
    <jsp:setProperty name="currentUser"
                     property="permissions"
                     param="permissions">
</jsp:useBean>

These examples both set a property name to the value of a corresponding request parameter also called name:

<jsp:setProperty name="myBean" property="name" param="name" />

<jsp:setProperty name="myBean" property="name"
                 value="<%= request.getParameter(\"name\" %>)" />


<jsp:getProperty>


Syntax
<jsp:getProperty name="beanName"
                 property="propertyName">


Description
A <jsp:getProperty> action places the value of a bean property, converted to a String, into the output stream.


Attributes
Valid attributes are as follows:


Table 3-6 Attributes for <jsp:getProperty>

Attribute

Description

name  

Name of the bean from which you want to retrieve a property. The name must be defined previously in the file with <jsp:useBean>.  

property  

The name of the bean property whose value you want to retrieve. property must be a valid property in the bean.  


Examples
<jsp:getProperty name="currentUser" property="name" />


<jsp:include>


Syntax
<jsp:include page="uri" flush="true"/>



Description

A <jsp:include> action includes the specified page in the current page at request-time, preserving the current page's context. Using this method, the included page is written to the output stream.

There is another method for including other resources: the <%@ include%> directive, which includes the resource at compile-time. For more information on file inclusion, see Including Other Resources.


Attributes
Valid attributes are as follows:


Table 3-7 Attributes for <jsp:include>

Attribute

Description

page  

This is either an absolute or relative reference to the page being included. For absolute references, this field begins with a backslash ("/"), and is rooted at the application's context root. For relative references, this field is relative to the JSP file performing the include, and may contain an expression that is evaluated at request time.  

flush  

Determines whether the included page is to be flushed to the output stream.  


Examples
<jsp:include page="/templates/copyright.html" flush="true" />


<jsp:forward>


Syntax
<jsp:forward page="URL" />


Description
The <jsp:forward> action allows the runtime dispatch of the current request to a static resource, a JSP page, or a Java servlet in the same context as the current page, terminating the execution of the current page. This action is identical to the forward() method of the RequestDispatcher interface.


Attributes
Valid attributes are as follows:


Table 3-8 Attributes for <jsp:forward>

Attribute

Description

page  

Valid URL pointing to the page to be included. This attribute may contain an expression which is evaluated at request-time, as long as this expression must evaluate to a valid URL.  

Note If page output is unbuffered (as with <% page buffer="none" %>) and data has already been written to the output stream, this tag results in a runtime error.


Examples
<jsp:forward page="/foo/handleAlternativeInput.jsp" />

The following element might be used to forward to a static page based on some dynamic condition.

<% String whereTo = "/templates/"+someValue; %>
<jsp:forward page="<%= whereTo %>" />


<jsp:plugin>


Syntax
<jsp:plugin type="bean|applet"
            code="objectCode"
            codebase="objectCodebase"
            { align="alignment" }
            { archive="archiveList" }
            { height="height" }
            { hspace="hspace" }
            { jreversion="jreversion" }
            { name="componentName" }
            { vspace="vspace" }
            { width="width" }
            { nspluginurl="URL" }
            { iepluginurl="URL" } >
            { <jsp:params
                  <jsp:param name=" paramName" value="paramValue" />
              </jsp:params> }
            { <jsp:fallback> fallbackText </jsp:fallback> }
</jsp:plugin>


Description
The <jsp:plugin> action enables a JSP author to generate HTML that contains the appropriate client browser dependent constructs (object or embed) to instruct the browser to download (if required) an appropriate Java plug-in and execute an Applet or JavaBeans component. The attributes of the <jsp:plugin> tag provide configuration data for the presentation of the element.

The <jsp:plugin> tag is replaced by either an <object> or <embed> tag, as appropriate for the requesting user agent, and emitted into the output stream of the response.

There are two related actions that are only valid within a <jsp:plugin> action:

  • <jsp:params> sets off a block containing parameters to the Applet or JavaBeans component. Individual parameters are set with

  • <jsp:param name="name" value="value">

  • The section ends with </jsp:params>. The names and values are component-dependent.

  • <jsp:fallback> indicates the content to be used by the client browser if the plugin cannot be started (either because object or embed is not supported by the client browser, or due to some other problem). The body of this tag is presented to the browser in the event of a failure of the surrounding <jsp:plugin>. For example:

    <jsp:plugin ...>
       <jsp:fallback><b>Plug-in could not be started!</b></jsp:fallback>
    </jsp:plugin>

If the plugin can start but the Applet or JavaBeans component cannot be found or started, a plugin-specific message is usually presented to the user, often as a pop-up window reporting a ClassNotFoundException.


Attributes
The <jsp:plugin> tag takes most of its attributes from the HTML <applet> and <object> tags (<applet> is defined in HTML 3.2, <object> in HTML 4.0). Refer to the official HTML specifications where these tags are introduced:

  • HTML 3.2: http://www.w3.org/TR/REC-html32.html

  • HTML 4.0: http://www.w3.org/TR/REC-html40/

Valid attributes for the <jsp:plugin> tag are as follows.


Table 3-9 Attributes for <jsp:plugin>

Attribute

Description

type  

Identifies the type of the component, bean or applet.  

code  

As defined by the HTML spec.  

codebase  

As defined by the HTML spec.  

align  

As defined by the HTML spec.  

archive  

As defined by the HTML spec.  

height  

As defined by the HTML spec.  

hspace  

As defined by the HTML spec.  

jreversion  

Identifies the specification version number of the JRE the component requires in order to operate. Default: 1.1  

name  

As defined by the HTML spec.  

vspace  

As defined by the HTML spec.  

title  

As defined by the HTML spec.  

width  

As defined by the HTML spec.  

nspluginurl  

URL where JRE plugin can be downloaded for Netscape Navigator, default is implementation defined.  

iepluginurl  

URL where JRE plugin can be downloaded for Microsoft Internet Explorer, default is implementation defined.  


Examples
<jsp:plugin type="applet"
            code="Tetris.class"
            codebase="/html" >
    <jsp:params>
        <jsp:param name="mode" value="extraHard"/>
    </jsp:params>

    <jsp:fallback>
        <p> unable to load Plugin </p>
    </jsp:fallback>
</jsp:plugin>


Implicit Objects

The JSP 1.1 specification defines some objects that are available implicitly for every JSP. They can be referred to from anywhere in your JSP, without previously defining them (for example, with <jsp:useBean>).

The following objects are available implicitly for every JSP:


Table 3-10 Implicitly Available Objects for Every JSP

Object

Description

Scope

Java type

request  

The request that triggered this JSP's execution.  

request  

protocol-dependent subtype of javax.servlet.ServletRequest, e.g. javax.servlet.HttpServletRequest  

response  

The response to the request (i.e., the returned page and its path back to the caller).  

page  

protocol-dependent subtype of javax.servlet.ServletResponse, e.g. javax.servlet.HttpServletResponse  

pageContext  

The page context for this JSP.  

page  

javax.servlet.jsp.PageContext  

session  

The session object (if any) created for or associated with the caller.  

session  

javax.servlet.http.HttpSession  

application  

The servlet context for this JSP, from the servlet's configuration object via getServletConfig().
getContext()
.
 

application  

javax.servlet.ServletContext  

out  

An object that writes to the output stream.  

page  

javax.servlet.jsp.JspWriter  

config  

The servlet configuration object (ServletConfig) for this JSP.  

page  

javax.servlet.ServletConfig  

page  

The instance of this page's class that is processing the current request. page is a synonym for the keyword this.  

page  

java.lang.Object  

exception  

For error pages only, the uncaught Throwable exception that caused the error page to be invoked.  

page  

java.lang.Throwable  

For example, you can refer to the request object as follows:

One of the request parameters was <%= request.getParameter("param"); %>.



Programming Advanced JSPs



This section provides some instructions for using advanced programing techniques. This section includes the following subsections:


Including Other Resources

An important feature of JSPs is their ability to dynamically include other page-generating resources, or their results, at run-time. You can include the contents of a static HTML page, or you can process a separate JSP and include its results in your output page.

For example, corporate headers and footers can be included on each page appropriately by creating page stubs that contain just the included elements. Note that it is possible to include entire pages on a conditional basis, which provides much more flexibility than simply inserting flat navigation bars or corporate headers.

There are two ways to include a resource in your JSP:

<%@ include file="filename" %>

<jsp:include page="uri" flush="true" />

If you include a resource using the <%@ include%> directive, the resource is included when the JSP is compiled into a servlet, and is thus treated as if it were a part of the original JSP. If the included resource is also a JSP, its contents are processed along with the parent JSP. For more information, see Java Directives.

If you include a resource using the <jsp:include> action, the included resource is included when the JSP is requested by a caller. For more information, see Java Actions.

The following example shows how each portion of a page can be provided by a separate resource, accessed from a single JSP. The source code for this example page shows both methods for including resources: static resources are included using the <jsp:include> action, dynamic resources are included using the <%@ include%> directive.




afterLogin.jsp:
<html><head><title>Sample Corporate Page</title></head><body>

<p align="left"><jsp:include page="corpHead.htm" flush="true" /></p>
<%@ include file="navBar.jsp" %>
<hr size="3">

<table border=0><tr>
<td width="25%"><%@ include file="appToc.jsp" %></td>
<td width="75%"><%@ include file="appToc.jsp" %></td>
</tr></table>

<hr>
<p align="left"><jsp:include page="corpFoot.htm" flush="true" /></p>
</body></html>


Using Java Beans

JSPs support several tags for the purpose of instantiating and accessing Java beans. You use beans to perform computations in order to obtain a set of results, which are stored as bean properties. JSPs provide automatic support for creating beans and for examining their properties.

Beans themselves are separate classes created according to the Java Bean specification. It is beyond the scope of this manual to describe how to create standard Java beans. For more information about Java beans, visit the official web site http://java.sun.com/beans. There are many tutorials that describe how to create beans, some of which are accessible from the official site.

It is common in beans to have "getter" and "setter" methods to retrieve and set bean properties. Getter methods are named getXxx(), where Xxx is a property called xxx (the first letter is capitalized for the method name). If you have a corresponding setter called setXxx(), the setter must take a parameter of the same type as the return value from the getter.

Note Note that this support is for standard Java beans, not EJBs. To access EJBs from your JSP, see Accessing Business Objects.

Note In NAS 4.0, which supported the JSP 0.92 specification, the request and response objects were accessed via "implicit beans". This support has changed in the JSP 1.1 specification; several objects, including the request and response objects, are available implicitly, with varying degrees of scope. See Implicit Objects.


Accessing Business Objects

Because JSPs are compiled into servlets at run-time, they have full access to the rest of the processes running in the server, including EJBs. You can access beans or servlets in the same way you would access them from a servlet, as long as the Java code you write is embedded inside an escape tag.

The method described here for contacting EJBs is identical to the method used from servlets. For more information, see "Accessing Business Logic Components" in Chapter 2 "Controlling Applications with Servlets" in the Programmer's Guide.

This example shows a JSP accessing an EJB called ShoppingCart by creating a handle to the cart by casting the user's session ID as a cart after importing the cart's remote interface:

<%@ import cart.ShoppingCart %>;
...
<% // Get the user's session and shopping cart
   ShoppingCart cart = (ShoppingCart)session.getValue(session.getId());

   // If the user has no cart, create a new one
   if (cart == null) {
        cart = new ShoppingCart();
        session.putValue(session.getId(), cart);
   } %>
...
<%= cart.getDataAsHTML() %>

This example shows the use of JNDI to look up a proxy, or handle, for the cart:

<% String jndiNm = "java:/comp/ejb/ShoppingCart";
   javax.naming.Context initCtx;
   Object home;
       try {
             initCtx = new javax.naming.InitialContext(env);
       } catch (Exception ex) {
             return null;
       }
       try {
             java.util.Properties props = null;
             home = initCtx.lookup(jndiNm);
       }
       catch(javax.naming.NameNotFoundException e)
       {
             return null;
       }
       catch(javax.naming.NamingException e)
       {
             return null;
       }
       try {
              IShoppingCart cart = ((IShoppingCartHome) home).create();
             ...
      } catch (...) {...}
%>
...
<%= cart.getDataAsHTML() %>

Note You must usually provide a method in the EJB to convert raw data to a format acceptable on the page, such as getDataAsHTML() in the examples above.

For more information on contacting EJBs, see "Accessing Business Logic Components" in Chapter 2 "Controlling Applications with Servlets".



Deploying JSPs



There are two ways iAS deploys JSPs; they are deployed as either unregistered JSPs or as registered JSPs.


Unregistered JSPs

Unregistered JSPs are deployed by simply being copied into the corresponding directory (the name of which is the same as the application name), in the AppPath. These JSPs can then be invoked using the URL access as follows:

  • http://s:p/AppPrefix/AppName/JSPFileName

Refer to the Invoking JSPs for more details.


Registered JSPs

The iAS allows for JSPs to be registered with GUIDs, using XMLs, a la Servlets. This allows for JSPs to use iAS-value-added features like load balancing. This is performed by registering XML files with the <jsp-file> entry as detailed in the Servlet 2.2 specification.

The following XML file is an example of a deployment descriptor for a registered JSP:

MyApp.xml:

<?xml version="1.0" ?>

<!DOCTYPE web-app>

<web-app>

<display-name> An Example Registered JSP File </display-name>

<servlet>

<servlet-name>JSPExample</servlet-name>

<jsp-file>JSPExample.jsp</jsp-file>

</servlet>

<servlet-mapping>

<servlet-name>JSPExample</servlet-name>

<url-pattern>/jspexample</url-pattern>

</servlet-mapping>

</web-app>

ias-MyApp.xml:

<?xml version="1.0" ?>

<ias-web-app>

<servlet>

<servlet-name>JSPExample</servlet-name>

<guid>{aaaabbbb-A456-161A-8be4-0800203942f2}</guid>

</servlet>

</ias-web-app>

In the above example, the JSP is registered with the GUID specified in the ias-MyApp.xml file. Although this example indicates that the servlet name is JSPExample, it does not mean that use of the .jsp extension is required. Its completely possible to have the servlet name as JSPExample.jsp instead. This JSP can then be accessed from a URL by using one of the following:

  • http://s:p/AppPrefix/MyApp/JSPExample

  • http://s:p/AppPrefix/MyApp/JSPExample.jsp (use if the servlet-name entry in the XML file is JSPExample.jsp)



Invoking JSPs

You can invoke a JSP programmatically from a servlet, or you can address it directly from a client using a URL. You can also include JSPs as well as invoke them; see Including Other Resources.


Calling a JSP With a URL

You can call JSPs using URLs embedded as links in your application's pages. This section describes how to invoke servlets using standard URLs.


Invoking JSPs in a Specific Application

JSPs that are part of a specific application are addressed as follows:

http://server:port/AppPrefix/appName/jspName?name=value

Each section of the URL is described in the table below:




URL element

Description

server:port  

Address and optional port number for the web server handling the request.  

AppPrefix  

Indicates to the web server that this URL is for a iAS application, so the request is routed to the iAS executive server. This is configured using the registry entry SSPL_APP_PREFIX.  

appName  

The application's name, which must be identical to the name of the application's subdirectory under AppPath.  

jspName  

The JSP's filename, including the .jsp extension.  

?name=value...  

Optional name-value parameters to the JSP. These are accessible from the request object.  

For example:

http://www.my-company.com/AppPrefix/OnlineBookings/directedLogin.jsp

Note The use of a generic application for a JSP has the same requirements and restrictions as a generic application for a servlet. There needs to be an application called "Default" that must have an XML file registered. Any URL request that accesses a servlet or a JSP with the /servlet/ entry is forwarded to the generic application "Default". This requirement is detailed in section "Invoking Generic Application Servlets," of Chapter 2 "Controlling Applications with Servlets".


Invoking JSPs in the Generic Application

JSPs that are not part of a specific application are addressed as follows:

http://server:port/servlet/jspName?name=value

Each section of the URL is described in the table below:




URL element

Description

server:port  

Address and optional port number for the web server handling the request.  

servlet  

Indicates to the web server that this URL is for a generic servlet object.  

jspName  

The JSP's name, including the .jsp extension.  

?name=value...  

Optional name-value parameters to the JSP. These are accessible from the request object.  

For example:

http://www.leMort.com/servlet/calcMort.jsp?rate=8.0&per=360&bal=180000


Invoking a JSP From a Servlet

A servlet can invoke a JSP in one of two ways:

  • The include() method in the RequestDispatcher interface calls a JSP and waits for it to return before continuing to process the interaction.

  • The forward() method in the RequestDispatcher interface hands control of the interaction to a JSP.

For more information on these methods, see "Delivering Results to the Client" in Chapter 2 "Controlling Applications with Servlets" in the Programmer's Guide.

An example of this is as follows:

public class ForwardToJSP extends HttpServlet
{
   public void service(HttpServletRequest req,
                        HttpServletResponse res)
   throws ServletException, IOException
  {
     RequestDispatcher rd = req.getRequestDispatcher("/test.jsp");
     rd.forward(req, res);
  }
}



JSP 1.1 Tag Summary




Directives
<%@ page|include|taglib { attr="value" }* %>

    attr: page language="java"
               extends="className"
               import="className{,+}"
               session="true|false"
               buffer="none|sizeInKB"
               autoFlush="true|false"
               isThreadSafe="true|false"
               info="text"
               errorPage="jspUrl"
               isErrorPage="true|false"
               contentType="mimeType{;charset=charset}"

          include file="filename"

         taglib uri="uriToTagLibrary"
                prefix="prefixString"

See Java Directives.


Expressions
<%= expression %>

See Java Scripting Elements.


Scriptlets
<% scriptlet %>

See Java Scripting Elements.


Comments
<%-- comment --%>       JSP comment, not passed to client
<!-- comment -->        standard HTML comment, passed to client
<% /** comment **/ %>   Java comment, encapsulated in scriptlet, passed to client

See Comments.


Bean-Related Actions
<jsp:useBean id="name" scope="scope"
             class="className" |
             class="className" type="typeName" |
             beanName="beanName" type="typeName" |
             type="typeName">
// optional body
</jsp:useBean>

<jsp:setProperty name="beanName"
                 property="propertyName"
                 param="requestParameter" | value="value"
</jsp:setProperty>

<jsp:getProperty name="beanName"
                 property="propertyName">

See Java Actions.


Other Actions
<jsp:include page="relativeUrl"
             flush="true" />

<jsp:forward page="URL" />

<jsp:plugin type="bean|applet"
            code="objectCode"
            codebase="objectCodebase"
            { align="alignment" }
            { archive="archiveList" }
            { height="height" }
            { hspace="hspace" }
            { jreversion="jreversion" }
            { name="componentName" }
            { vspace="vspace" }
            { width="width" }
            { nspluginurl="URL" }
            { iepluginurl="URL" } >
            { <jsp:params
                 <jsp:param name=" paramName" value="paramValue" />
              </jsp:params> }
            { <jsp:fallback> fallbackText </jsp:fallback> }
</jsp:plugin>

See Java Actions.



Value-added Features




PagePath

A static (HTML) or dynamic (JSP) page is looked up by first looking inside the directory identified by $AppPath (assigned to the registry key \\SOFTWARE\Netscape\Application Server\4.0\AppPath), and, then, if not found, inside any of the directories identified by $PagePath (registry key: \\SOFTWARE\Netscape\Application Server\6.0\PagePath). This is an optional key that is not present by default, and will need to be added, if used. Whereas $AppPath is a single directory, $PagePath is a list of directories, separated by the path-list character of the current system (':' on Unix, and ';' on NT).

A dynamic page is compiled into the directory $AppPath/compiled_jsp, where both its class and intermediate source file are stored. Hence, a dynamic page should have a unique path relative to $AppPath and $PagePath to avoid confusion. Also, note, that the rules for relative paths specified in JSP 1.1 apply to both AppPath and PagePath, i.e. a uri to a page is relative to the current application context.

Hence, suppose A.jsp is stored as:

$AppPath/myApp/dir/A.jsp, and includes B.jsp as <jsp:include page="B.jsp"/>, then the JSP engine will first look for B.jsp in $AppPath/myApp/dir, and then in $PagePath[0]/myApp/dir, $PagePath[1]/myApp/dir, etc.


Custom Tag Extensions

The JSP v1.1 specification details a protocol to support user-defined custom tags. (See JSP v1.1 specification Chapter 5 Tag Extensions.) Although the specification does not mandate any tags, as a value-add to iAS users, iAS ships with certain custom tags that follow the JSP 1.1-defined protocol for tag extensions.

Some of these tags are meant to provide support for LDAP and database querying, and others provide support for using conditionals inside JSPs, for which there's no primitive support as part of the specification.

In order to support JSP page-caching, iAS ships with a Cache tag library. Details on how this is used are also provided in this chapter's section JSP Page Caching.

The other tags included within iAS are for internal use only, specifically to support converting GX tags in NAS 4.0 applications. These tags are used in generating JSP 1.1 pages from JSP 0.92 pages (which supported GX tags), and should not be used anywhere externally.

The following tag libraries are introduced by iAS:

  • Query

  • LDAP

  • Conditional

  • Attribute


Database Query TagLib

The query taglib supports declarative declarations of RowSets in a JSP page, along with loops for looping through result-sets and a display tag fordisplaying column values.


List of Query tags:

  1. <rdbm:useQuery id="export_name" scope="[page|request|session|application]" command="select * from..." queryFile="foo.gxq" queryName="firstQuery"
    execute="[true|false]" dataSourceName="jdbc/..." url="odbc:...">...</rdbm:useQuery>

  2. <rdbm:param query="query-declaration-export-name" name="name-of-parameter" value="value" bindOnLoad="[true|false]" type="[String|Int|Double|Float|BigDecimal|Date|Boolean|Time|Timestamp"
    format="java-format-string for dates">value</rdbm:param>

  3. <rdbm:loop id="export_name" scope="[page|request|session|application]" query="query-declaration-export-name" start="[request-parameter-name|request-attribute-name|last|constant]" max="integer-maximum-number-of-rows" execute='{true|false]">...</rdbm:loop>

  4. <rdbm:field query="query-declaration-export-name" name="field name" format="format for doubles" urlEncode="{false/true}">default

value</rdbm:field>

  1. <rdbm:close resource="query-declaration-export-name"/>

  2. <rdbm:execute query="query-declaration-export-name"/>

  3. <rdbm:goRecord query="query-declaration-export-name" execute="{false/true}" start="[request-parameter-name|request-attribute-name|last|constant]">default
    start</rdbm:goRecord>


useQuery tag
The useQuery tag declares a use of a result-set. The useQuery tag allows the tool to understand what query is being made, and hence, what fields are available for use. If the result set is already in the scope that the useQuery wants to save to, then the body of this tag is skipped, and, although the RowSet is currently created, nothing is done with the created RowSet.

If the result-set does not already exist, the created RowSet is exported using the id attribute of the useQuery tag at the specified scope, which defaults to request. Either the command specified is used, or a query located in the queryFile is loaded. The name of the loaded query is either the name located in the queryName attribute, or, if none is specified, the value of the tag's id attribute. Once the rowset is initialized, it may be executed if the execute tag is specified. It is important to execute a query if you want to use the field tag outside of a loop.

If the query is loaded from a file rather than specified in the command attribute, the file is loaded and cached by the QueryLoader class. The two attributes queryFile and queryName work in conjunction. The queryFile locates the query file. If the value of the attribute is a relative file specification, then the file is looked up in the RDBMS.path.query path. This path should be specified as a System property as a series of semi-colon delimited directories. If this variable is not set, then the NAS-specific GX.path.query property is used instead. The file is not located relative to the jsp itself. The query file should look something like:

query name1 [using (ODBC, cdx, netscape)] is
select *
from foo, bar
where :whereClause /* :whereClause is an example of a bindOnLoad, named parameter */

query name2 is
select * from foo, bar where foo.x = bar.y and foo.name = :name /* :name is an example of a named parameter */

A blank line (without spaces, tabs, etc!) separates queries which are named using the query ... is construct.


Param tag
The Param tag sets a parameter on a RowSet. The name of the parameter can either be an index or the actual name of the parameter as saved in the Dictionary. Note that bindOnLoad parameters MUST exist in the body of the useQuery tag before any non-bindOnLoad parameters. The value of the parameter is either the value stored in the value attribute, or the contents of the param tag's body. Because JSP1.1 tags don't generally nest (<%= ... %> being the notable exception), the only way to bind a parameter to a value from another query would be to place a field tag within the body of a parameter tag and have the parameter tag use its body as the value, which is why you can place the value in the boy of the tag.

Param tags may exist within the useQuery tag, in which case they set the parameters directly against their parent query, or elsewhere, probably before a loop tag re-executes the RowSet, in which case the parameter is set on the RowSet that the useQuery tag exported.


Loop tag
The loop tag loops through the contents of a ResultSet. The query attribute is used to locate the ResultSet or an enclosing useQuery tag. The start attribute is used to indicate the starting position of the loop. Start may either refer to a parameter, or to an attribute, which is looked up using PageContext.findAttribute() or a constant Integer value. That value then indicates which record number to start on, or "last", which will cause the RowSet to be scrolled to the end, and then back max rows. The max attribute is used to indicate the maximum number of records to display.

If execute is specified, then the RowSet is executed before looping begins.


Field tag
The field tag displays a particular column in the ResultSet. The query attribute locates the enclosing useQuery tag or a previous useQuery tag's exported ResultSet. The name attribute identifies the column name to display. The format attribute allows one to format Strings, numbers, or dates into the appropriate type. The Attribute urlEncode can be used to encode the strings. If the column is null, the body of the field tag is output.


Close tag
The close tag releases resources back to the system. The resource attribute locates the exported query resource (ResultSet) and calls close() on it.


Execute tag
The execute tag executes the identified query.


goRecord tag
The goRecord tag optionally executes the specified query and moves the resultset to the record indicated by the start attribute. Start may either refer to a parameter, or to an attribute or a constant, if the start attribute is last, then the result-set is moved to the last record.


Example
The following tags produce the displayed output.

<HTML>
<BODY>
<%@ taglib prefix="rdbm" uri="rdbmstags6_0.tld" %>
<h2>Now let us see</h2>
<rdbm:useQuery id="a" queryFile="dbms/queries.gxq"
   dataSourceName="jdbc/cdx">
</rdbm:useQuery>
<rdbm:useQuery id="b" queryFile="dbms/queries.gxq"
    dataSourceName="jdbc/cdx">
</rdbm:useQuery>

<table border=1 cellPadding=3>
   <tr><th>name</th><th>phone</th><th>Titles Owned</th></tr>
   <rdbm:loop id="loop1" query="a" max="5" execute="true">
      <tr>
        <td><rdbm:field query="a" name="name"/></td>
        <td><rdbm:field query="a" name="phone"/></td>
        <td>
           <rdbm:param query="b" id="owner" type="Int">
           <rdbm:field query="a" name="id"/>
            </rdbm:param>
            <table border=1 cellPadding=3 width="100%">
              <tr><th>title</th><th>price</th><th>artist</th></tr>
              <rdbm:loop id="loop2" query="b" max="5"execute="true">
                <tr>
                  <td><rdbm:field query="b" name="title"/></td>
                <td><rdbm:field query="b" format="$#,###.00"
                      name="price"/>
                </td>
                  <td><rdbm:field query="b" name="artist"/></td>
                </tr>
              </rdbm:loop>
            </table>
        </td>
     </tr>
   </rdbm:loop>
   </table>
   </td>
   </tr>
</rdbm:loop>
</table>
<rdbm:close resource="a"/>
<rdbm:close resource="b"/>
</BODY>
</HTML>



Now let us see




LDAP Tag Library

One unfortunate aspect currently is that LDAP connections are likely to be request-specific -- that is, the current user may be the only user that is authenticated to read the LDAP attributes of that user's data. Because of this, an additional LDAPAuthenticate/Authorize type of tag is required so that the mapping between "current user" and "connection to use to perform LDAP searches" can be coded. When the LDAP server is remote and a general authorize-capable login is not available, the LDAPAuthenticate tag should be used instead.


List of LDAP Tags:

  1. <ldap:[authenticate|connection] query="name of ldap exported query" url="ldap://..." password="..."> </ldap:[authenticate|connection]>

  2. <ldap:authorize query="name of ldap exported query" dn="distinguished name for the user to authorize against"> </ldap:authorize>

  3. <ldap:param name="parameter name in authenticate userDN or query url" query="name of ldap exported query" value="...">default value</ldap:param>

  4. <ldap:password query="name of ldap exported query" value="...">default value</ldap:password>

  5. <ldap:useQuery id="exported LDAPTagSearch" scope="[page|request|session|application]" url="ldap://... queryFile="filename for ldap query" queryName="name of the query in the ldap query file" connection="classname of an LDAPPoolManager" authorize="distinguished name for the user to authorize against">...</ldap:useQuery>

  6. <ldap:loop[Entry] id="name of attribute to export loop'd value" scope="[page|request|session|application]" query="name of ldap exported query" start="request variable name" max="number" pre="number of records before jump" jump="value of sort to jump to" useVL="true/false"> </ldap:loop[Entry]>

  7. <ldap:loopValue id="name of attribute to export loop'd value" scope="[page|request|session|application]" query="name of ldap exported query" entry="name of ldap exported entry from loopEntry" attribute="name of attribute to loop through" start="..." max="..."> </ldap:loopValue>

  8. <ldap:field query="name of query to use" entry="name of ldap exported entry from loopEntry" url="ldap://..." attribute="name of attribute to display"> </ldap:field>

  9. <ldap:sort query="name of ldap exported query" order="..."/>

  10. <ldap:close resource="name of ldap exported query"/>


Authenticate tag (also called 'connection')
The authenticate tag works in the context of an LDAPTagSearch. The LDAPTagSearch is either retrieved from the PageContext using findAttribute and the name of the query attribute, or by finding a parent useQuery tag and gettings its LDAPTagSearch. The url and password attributes are used to authenticate the LDAPConnection which the LDAPTagSearch holds onto. If the url attribute has parameters (that is, if the attribute has :foo values in it after the standard ldap://server:portNumber/ section of the ldap URL), then the body of the authenticate tag needs to contain Param tags for each of the parameters. If the password attribute is unspecified, then the body of the authenticate tag should contain a Password tag as well. At the end of the tag, the tag attempts to authenticate the LDAPTagSearch.


Authorize tag
The authorize tag works in the context of an LDAPTagSearch. The LDAPTagSearch is either retrieved from the PageContext using findAttribute and the name of the query attribute, or by finding a parent useQuery tag and gettings its LDAPTagSearch. The dn attribute is used to authorize the LDAPConnection which the LDAPTagSearch holds onto. If the dn attribute has parameters (that is, if the attribute has :foo values in it), then the body of the authorize tag needs to contain Param tags for each of the parameters. At the end of the tag, the tag attempts to authorize the LDAPTagSearch.


Param tag
The param tag sets parameters in LDAP URLs. LDAP Urls are specified in the url attribute of the authenticate tag, the dn attribute of the authorize tag and the url attribute of the field and useQuery tags.

At anyrate, params in the url are any java-legal-identifer with a prepended ':', much as the query parameters in a gxq file. For example, user in ldap://nsdirectory.mcom.com:389/uid=:user,ou=People,dc=netscape,dc=com. All parameters must be resolved by the end of the field, authenticate, authorize, or useQuery tags. Note 389 is not a tag, first because it's before the DN section of the LDAP Url, and second, because it isn't a java-level-identifier.

The body of the Param tag becomes the value of the parameter as named by the name attribute, assuming no value is specified in the Param tag itself.


Password tag
The password tag sets the password for the authenticate tag. Like the param tag, the body of the password tag becomes the value of the password, assuming that no value is specified as an attribute of the password tag. The password tag is legal only inside the authenticate tag.


useQuery tag
The useQuery tag describes the URL used to search the LDAP repository. At the end of its body, an LDAPTagSearch is placed into the context at the level indicated by scope using the name indicated by id. The url property contains the url of a query that, typically, a loop tag will loop through, or a field tag will display. This is because the loop tag cannot specify parameter mappings except in the body -- which is rather too late for loop to determine if there are even any results! The field tag can already specify an url, and thus doesn't need to reference a query, though it can.

The url can also be loaded from a query file. The two attributes queryFile and queryName work in conjunction. The queryFile locates the query file. If the value of the attribute is a relative file specification, then the file is looked up in the LDAP.path.query path. This path should be specified as a System property as a series of semi-colon delimited directories. If this variable is not set, then the NAS-specific GX.path.query property is used instead. The file is not located relative to the jsp itself. The query file should look something like:

query name1 is
ldap://directory:389/dc=com?blah

query name2 is
ldap://directory:389/dc=org?blah

A blank line (without spaces, tabs, etc!) separates queries which are named using the query ... is construct.


Loop tag (also called the 'loopEnrty' tag)
The loopEntry tag loops through a series of LDAPEntries resulting from a search that returns multiple entries. The query attribute points to an exported LDAPTagSearch (see above Query tag). The start and end tags work as specifed in the Query's Loop tag. If the useVL attribute is true, then an {id}_contentCount value is exported which corresponds to the contentCount of the VirtualListResponse. On each pass through the loop, the currenty LDAPEntry is exported at the scope specified using the id specified. The pre and jump attributes correspond to the beforeCount and jumpTo parameters in the VirtualListControl constructor. If the loop is using a VirtualListControl, that is, if the useVL attribute is set, then a VirtualListControl is used to position the window of returned entries. The actual public draft url for VirtualLists is here.


LoopValue tag
The loopValue tag loops through a multi-value attribute of an LDAPEntry or the first LDAPEntry in an LDAPSearchResults. The query attribute points to an exported LDAPTagSearch (see above Query tag). If this is not specified, then the entry attribute points to an exported entry as specified by a containing Loop tag. One or the other must be specified. It is an error to specify both. The attribute tag names the multi-value attribute. The start and end tags work as specifed in the Query's Loop tag. On each pass through the loop, the current LDAPAttribute-value is exported at the scope specified using the id specified.


Field Tag
The field tag prints out the value of a single-value attribute as specified in the query or url or entry attributes and the attribute attribute. If no value exists, the body of the field tag is passed through. The body of the field tag will only be evaluated if the url has parameters (and hence, there would be parameter bindings in the body that need to be evaluated and set), or if the mapped value is null. If the attribute name is $DN$, then the distinguished name for the entry is returned as the value of the field.


Sort tag
The sort tag works in conjunction with the useQuery tag, setting a sort order for the enclosing query. The query attribute identifies the enclosing query tag (or an exported LDAPTagSearch, if the sort tag occurs outside of the useQuery tag's body). The order attribute specifies the sort-order, as described by the keyDescription Parameter to the LDAPSortKey constructor. The useQuery tag supports multiple Sorts. Sorts are prioritized in the order specified.


Close tag
The close tag releases resources back to the system. The resource attribute locates the exported query resource (LDAPTagSearch) and calls close() on it. This calls abandon on any executing SearchResults, and releases the Connection back to the connection-pool (or disconnect()s the connection, if the connection doesn't come from a pool, which can happen when using the authenticate tag).


Example
The following example uses both the ldap tags and the switch tags, which are described below. It is assumed that the switch tags are mostly self-describing.

<HTML>

<BODY>

<%@ taglib prefix="cond" uri="condtags6_0.tld" %>

<%@ taglib prefix="ldap" uri="ldaptags6_0.tld" %>

<%@ taglib prefix="attr" uri="attribtags6_0.tld" %>

<cond:parameter name="user">
   <cond:exists>
      <ldap:query id="c" url="ldap://localhost:389/uid=:user,
        ou=People,dc=netscape,dc=com?cn,mailalternateaddress,mail">
        <cond:parameter name="password">
          <cond:exists>
             <ldap:authenticate query="c"
                   url="ldap://localhost:389/dc=                    com??sub?(uid=:user)">
                <ldap:param name="user">
                   <attr:getParameter name="user" />
                </ldap:param>
                <ldap:password>
                   <attr:getParameter name="password" />
                </ldap:password>
            </ldap:authenticate>
         </cond:exists>
      </cond:parameter>
     <ldap:param name="user"><attr:getParameter name="user" />
     </ldap:param>
    </ldap:query>
    <h2>Hello
    <ldap:field query="c" attribute="cn">

No Contact Name for <attr:getParameter name="user" /> in LDAP!

   </ldap:field></h2>
   <p>

Your main email is:
   <blockquote>
   <ldap:field query="c" attribute="mail"/>
   </blockquote>

Your alternate email addresses are as follows:

<ul>
<ldap:loopValue id="foo" scope="request" query="c" attribute="mailalternateaddress">
<li><attr:get name="foo" scope="request"/>
</ldap:loopValue>
</ul>
<cond:ldap name="c">
<cond:authenticated>
<p>

Your employee number is:
<ldap:field attribute="employeenumber" query="c">
They removed the employee numbers from ldap -- doesn't that suck?!

</ldap:field>
</cond:authenticated>
<cond:else>
<cond:parameter name="password">
<cond:exists>Your specified password is incorrect. Please retry!</cond:exists>
<cond:else>To see your employee id, please specify a 'password' parameter in the url along with your user name!<p></cond:else>

</cond:parameter>
</cond:else>
</cond:ldap>
<p>
<ldap:close resource="c"/>
</cond:exists>
<cond:else>

To see your employee information, please specify a 'user' parameter in the url!

<p>
</cond:else>
</cond:parameter>
</body></html>
Would produce one of the following (at least, it would if they hadn't removed employee number from nsdirectory recently!):




Conditional Tag Library

The conditional family of tags supports switch/case kinds of tags, allowing us to special case when a RowSet is at the end, or when a user should be given management-only types of information, or when a user has requested high-bandwidth content, etc. The root tags are as follows:

  1. <cond:switch type="[value|role|rowset|ldap|attribute|parameter]" value="constant value, role name, rowset name, etc."> ... </cond:switch>

  2. <cond:case operation="[=|<|>|<=|>=|!=|<>|><|=>|=<|~=|equals|equalsIgnoreCase|else|exists|notEmpty|executeNotEmpty|isLast|connected|authenticated|{method-name}]"
    value="..."></cond:case>

  3. <cond:value value="blah">default value</cond:value>
    The value tag can exist in either the switch or case tags

  4. <cond:dynamicValue value="blah"> ... <cond:value/> ... <cond:*case*/> ... </cond:dynamicValue>

However, for ease of use and better readability, the following equivalents exist:

  1. <cond:role> ... </cond:role>

  2. <cond:rowset name="rowset name"> ... </cond:rowset>

  3. <cond:ldap name="ldap connection name"> ... </cond:ldap>

  4. <cond:attribute name="attribute name"> ... </cond:attribute>

  5. <cond:parameter name="parameter name | $REMOTE_USER$"> ... </cond:parameter>

  6. <cond:else> ... </cond:else>

  7. <cond:equals value="..."> ... </cond:equals>

  8. <cond:equalsIgnoreCase value="..."> ... </cond:equalsIgnoreCase>

  9. <cond:exists> ... </cond:exists>

  10. <cond:notEmpty> ... </cond:notEmpty>

  11. <cond:executeNotEmpty> ... </cond:executeNotEmpty>

  12. <cond:isLast> ... </cond:isLast>

  13. <cond:Connected> ... </cond:connected>

  14. <cond:authenticated> ... </cond:authenticated>

Some of these may be more expressive than we really require. For example:

<cond:parameter name="foo"> ... </cond:parameter>

is really the same as:

<cond:switch><cond:value><%= request.getParameter("foo") %></cond:value> ... </cond:switch>

Additionally, one might assume that this:

<cond:rowset value="rowset name"><cond:exists>...</cond:exists></cond:rowset>

would be the same as:

<cond:rowset value="rowset name"><cond:case operation="=">...</cond:case></cond:rowset>

It is currently unclear whether the increased expressiveness is worth the tradeoff in possible user-confusion.


Switch tag

The switch tag defaults to be a straight value comparison, much as a "real" switch tag is. However, it is more likely to be used in one of its other incarnations. In particular, the rowset type of switch replaces some of the callbacks that DBRowSet contained.

The switch tag keeps track of whether a particular case statement has fulfilled the switch statement. It exports nothing, except for its body to the content. page.


Case tag

The case tag contains an operation and (possibly) a second operand, which is used to determine if the case statement fulfills the Switch tag. Note that if a case and switch combination is used in which a value is required, and no value is specified, a value is obtained from an enclosing cond:dynamicValue tag. This allows the case tag to implement only the Tag interface, making the JSP build more efficient. The case tag's body will not be evaluated unless the case statement fulfills an as-yet unfulfilled switch statement.

If no operation is specified, the operation is assumed to be "else" -- that is, fulfill the switch regardless. We may want to change that, although whether we default to "=" or equals poses a very interesting question. If no operation is specified and the switch is of type role, the operation is assumed to be equals.

Note that certain case operations make sense in only certain types of switches. The isLast and notEmpty tags are useful for both ldap (query or entry) and rowset type of switches. The executeNotEmpty operation only make sense for rowset types of switches. The connected and authenticated operations only make sense for ldap types of switches. Similarly, the "=, <, >" etc. types of operations only make sense when comparing numerical values. The value of the switch and the value of the case are converted to Doubles (if necessary), and their values compared. The equals and equalsIgnoreCase operations make sense only against Strings, though equals is called against the switch's value's equals method -- which might be implemented by an Object to compares itself against a String (the value of the case, always!). notEmpty also makes sense for Strings as a check that a parameter has a specified, non-zero length setting.


Value tag

The value tag's body is evaluated and passed up the first parent of the value tag that implements IValueContainingTag which both switch and dynamicValue do (naturally). You can also specify the value in a value attribute of the value tag. But then, if you could do that, you'd have put the value in the switch or case directly, wouldn't you?


dynamicValue tag

The dynamicValue tag's body should have, at least, two elements in it. One is a value tag, which builds the dynamic value of interest. The second is one of the other case tags whose value attribute is extracted from the enclosing dynamicValue instance. The dynamicValue tag does have a value tag, but only an assembly programmer would truly love it:

<cond:attribute name="foo">
   <cond:dynamicValue value="10">
             <cond:case operation="<">less than ten</cond:case>
             <cond:case operation="=">equal to ten</cond:case>
             <cond:case operation=">">greater than ten</cond:case>
    </cond:dynamicValue>
</cond:attribute>

Alas, there is no machine-equivalent to comparison bits in the status register, so the operation is still performed three times. It is unlikely, though possible, that this tag will be used in this fashion.


Example
The following is an example of how switch might be used. The three links at the end will produce the three different types of output:

<%@ taglib prefix="cond" uri="condtags6_0.tld" %>

<cond:parameter name="showHeader">
   <cond:equalsIgnoreCase value="true">
      <h2>Now let us see</h2>
   </cond:equalsIgnoreCase>
   <cond:dynamicValue>
      <cond:value value="false"/>
      <cond:equalsIgnoreCase>
          I'm not showing a header. Nope, not me!
      </cond:equalsIgnoreCase>
   </cond:dynamicValue>
   <cond:else>
      showHeader not specified or illegal value
   </cond:else>
</cond:parameter>
The possible outputs would be:




Attribute Tag Library


List of tags:

  1. <attr:getAttribute name="attributeName" scope="[|page|request|session|application]" format="...">default value</attr:getAttribute>

  2. <attr:setAttribute name="attributeName" value="..." scope="[page|request|session|application]">value</attr:setAttribute>

  3. <attr:getParameter name="parameterName" format="urlEncode">default value</attr:getParameter>

  4. <attr:getRemoteUser>default value</nas:getRemoteUser> <!-- prints out the Servlet's RemoteUser -->


getAttribute tag
Prints out the value of a named attribute whose value is retrieved from the specified scope. If no scope is specified, findAttribute() is used to find the attribute. If no value is found, the body of the tag is printed instead. The format is used ala the query:field tag.


setAttribute tag
Sets the value of a named attribute into the specified scope. If no scope is specified, page is assumed. The value is either the value specified in the value attribute, or if none is specifed, the body of the tag is used.


getParameter tag
Prints the value of a named parameter. If no parameter value exists, the body of the tag is printed instead. The format attribute is used ala the query:field tag.


Example
See examples on Conditional and LDAP taglibs


Load-balancing for JSPs

A significant addition to JSPs in iAS 6.0, compared to NAS 4.0, is the support for load-balancing JSPs individually. This is done by assigning a GUID to a JSP, similar to how GUIDs are assigned to servlets, i.e. in the XML descriptor. (See section on Registered JSPs). By assigning a GUID to a JSP, it becomes possible to load-balance JSPs just as servlets would, through the administrative tool.

The conditional family of tags supports switch/case kinds of tags, allowing us to special case when a RowSet is at the end, or when a user should be given management-only types of information, or when a user has requested high-bandwidth content, etc.


JSP Page Caching

iAS 6.0 provides a new feature called JSP Caching, which aids in development of compositional JSPs. This provides functionality to cache JSPs within the java engine, thereby making it possible to have a master JSP which includes multiple JSPs (a la a portal page), each of which can be cached using different cache criteria. Think of a portal page which contains a window to view stock quotes, another to view weather information, and so on. The stock quote window can be cached for 10 minutes, and the weather report window for 30 minutes, and so on.

Note that caching of JSPs is in addition to result caching, so its possible that a JSP can be composed of several included JSPs , each of which has a separate cache criterion, and the composed JSP itself can be cached in the KXS using the result-caching that becomes available as JSPs now have GUIDs (see section on Registered JSPs).

Caching of JSPs uses the custom tag library support provided by JSP 1.1. A typical cache-able JSP page looks as follows:

<%@ taglib prefix="ias" uri="CacheLib.tld"%>
<ias:cache>
<ias:criteria timeout="30">
<ias:check class="com.netscape.server.servlet.test.Checker"/>
<ias:param name="y" value="*" scope="request"/>
</ias:criteria>
</ias:cache>
<%! int i=0; %>
<html>
<body>
<h2>Hello there</h2>
I should be cached.
No? <b><%= i++ %></b>
</body>
</html>

The <ias:cache> and </ias:cache> delimit the cache constraints. The <ias:criteria > tag specifies the timeout value, and encloses different cache criteria. Cache criteria can be expressed using any or both of the tags, <ias:check> and <ias:param>. The syntax for these tags is as follows:

  • <ias:criteria timeout="val" > : This specifies the timeout for the cached element, in seconds. The cache criteria are specified within this and the closing </ias:criteria>

  • <ias:check class="classname" /> This is one of the mechanisms of specifying cache criteria. The classname refers to a class that has a method called "check", which has the following signature:

public Boolean check(HttpServletRequest req)

This returns a boolean indicating whether the element is to be cached or not.

  • <ias:param name="paramName" value="paramValue" scope="request" /> : This is the other mechanism to specify cache criteria.

paramName is the name of an attribute, passed in either in the request object (using setAttribute), or in the URI. This is the parameter used as a cache criterion.

paramValue is the value of the parameter, which determines whether caching should be performed or not. This can be of the following kinds:

constraint

meaning

x = ""

x must be present either as a parameter or as an attribute.

x = "v1|...|vk", where vi might be "*"

x is mapped to one of the strings (parameter/attribute). If x=*, then the constraint is true of the current request if the request parameter for x has the same value as was used to store the cached buffer.

x = "1-u", where 1 and u are integers.

x is mapped to a value in the range [1,u]

The scope identifies the source of the attributes that are checked. These can be page, request (default), session, or application.


Example:
The following is an example of a cached JSP page:

<%@ taglib prefix="ias" uri="CacheLib.tld"%>
<ias:cache>
<ias:criteria timeout="30">
<ias:check class="com.netscape.server.servlet.test.Checker"/>
<ias:param name="y" value="*" scope="request"/>
</ias:criteria>
</ias:cache>
<%! int i=0; %>
<html>
<body>
<h2>Hello there</h2>

I should be cached.

No? <b><%= i++ %></b>
</body>
</html>

where Checker is defined as:

package com.netscape.server.servlet.test;

import com.netscape.server.*;

import javax.servlet.*;
import javax.servlet.http.*;

public class Checker {
   String chk = "42";
   public Checker()
   {

   }

public Boolean check(ServletRequest _req)

   {

       HttpServletRequest req = (HttpServletRequest)_req;
       String par = req.getParameter("x");
       return new Boolean(par == null ? false : par.equals(chk));
    }

}

Given the above, a cached element is valid for a request with parameter 'x=42', and 'y' equal to the value used to store the element. Note that its possible to have multiple sets of <ias:param> and <ias:check> inside an <ias:criteria> block. Also, its possible to have multiple <ias:criteria> blocks inside a JSP.


Previous     Contents     Index     DocHome     Next     
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.

Last Updated June 25, 2000