Skip Headers

Oracle9iAS Containers for J2EE Support for JavaServer Pages Developer's Guide
Release 2 (9.0.3)

Part Number A97679-01
Go To Core Documentation
Core
Go To Platform Documentation
Platform
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

8
JSP Tag Libraries

This chapter discusses custom tag libraries, covering the basic framework that vendors can use to provide their own libraries. There is also discussion of Oracle extensions, and a comparison of standard runtime tags versus vendor-specific compile-time tags. The chapter is organized as follows:

The chapter offers a detailed overview of standard tag library functionality. For complete information, refer to the Sun Microsystems JavaServer Pages Specification, Version 1.2 (or higher). For information about the tag libraries provided with OC4J, see the Oracle9iAS Containers for J2EE JSP Tag Libraries and Utilities Reference.

Custom tag syntax largely follows XML conventions. For general information about XML, you can find the specification at the following Web site:

http://www.w3.org/XML/

Overview: Tag Library Framework

JavaServer Pages technology allows vendors to create custom JSP tag libraries. A tag library defines a collection of custom actions. The tags can be used directly by developers in manually coding a JSP page, or automatically by Java development tools.

This section provides an overview of the JSP tag library framework, as well as a summary of new tag library features in the JSP 1.2 specification.

For information beyond what is provided here regarding tag libraries and the standard JavaServer Pages tag library framework, refer to the following resources:

Overview of a Custom Tag Library Implementation

A custom tag library is made accessible to a JSP page through a taglib directive of the following general form:

<%@ taglib uri="URI" prefix="prefix" %>

Note the following points about implementation and usage of a tag library.

The remainder of this chapter provides details about these topics.


Note:

The OC4J JSP container supports tag library features for the JServ environment as well, with the exception of tag library event listeners.


Overview of Tag Library Changes Between the JSP 1.1 and 1.2 Specifications

The JSP 1.2 specification adds features for improved tag library support in the following areas:

Summary of TLD File Changes Between the JSP 1.1 and 1.2 Specifications

The following list is a summary of features in TLD syntax and functionality that were introduced in the JSP 1.2 specification. These changes were not available until Oracle9iAS release 2 (9.0.3). "Tag Library Descriptor Files" includes information about these features.

Summary of Tag Handler Changes Between the JSP 1.1 and 1.2 Specifications

The JSP 1.1 specification has two interfaces that can be implemented by tag handlers--Tag, for tags without bodies, and BodyTag, for tags with bodies. The JSP 1.2 specification adds the IterationTag interface, for tags that call for iteration through a tag body, but do not require access to the tag body content through a body content object. IterationTag extends Tag and is extended by BodyTag.

Also in JSP 1.2, the int constant EVAL_BODY_TAG, which indicates that there is a tag body to be processed, is deprecated and replaced by EVAL_BODY_AGAIN and EVAL_BODY_BUFFERED. EVAL_BODY_AGAIN is used with tags that iterate through a tag body, to specify that iteration should continue. EVAL_BODY_BUFFERED is used with tags that require access to body content, to direct that a BodyContent object be created.

The JSP 1.2 specification also adds the TryCatchFinally interface, which any tag handler can implement for improved data integrity and resource management when exceptions occur.

The JSP 1.2 changes were not available until Oracle9iAS release 2 (9.0.3). "Tag Handlers" includes information about these new features.

Tag Library Descriptor Files

A tag library descriptor (TLD) file is an XML-style document that contains information about a tag library and individual tags of the library. The name of a TLD file has the .tld extension.

A JSP container uses the TLD file in determining what action to take when it encounters a tag from the library. The taglib directive in a JSP page informs the JSP container where to find the TLD file. (See "Overview: Specifying a Tag Library with the taglib Directive".)

This section provides an overview and general information about TLD file syntax and usage, referring ahead to other sections as appropriate for more information about related topics. This section covers the following topics:

For complete information, refer to the Sun Microsystems JavaServer Pages Specification, Version 1.2.

See "Example: Using the IterationTag Interface and a Tag-Extra-Info Class" for a sample TLD file.


Note:

By default, the OC4J JSP container performs XML validation of TLD files. To disable this, set the no_tld_xml_validate JSP configuration parameter to true. (See "JSP Configuration Parameters" for more information.) For pre-translation, use the ojspc -noTldXmlValidate option. (See "Option Descriptions for ojspc".)


Overview of TLD File Validation and Features

The OC4J JSP container uses the DOCTYPE declaration of a TLD file to determine which TLD DTD version to validate against, unless TLD validation has been disabled. By default, as of Oracle9iAS release 2 (9.0.3), the JSP container assumes the JSP 1.1 TLD DTD. To use the JSP 1.2 TLD DTD, list the following as the system ID (DTD location):

http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd

Here is an example:

<!DOCTYPE taglib
        PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

When TLD validation is enabled, the XML parser must be able to reference the appropriate DTD, which it can do with the above DOCTYPE declaration for JSP 1.2. (TLD validation is enabled if the JSP no_tld_xml_validate parameter has its default false setting, or, for pre-translation, if the ojspc -noTldXmlValidation flag is not used.)


Note:

According to the JSP 1.2 specification, use an absolute URL to specify the system ID. If a TLD file does not use a public external DOCTYPE declaration with an absolute URL, the OC4J JSP container will assume that the JSP 1.1 TLD DTD is intended.


A TLD file provides definitions for the tag library as a whole as well as for each individual tag. For each tag, it defines the tag name, its attributes (if any), its scripting variables (if any), and the name of the class that handles tag semantics. See "Use of the tag Element".

For the library as a whole, TLD definitions can include a tag-library-validator class and event listeners. See "Other Key Elements and Their Subelements: validator and listener".

A TLD file also provides additional definitions for the library as a whole, as follows.


Note:

The <tag>, <validator>, and <listener> elements and the elements listed below are top-level subelements under the <taglib> root element of the TLD file.


Use of the tag Element

Each tag of a tag library is specified in a <tag> element, under the root <taglib> element of the TLD file. There must be at least one <tag> element in a TLD file. This section describes its usage and subelements.

Subelements of the tag Element

The subelements of a <tag> element define a tag, as follows:


Notes:

As of Oracle9iAS release 2 (9.0.3), the OC4J JSP container ignores the <type> element. It is for informational use only, for anyone examining the TLD file. Additionally, note the following:

  • For literal attribute values, where <rtexprvalue> specifies false, the <type> value (if any) should always be java.lang.String.

  • When <rtexprvalue> specifies true, then the type of the tag handler property corresponding to this tag attribute determines what you should specify for the <type> value (if any).



Notes:

  • A custom tag name must qualify as an NMTOKEN according to the XML specification. For example, it cannot start with a numeric character.

  • Attribute names must follow naming conventions for XML attributes, and their setter methods in tag handler classes must follow the JavaBeans specification.


Sample tag Element and Use of Its body-content Subelement

Here is a sample TLD file entry for a tag myaction:

<tag>
  <name>myaction</name>
  <tag-class>examples.MyactionTag</tag-class>
  <tei-class>examples.MyactionTagExtraInfo</tei-class>
  <body-content>JSP</body-content>
  <attribute>
    <name>attr1</name>
    <required>true</required>
  </attribute>
  <attribute>
    <name>attr2</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
  </attribute>
</tag>

According to this entry, the tag handler class is MyactionTag and the tag-extra-info class is MyactionTagExtraInfo. The attribute attr1 is required; the attribute attr2 is optional and can take a runtime expression as its value.

The <body-content> element indicates how the tag body (if any) should be processed. There are three choices:

Consider the following example:

<foo:bar>
   <%=blah%>
</foo:bar>

If the bar tag has a <body-content> value of JSP, then the body is processed by the JSP translator, and the expression is evaluated. With a <body-content> value of tagdependent, the JSP translator does not process the body. In this case, the characters "<", "%", "=", and ">" have no special meaning--they are treated as literal characters, along with the rest of the body, and are part of the JSP out object passed straight through to the tag handler .

There are additional considerations for JSP XML documents. In this case, because the document is parsed by the XML parser, it is not appropriate to implement support for a value of tagdependent. This value is essentially meaningless in a JSP XML document.

One reason for this is that in XML, there is already a convenient mechanism for escaping body content--using the CDATA token. But beyond that, there are many scenarios where it would actually be undesirable to pass content straight through as a tagdependent implementation would do. Consider an example using a tag for SQL queries, comparing the following traditional syntax:

<foosql:query ... >
   select ... where salary > 1000
</foosql:query>

to the following JSP XML syntax:

<foosql:query ... >
   <![CDATA[select ... where salary > 1000]]>
</foosql:query>

In the traditional syntax, a <body-content> value of tagdependent would result in the query statement being passed straight through to the JSP out object, presumably the desired result.

In the XML syntax, the CDATA token (or, alternatively, a "&gt;" escape character) is required, because otherwise the character ">" has special meaning to the XML parser.

In this example, if an implementation of tagdependent were used, the entire body would be passed through to the out object:

<![CDATA[select ... where salary > 1000]]>

But presumably, the information that should really be passed through is only the SQL query itself:

select ... where salary > 1000

This is what would happen by processing the body through a <body-content> value of JSP, and using the CDATA token for the XML parser. This is more appropriate behavior than what would happen with a tagdependent implementation.

See "Details of JSP XML Documents" for more information about JSP XML syntax.

Other Key Elements and Their Subelements: validator and listener

The TLD <validator> and <listener> elements are new in the JSP 1.2 specification.

A <validator> element and its subelements specify information about a tag-library-validator (TLV) class that can validate JSP pages that use this tag library. The <validator> element has three subelements: <validator-class>, <description>, and <init-param>. The <init-param> subelement has the same functionality as <init-param> subelements within <servlet> elements in the web.xml file. It has <param-name> and <param-value> subelements to specify each parameter. See "Validation and Tag-Library-Validator Classes" for more information.

A <listener> element and its <listener-class> subelement specify an event listener for use with the tag library, such as in creating and destroying resource pools used by the library. See "Tag Library Event Listeners" for more information.

Tag Library and TLD Setup and Access

This section discusses the packaging, placement, and access of tag libraries and their TLD files. It covers the following topics:

Overview: Specifying a Tag Library with the taglib Directive

This section summarizes the use of taglib directives, discussing original functionality under the JSP 1.1 specification and new functionality under the JSP 1.2 specification.

Import a custom library into a JSP page by using a taglib directive, of the following general form:

<%@ taglib uri="URI" prefix="prefix" %>

The prefix setting specifies a string of characters that stipulates when tags from this library are being used. For example, if mytag is in a library that has a specified prefix of oracust, use mytag as follows:

<oracust:mytag attr1="..." attr2="..." >
...
</oracust:mytag>


Note:

Prefixes must follow the naming conventions of the XML namespaces specification.


Under the JSP 1.1 specification, the uri setting can indicate a file location as in either of the following scenarios, either directly or through a "shortcut" URI:

See "Specifying a Tag Library by Physical Location" for more information.

Under the JSP 1.2 specification, the uri setting can still indicate the physical location of a TLD file or the location of a JAR file containing one tag library and its TLD file, but it can also be used as follows:

As under JSP 1.1, you can also use a shortcut URI.

See "Packaging and Accessing Multiple Tag Libraries in a JAR File" for more information. For information about shortcut URIs, see "Use of web.xml for Tag Libraries".

Specifying a Tag Library by Physical Location

As first defined in the JSP 1.1 specification, the taglib directive of a JSP page can fully specify the name and physical location, within a WAR file structure, of the TLD file that defines a particular tag library, as in the following example:

<%@ taglib uri="/WEB-INF/oracustomtags/tlds/mytld.tld" prefix="oracust" %>

Specify the location as application-relative, by starting with "/" as in this example. See "Requesting a JSP Page" for discussion of application-relative syntax.

Be aware that the TLD file should be in the WEB-INF directory or a subdirectory.

Alternatively, as also defined since JSP 1.1, the taglib directive can specify the name and application-relative physical location of a JAR file instead of a TLD file, where the JAR file contains a single tag library and the TLD file that defines it. In this scenario, the TLD file must be located and named as follows in the JAR file:

META-INF/taglib.tld

You must place the JAR file in the /WEB-INF/lib directory.

Here is an example of a taglib directive that specifies a tag library JAR file:

<%@ taglib uri="/WEB-INF/lib/mytaglib.jar" prefix="oracust" %>

Also see "Packaging and Accessing Multiple Tag Libraries in a JAR File", following, which describes a scenario that is newly supported by the JSP 1.2 specification.


Note:

In either scenario discussed in this section, the taglib directive can specify a "shortcut" URI that corresponds to the complete URI value according to settings in the web.xml file. See "Use of web.xml for Tag Libraries".


Packaging and Accessing Multiple Tag Libraries in a JAR File

The preceding section, "Specifying a Tag Library by Physical Location", discusses the JSP 1.1 scenarios of using a taglib directive to specify a TLD file by physical location, or to specify a JAR file that contains a single tag library and its TLD file.

In addition to these scenarios, the JSP 1.2 specification allows the packaging of multiple tag libraries, and the TLD files that define them, in a single JAR file. Inside the JAR file, these TLD files must be located under the /META-INF directory or a subdirectory.

While a single TLD file in a JAR file is packaged as /META-INF/taglib.tld (although this is no longer s strict requirement under JSP 1.2), a JAR file with multiple TLD files must use unique names or subdirectories. Here are a couple of possibilities, for example, for packaging three TLD files in a JAR file:

/META-INF/abctags.tld
/META-INF/deftags.tld
/META-INF/ghitags.tld

or:

/META-INF/abc/taglib.tld
/META-INF/def/taglib.tld
/META-INF/ghi/taglib.tld

In each TLD file, there is a <uri> element under the root <taglib> element. Use this feature as follows:

The value of the <uri> element can be arbitrary--it is simply used as a key and does not indicate a physical location. By convention, however, its value is of the form of a physical location, such as in the following example:

<uri>http://www.mycompany.com/j2ee/jsp/tld/myproduct/mytags.tld</uri>

A <uri> value must follow the XML namespace convention.

A JAR file with multiple TLD files must be placed in the /WEB-INF/lib directory or in the OC4J "well-known" URI location described in "Oracle Extension for Tag Library Sharing". During translation, the JSP container searches these two locations for JAR files, searches each JAR file for TLD files, and accesses each TLD file to find its <uri> element.


Notes:

  • A <uri> element and the corresponding taglib directive can specify a "shortcut" URI setting. This corresponds to settings in the web.xml file, as "Use of web.xml for Tag Libraries" explains.

  • A JSP 1.2-compliant JSP container, such as the OC4J JSP container, supports the multiple TLD file packaging mechanism for JSP 1.1 TLD files as well as JSP 1.2 TLD files.


Example: URI Settings for Multiple Tag Libraries in a JAR File

Consider a JAR file, myapptags.jar, that includes the following TLD files:

/META-INF/mytaglib1.tld
/META-INF/mytaglib2.tld

Assume that mytaglib1.tld specifies the following:

<taglib> 
   <tlib-version>1.0</tlib-version> 
   <jsp-version>1.2</jsp-version> 
   <short-name>shorty</short-name>
   <uri>http://www.foo.com/jsp/mytaglib1</uri>
   <description>example TLD</description>
   <tag>
      <name>mytag1</name>
      ...
   </tag>
   ...
</taglib>

To use mytag1 or any other tag defined in mytaglib1.tld, a JSP page could have the following taglib directive:

<%@ taglib uri="http://www.foo.com/jsp/mytaglib1" prefix="myprefix1" %>

URI values in this scenario (multiple tag libraries in a single JAR file) are used as keywords only. They can be arbitrary.

For a more complete example, see "Example: Multiple Tag Libraries and TLD Files in a JAR File".

Oracle Extension for Tag Library Sharing

As an extension of standard JSP "well-known URI" functionality described in the JSP 1.2 specification, the OC4J JSP container supports the use of a shared tag library directory where you can place tag library JAR files to be shared across multiple Web applications.

The directory location is according to the setting of the OC4J JSP well_known_taglib_loc configuration parameter, with the specified location being under [Oracle_Home] if [Oracle_Home] is defined, or under the current directory (from which the OC4J process was started) if [Oracle_Home] is not defined. The default value of well_known_taglib_loc is as follows:

j2ee/home/jsp/lib/taglib/

Also see "JSP Configuration Parameters" for a description of the well_known_taglib_loc parameter.

The shared directory must be added to the server-wide classpath by specifying it as a library path element. The default location is set in the application.xml file in the OC4J configuration files directory (j2ee/home/config by default in OC4J standalone); you can alter the setting there as desired. See the Oracle9iAS Containers for J2EE User's Guide for information about application.xml.

TLD files to be shared across a set of applications must be placed in a JAR file. There can be multiple JAR files in the well-known location. Each tag library will be uniquely identified through the <uri> element in its TLD file. Also see "Packaging and Accessing Multiple Tag Libraries in a JAR File".

Use of web.xml for Tag Libraries

Versions 2.2 and higher of the Sun Microsystems Java Servlet Specification describe a standard deployment descriptor for servlets--the web.xml file. JSP pages can use this file in specifying the location or URI identifier of a JSP TLD file.

For JSP tag libraries, the web.xml file can include <taglib> elements and two subelements:

For the scenario of an individual TLD file, or the scenario of a JAR file that contains a single tag library and its TLD file, the <taglib-location> subelement indicates the application-relative physical location (by starting with "/") of the TLD file or tag library JAR file. See "Specifying a Tag Library by Physical Location" for related information.

For the scenario of a JAR file that contains multiple tag libraries and their TLD files, a <taglib-location> subelement indicates the unique identifier of a tag library. In this case, the <taglib-location> value actually indicates a key, not a location, and corresponds to the <uri> value in the TLD file of the desired tag library. See "Packaging and Accessing Multiple Tag Libraries in a JAR File" for related information.

The <taglib-uri> subelement indicates a shortcut URI to use in taglib directives in your JSP pages, with this URI being mapped to the physical location or URI identifier specified in the accompanying <taglib-location> subelement.

Following is a sample web.xml entry for a TLD file:

<taglib>
   <taglib-uri>/oracustomtags</taglib-uri>
   <taglib-location>/WEB-INF/oracustomtags/tlds/mytld.tld</taglib-location>
</taglib>

This entry makes /oracustomtags equivalent to /WEB-INF/oracustomtags/tlds/mytld.tld in taglib directives in your JSP pages.

Given this example, the following directive in your JSP page results in the JSP container finding the /oracustomtags URI in web.xml and, therefore, finding the accompanying name and location of the TLD file (mytld.tld):

<%@ taglib uri="/oracustomtags" prefix="oracust" %>

This statement enables you to use any of the tags of this custom tag library in a JSP page.

See the Sun Microsystems Java Servlet Specification, Version 2.3, and the Sun Microsystems JavaServer Pages Specification, Version 1.2, for more information about the web.xml deployment descriptor.


Important:

Using the <taglib> element in web.xml is required in the case of a TLD file that is located in the JSP shared tag library directory and has <listener> elements. This is the only way that the TLD file can be found and accessed in order to activate its listeners. See "Oracle Extension for Tag Library Sharing" and "Tag Library Event Listeners".


Example: Multiple Tag Libraries and TLD Files in a JAR File

This example presents key aspects of tag library packaging for some of the Oracle JSP demo applications. This is a situation where multiple tag libraries are packaged in a single JAR file. The JAR file includes tag handler classes, tag-library-validator classes, and TLD files for multiple libraries. The following shows the contents and structure of the JAR file:

examples/BasicTagParent.class
examples/ExampleLoopTag.class
examples/BasicTagChild.class
examples/BasicTagTLV.class
examples/TagElemFilter.class
examples/XMLViewTagTLV.class
examples/TagFilter.class
examples/XMLViewTag.class
META-INF/xmlview.tld
META-INF/exampletag.tld
META-INF/basic.tld
META-INF/MANIFEST.MF

Key TLD File Entries for Multiple-Library Example

This section illustrates the <uri> elements of the TLD files.

The basic.tld file includes the following:

<taglib>

  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>basic</short-name>
  <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/basic.tld</uri>

  ...

</taglib>

The exampletag.tld file includes the following:

<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">

  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>example</short-name>
  <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/exampletag.tld</uri>

  ...

</taglib>

The xmlview.tld file includes the following:

<taglib>

  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>demo</short-name>
  <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/xmlview.tld</uri>

  ...

</taglib>

Key web.xml File Entries for Multiple-Library Example

This section shows the <taglib> elements of the web.xml deployment descriptor, which map the full URI values (as seen in the <uri> elements of the TLD files in the previous section) to shortcut URI values used in the JSP pages that access these libraries.

...

<taglib>
  <taglib-uri>/oraloop</taglib-uri> 
  <taglib-location>http://xmlns.oracle.com/j2ee/jsp/tld/demos/exampletag.tld
  </taglib-location> 
</taglib>
<taglib>
  <taglib-uri>/orabasic</taglib-uri> 
  <taglib-location>http://xmlns.oracle.com/j2ee/jsp/tld/demos/basic.tld
  </taglib-location> 
</taglib>
<taglib>
  <taglib-uri>/oraxmlview</taglib-uri> 
  <taglib-location>http://xmlns.oracle.com/j2ee/jsp/tld/demos/xmlview.tld
  </taglib-location> 
</taglib>

...

JSP Page taglib Directives for Multiple-Library Example

This section shows taglib directives from the JSP pages of the demos, which reference the shortcut URI values defined in the web.xml elements listed in the preceding section.

The page basic1.jsp includes the following directive:

<%@ taglib prefix="basic" uri="/orabasic" %>

The page exampletag.jsp includes the following directive:

<%@ taglib prefix="example" uri="/oraloop" %>

The page xmlview.jsp includes the following directive:

<%@ taglib prefix="demo" uri="/oraxmlview" %>

Tag Handlers

This section describes tag handlers, which define the semantics of actions that result from the use of custom tags. It includes the following topics:

Overview of Tag Handlers

A tag handler is an instance of a Java class that directly or indirectly implements the standard javax.servlet.jsp.tagext.Tag interface. Depending on whether there is a tag body and how that body is to be processed, the tag handler implements one of the following interfaces, in the javax.servlet.jsp.tagext package:

A tag handler class might implement one of these interfaces directly, or might extend a class (such as one of the support classes provided by Sun Microsystems) that implements one of them.

Each custom tag has its own handler class. By convention, the name of the tag handler class for a tag abc, for example, is AbcTag.

The TLD file of a tag library specifies the name of the tag handler class for each tag in the library. See "Tag Library Descriptor Files".

A tag handler instance is typically created by the JSP page implementation instance, by use of a zero-argument constructor, and is a server-side object used at request-time. The tag handler has properties that are set by the JSP container, including the page context object for the JSP page that uses the custom tag, and a parent tag handler object if the use of this tag is nested within an outer tag. A tag handler, as applicable, supports parameter-passing, evaluation of the tag body, and access to other objects in the JSP page, including other tag handlers.

"Example: Using the IterationTag Interface and a Tag-Extra-Info Class" includes code for a sample tag handler class.


Note:

The Sun Microsystems JavaServer Pages Specification, Version 1.2 does not mandate whether multiple uses of the same custom tag within a JSP page should use the same tag handler instance or different instances--this is left to the discretion of JSP vendors. See "OC4J JSP Tag Handler Features" for information about the Oracle implementation.


Attribute Handling, Conversions from String Values

A tag handler class has an underlying property for each attribute of the custom tag. These properties are somewhat like JavaBean properties, with at least a setter method.

Recall that there are two approaches in setting a tag attribute:

Custom Tag Processing, with or without Tag Bodies

Custom tags, as with standard JSP tags, may or may not have a body. In the case of a custom tag, even when there is a body, its content may not have to be accessed by the tag handler.

There are four scenarios:

  1. There is no body.

    In this case you need only a single tag, not a start-tag and end-tag. Following is a general example:

    <oracust:mytag attr1="...", attr2="..." />
    
    

    This is equivalent to the following, which is also permissible:

    <oracust:mytag attr1="...", attr2="..." ></oracust:abcdef>
    
    

    In this case, the tag handler should implement the Tag interface.

    The <body-content> setting for this tag in the TLD file should be empty.

  2. There is a body; access of the body content by the tag handler is not required; the body is executed no more than once.

    In this case, there is a start-tag and an end-tag with a body of statements in between, but the tag handler does not process the body--body statements are passed through for normal JSP processing only. Following is a general example of this scenario:

    <foo:if cond="<%= ... %>" >
    ...body executed if cond is true, but body content not accessed by tag 
    handler...
    </foo:if>
    
    

    In this case, the tag handler should implement the Tag interface.

    The <body-content> setting for this tag in the TLD file should be JSP (the default) or tagdependent, depending on whether the body content should be translated or treated as template data, respectively.

  3. There is a body; access of the body content by the tag handler is not required; the body is executed multiple times (iterated).

    This is the same as the second scenario, except there is iterative processing of the tag body.

    <foo:myiteratetag ... >
    ...body executed multiple times, according to attribute or other settings, 
    but body content not accessed by tag handler...
    </foo:myiteratetag>
    
    

    In this case, the tag handler should implement the IterationTag interface.

    The <body-content> setting for this tag in the TLD file should be JSP (the default) or tagdependent, depending on whether the body content should be translated or treated as template data, respectively.

  4. There is a body that must be processed by the tag handler.

    Again, there is a start-tag and an end-tag with a body of statements in between; however, the tag handler must access the body content.

    <oracust:mybodytag attr1="...", attr2="..." >
    ...body accessed and processed by tag handler...
    </oracust:mybodytag>
    
    

    In this case, the tag handler should implement the BodyTag interface.

    The <body-content> setting for this tag in the TLD file should be JSP (the default) or tagdependent, depending on whether the body content should be translated or treated as template data, respectively.


    Notes:

    • In the first scenario, where there is no body, the action is known as an empty action. In the second, third, and fourth scenarios, where there is a body, the action is known as a non-empty action.

    • In the first, second, and third scenarios, where no body content processing is required by the tag handler, the handler is known as a simple tag handler.

    • For additional information about the <body-content> element, see "Use of the tag Element".


Summary of Integer Constants for Body Processing

The tag handler interfaces that are described in the following sections specify methods that you must implement, as applicable, to return appropriate int constants, depending on the situation.

The possible return values from the doStartTag() method, which is defined in the Tag interface and inherited by the IterationTag and BodyTag interfaces, are as follows:

The possible return values from the doAfterBody() method, defined in the IterationTag interface and inherited by the BodyTag interface, are as follows:

The possible return values from the doEndTag() method, defined in the Tag interface and inherited by the IterationTag and BodyTag interfaces, are as follows:

Simple Tag Handlers without Iteration

For a custom tag that does not have a body, or has a body whose content does not require access and special processing by the tag handler, the tag handler is referred to as a simple tag handler. The tag handler class can implement the following standard interface:

However, if there is a tag body that is to be iterated, then the tag handler should implement the IterationTag interface instead--see "Simple Tag Handlers with Iteration".

The standard javax.servlet.jsp.tagext.TagSupport class implements the Tag interface, but also implements the IterationTag interface. Because of this, it is inefficient to use the TagSupport class for a tag that does not iterate through the tag body. This is especially important to consider when migrating code from a JSP 1.1 environment to a JSP 1.2 environment, in case you created tag handlers that extended TagSupport under JSP 1.1. For simple tag handlers not requiring body iteration, it is best to implement the Tag interface from scratch.

The Tag interface defines methods for the following key functions:

For complete information, see the Sun Microsystems Tag interface Javadoc at:

http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/jsp/tagext/Tag.html

In particular, the Tag interface specifies the following key methods:

The tag developer provides code for these methods in the tag handler class, as appropriate, to be executed as the start-tag and end-tag, respectively, are encountered. The JSP page implementation class generated by the JSP translator includes appropriate calls to these methods.

Implement action processing--whatever you want the action tag to accomplish--in the doStartTag() method. The doEndTag() method implements any appropriate post-processing. In the case of a tag without a body, essentially nothing happens between the execution of these two methods.

The Tag interface also specifies getter and setter methods for the pageContext and parent properties. The JSP page implementation instance invokes the setPageContext() and setParent() methods before invoking the doStartTag() and doEndTag() methods.

The doStartTag() method returns an int value. For a tag handler class implementing the Tag interface, this value is one of the following:

The doEndTag() method also returns an int value, one of the following:

Simple Tag Handlers with Iteration

For a custom tag that has a body that does not require access and special processing by the tag handler, but does require repeated reevaluation such as for iteration, the tag handler class can implement the following standard interface:

The IterationTag interface extends the Tag interface. A class that implements the IterationTag interface is still known as a simple tag handler.

The following standard support class implements the IterationTag interface, as well as the java.io.Serializable interface, and can be used as a base class:

In addition to implementing appropriate methods from the Tag and IterationTag interfaces, the TagSupport class includes a convenience method, findAncestorWithClass(), that calls the getParent() method defined in the Tag interface.


Note:

It is not advisable to extend the TagSupport class if your tag handler does not have to support body iteration. Because TagSupport implements the IterationTag interface, there is looping logic that would be unnecessary. In addition to being generally inefficient, this increases the likelihood of methods exceeding a Java 64K size limit.


The IterationTag interface inherits basic tag-handling functionality, including the doStartTag() and doEndTag() methods, from the Tag interface. See "Simple Tag Handlers without Iteration".

The IterationTag interface also defines the following additional key method:

This method is called after each evaluation of the tag body, to see if the body should be evaluated again. It returns one of the following int values:


Notes:

  • In the JSP 1.1 specification, the doAfterBody() method is defined in the BodyTag interface. Moving this method definition to the IterationTag interface in JSP 1.2 allows a simple iteration tag handler to avoid the overhead of maintaining a BodyContent object.

  • For a complete example of IterationTag usage, see "Example: Using the IterationTag Interface".


Tag Handlers That Access Body Content

For a custom tag with body content that the tag handler must be able to access, the tag handler class can implement the following standard interface:

The following standard support class implements the BodyTag interface, as well as the java.io.Serializable interface, and can be used as a base class:

This class implements appropriate methods from the Tag, IterationTag, and BodyTag interfaces.


Note:

Do not use the BodyTag interface (or BodyTagSupport class) if your tag handler does not actually require access to the body content. This would result in the needless overhead of creating and maintaining a BodyContent object. Depending on whether iteration through the body is required, use the Tag interface or the IterationTag interface (or TagSupport class) instead.


BodyTag Features

The BodyTag interface inherits basic tag-handling functionality from the Tag interface, including the doStartTag() and doEndTag() methods and their defined return values. It also inherits functionality from the IterationTag interface, including the doAfterBody() method and its defined return values. See "Simple Tag Handlers without Iteration" and "Simple Tag Handlers with Iteration".

Along with its inherited features, the BodyTag interface adds functionality to capture execution results from the tag body. Evaluation of a tag body is encapsulated in an instance of the javax.servlet.jsp.tagext.BodyContent class. The page implementation object creates this instance as appropriate. See "BodyContent Objects".

As with the Tag interface, the doStartTag() method specified in the BodyTag interface supports int return values of SKIP_BODY and EVAL_BODY_INCLUDE. For BodyTag, this method also supports an int return value of EVAL_BODY_BUFFERED. To summarize the meanings:

The BodyTag interface also adds definitions for the following methods:

If the doStartTag() method returns EVAL_BODY_BUFFERED, the JSP page implementation instance executes the following steps, in order:

  1. It creates a BodyContent instance.

  2. It calls the setBodyContent() method of the tag handler, to pass the BodyContent instance to the tag handler.

  3. It calls the doInitBody() method of the tag handler to perform initialization, if any, related to the BodyContent instance.

These steps occur before the tag body is evaluated. While the body is evaluated, the JSP out object will be bound to the BodyContent object.

After each evaluation of the body, as for tag handlers implementing the IterationTag interface, the page implementation instance calls the tag handler doAfterBody() method. This involves the following possible return values:

Once evaluation of the body is complete, for however many iterations are appropriate, the page implementation instance invokes the tag handler doEndTag() method.

BodyContent Objects

For tag handlers implementing the BodyTag interface, evaluation results from the tag body are made accessible to the tag handler through an instance of the javax.servlet.jsp.tagext.BodyContent class. This class extends the javax.servlet.jsp.JspWriter class.

A BodyContent instance is created through the pushBody() method of the JSP page context.

The BodyContent class, in addition to inheriting JspWriter features, adds methods to accomplish the following:

Typical uses for a BodyContent object include the following:

TryCatchFinally Interface

For data integrity and resource management when exceptions occur during tag processing, the JSP 1.2 specification adds the javax.servlet.jsp.tagext.TryCatchFinally interface. Implementing this interface in your tag handlers is particularly useful for tags that must handle errors, and for ensuring the proper release of resources.

The TryCatchFinally interface specifies the following methods:

Following is a typical TryCatchFinally invocation (from the Sun Microsystems JavaServer Pages Specification, Version 1.2):

 h = get a Tag();  // get a tag handler, perhaps from pool

 h.setPageContext(pc);  // initialize as desired
 h.setParent(null);
 h.setFoo("foo");
 
 // tag invocation protocol; see Tag.java
 try {
   h.doStartTag()...
   ....
   h.doEndTag()...
 } catch (Throwable t) {
   /* React to exceptional condition; invoked if exception occurs between
      doStartTag() and doEndTag(). */
   h.doCatch(t);
 } finally {
   // restore data invariants and release pre-invocation resources
   h.doFinally();
   /* doFinally() is almost always called, unless Throwable error occurs
      during setter method, or Java thread terminates. */
 }

Access to Outer Tag Handler Instances

Where nested custom tags are used, the tag handler instance of the nested tag has access to the tag handler instance of the outer tag, which may be useful in any processing and state management performed by the nested tag.

This functionality is supported through the static findAncestorWithClass() method of the javax.servlet.jsp.tagext.TagSupport class. Even though the outer tag handler instance is not named in the JSP page context, it is accessible because it is the closest enclosing instance of a given tag handler class.

Consider the following JSP code example:

<foo:bar1 attr="abc" >
   <foo:bar2 />
</foo:bar1>

Within the code of the bar2 tag handler class (class Bar2Tag, by convention), you can have a statement such as the following:

Tag bar1tag = TagSupport.findAncestorWithClass(this, Bar1Tag.class);

The findAncestorWithClass() method takes the following as input:

The findAncestorWithClass() method returns an instance of the appropriate tag handler class, in this case Bar1Tag, as a javax.servlet.jsp.tagext.Tag instance.

It is useful for a Bar2Tag instance to have access to the outer Bar1Tag instance in case the Bar2Tag needs the value of a bar1 tag attribute or needs to call a method on the Bar1Tag instance.

OC4J JSP Tag Handler Features

This section describes OC4J JSP extended features for tag handler pooling and code generation size reduction. It covers the following topics:

Disabling or Enabling Runtime or Compile-Time Tag Handler Reuse

In Oracle9iAS release 2, you can specify that tag handler instances be reused within each JSP page. This is sometimes referred to as tag handler instance pooling. As of release 2 (9.0.3), there are two models for this:

The JSP tags_reuse_default configuration parameter is relevant in either case. See "JSP Configuration Parameters" for further information about this parameter and how to set it.

Key Points Regarding Tag Handler Reuse

Be aware of the following points about tag handler reuse:

Enabling or Disabling the Runtime Model for Tag Handler Reuse

The runtime model can be enabled in either of two ways:

or:

You can also disable the runtime model in either of two ways:

or:

Enabling or Disabling the Compile-Time Model for Tag Handler Reuse

You can switch to the compile-time model for tag-handler reuse in one of two ways:

or:

A compiletime_with_release setting results in the tag handler release() method being called between usages of the same tag handler within the same page. This method releases state information, with details according to the tag handler implementation. For example, if the tag handler is coded so as to assume a release of state information between tag usages, then compiletime_with_release would be appropriate. If unsure about the implementation of the tag handler and about which compile-time setting to use, you might consider experimentation.

To disable the compile-time model, set tags_reuse_default to a value of none. This also disables the runtime model.


Notes:

  • Remember to retranslate your JSP pages when switching from the runtime model to the compile-time model for tag handler reuse.

  • The page context oracle.jsp.tags.reuse attribute is ignored with a tags_reuse_default setting of compiletime or compiletime_with_release.


Tag Handler Code Generation

The Oracle JSP implementation reduces the code generation size for custom tag usage. In addition, there is a JSP configuration flag, reduce_tag_code, that you can set to true for even further size reduction.

Be aware, however, that when this flag is enabled, the code generation pattern does not maximize tag handler reuse. Although you can still improve performance by setting tags_reuse_default to true as described in "Disabling or Enabling Runtime or Compile-Time Tag Handler Reuse", the effect is not maximized when reduce_tag_code is also true.

See "JSP Configuration Parameters" for further information about these parameters and how to set them.

Scripting Variables, Declarations, and Tag-Extra-Info Classes

A custom tag action can create one or more server-side objects, known as scripting variables, that are available for use by the tag itself or by other scripting elements, such as scriptlets and other tags. A scripting variable can be defined either through a <variable> element in the TLD file of the tag library, for elementary cases, or through a tag-extra-info class, for cases where the logic for the scripting variable is more complex.

This section covers the following topics:

Using Scripting Variables

Objects that are defined explicitly in a custom tag can be referenced in other actions through the JSP page context, using the object ID as a handle. Consider the following example:

<oracust:foo id="myobj" attr1="..." attr2="..." />

This statement results in the object myobj being available to scripting elements in the page, according to the declared scope of myobj. (See "Scripting Variable Scopes".) The id attribute is a translation-time attribute. You can specify a variable in one of two ways:

Generally, the more convenient <variable> mechanism will suffice.

The JSP container enters myobj into the page context, where it can later be obtained by other tags or scripting elements using syntax such as the following:

<oracust:bar ref="myobj" />

The myobj object is passed through the tag handler instances for the foo and bar tags. All that is required is knowledge of the name of the object (myobj).


Note:

In the example, id and ref are merely sample attribute names; there are no special predefined semantics for these attribute names. It is up to the tag handler to define attribute names and create and retrieve objects in the page context.


Scripting Variable Scopes

Specify the scope of a scripting variable in the <variable> element or tag-extra-info class of the tag that creates the variable. It can be one of the following int constants:

Variable Declaration Through TLD variable Elements

In the JSP 1.1 specification, use of a scripting variable for a custom tag requires the creation of a tag-extra-info (TEI) class. See "Variable Declaration Through Tag-Extra-Info Classes". With the JSP 1.2 specification, however, there is a simpler mechanism--a <variable> element in the TLD file where the associated tag is defined. This is sufficient for most cases, where logic related to the variable is simple enough to not require use of a TEI class.

The <variable> element is a subelement under the <tag> element that defines the tag that uses the variable.

You can specify the name of the variable in one of two ways:

or:

Along with <name-given> and <name-from-attribute>, the <variable> element has the following subelements:

Here is an example that declares two scripting variables for a tag myaction. Note that details within the <tag> element that are not directly relevant to this discussion are omitted:

<tag>
   <name>myaction</name>
   ...
   <attribute>
     <name>attr2</name>
     <required>true</required>
   </attribute>
   <variable>
      <name-given>foo_given</name-given>
      <declare>false</declare>
      <scope>AT_BEGIN</scope>
   </variable>
   <variable>
      <name-from-attribute>attr2</name-from-attribute>
      <variable-class>java.lang.Integer</variable-class>
   </variable>
</tag>

The name of the first variable is hardcoded as foo_given. By default, it is of type String. It is not to be newly declared, so is assumed to exist already, and its scope is from the start-tag to the end of the page.

The name of the second variable is according to the setting of the required attr2 attribute. It is of type Integer. By default, it is to be newly declared and its scope is NESTED--between the myaction start-tag and end-tag.

See "Tag Library Descriptor Files" for more information about related TLD syntax.

Variable Declaration Through Tag-Extra-Info Classes

For a scripting variable with associated logic that is at least somewhat complicated, the use of a <variable> element in the TLD file to declare the variable might be insufficient. In this case, you can specify details regarding the scripting variable in a subclass of the javax.servlet.jsp.tagext.TagExtraInfo abstract class. This manual refers to such a subclass as a tag-extra-info class. Tag-extra-info classes support additional validation of tag attributes and provide additional information about scripting variables to the JSP runtime.

The JSP container uses tag-extra-info instances during translation. The TLD file specifies any tag-extra-info classes to use for scripting variables of a given tag. Use <tei-class> elements, as in the following example:

<tag>
  <name>loop</name>
  <tag-class>examples.ExampleLoopTag</tag-class>
  <tei-class>examples.ExampleLoopTagTEI</tei-class>
  <body-content>JSP</body-content>
  <description>for loop</description>
  <attribute>
     ...
  </attribute>
  ...
</tag>

The following are key related classes, also in the javax.servlet.jsp.tagext package:

The key methods of the TagExtraInfo class are as follows:

The tag-extra-info class constructs each VariableInfo instance with the following information regarding the scripting variable:


Important:

As of the OC4J 9.0.3 implementation, you can have the getVariableInfo() method return either a fully qualified class name (FQCN) or a partially qualified class name (PQCN) for the Java type of the scripting variable. FQCNs were required in previous releases, and are still preferred to avoid confusion in case there are duplicate class names between packages. Primitive types are not supported.


See "Sample Tag-Extra-Info Class: ExampleLoopTagTEI.java" for sample code of a tag-extra-info class.

Validation and Tag-Library-Validator Classes

The JSP 1.2 specification adds a feature to optionally associate a "validator" class with each tag library. These classes are referred to as tag-library-validator (TLV) classes. The purpose of a TLV class is to validate any JSP page that uses the tag library, verifying that the page adheres to any constraints that you wish to impose through your implementation of the TLV class. Although it is probably typical for a TLV class to check for constraints regarding use of the associated tag library only, there is no limitation--the TLV class can check any aspect of a JSP page.

A tag-library-validator class must be a subclass of the javax.servlet.jsp.tagext.TagLibraryValidator class.

This section discusses tag library validation and TLV classes, covering the following topics:

TLD validator Element

To specify a TLV class for a tag library, use a <validator> element in the TLD file. The <validator> element has the following subelements:

The following <validator> element examples are from the Sun Microsystems JavaServer Pages Standard Tag Library, Version 1.0 specification.

Example 1

This is an example of a TLV class (ScriptFreeTLV) that can disallow JSP declarations, JSP scriptlets, JSP expressions, and runtime expressions according to the settings of its initialization parameters. In this case, JSP expressions and runtime expressions will be allowed, but not JSP declarations or JSP scriptlets.

<validator>
   <validator-class>
      javax.servlet.jsp.jstl.tlv.ScriptFreeTLV
   </validator-class>
   <init-param>
      <param-name>allowDeclarations</param-name>
      <param-value>false</param-value>
   </init-param>
   <init-param>
      <param-name>allowScriptlets</param-name>
      <param-value>false</param-value>
   </init-param>
   <init-param>
      <param-name>allowExpressions</param-name>
      <param-value>true</param-value>
   </init-param>
   <init-param>
      <param-name>allowRTExpressions</param-name>
      <param-value>true</param-value>
   </init-param>
</validator>

Example 2

This is an example of a TLV class (PermittedTagLibsTLV) that allows tag library usage only as specified in its initialization parameter. In addition to the tag library with which the TLV class is associated (the use of which is allowed implicitly), the TLV class allows the libraries specified in a list (with entries separated by white space) in its initialization parameter setting. In this case, it allows only the core, xml, fmt, and sql JSTL libraries.

<validator>
   <validator-class>
      javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV
   </validator-class>
   <init-param>
      <param-name>permittedTaglibs</param-name>
      <param-value>
         http://java.sun.com/jstl/core
         http://java.sun.com/jstl/xml
         http://java.sun.com/jstl/fmt
         http://java.sun.com/jstl/sql
      </param-value>
   </init-param>
</validator>

Key TLV-Related Classes and the validation() Method

As the introduction mentions, a TLV class is a subclass of the javax.servlet.jsp.tagext.TagLibraryValidator class.

The following related classes are also in the javax.servlet.jsp.tagext package:

Here is the key method of a TLV class:

TLV Processing

As each taglib directive is encountered in a JSP page during translation, the JSP container searches the associated TLD file for a <validator> element that specifies a TLV class. If one is found, the container executes the following steps during the translation. See the preceding section, "Key TLV-Related Classes and the validation() Method", for background information about classes and methods discussed here.

  1. The TLV class is instantiated, with initialization parameter settings according to any <init-param> subelements of the <validator> element.

  2. The XML view of the JSP page is exposed to the TLV instance. (See "Details of the JSP XML View".)

  3. The validate() method of the TLV instance is called to validate the JSP page. (See the next section, "Validation Mechanisms".) If this method encounters any errors, it returns an array of ValidationMessage instances. If there are no errors, the method can return null or an empty ValidationMessage[] array.


Note:

The OC4J JSP container implements an optional JSP 1.2 feature for improved reporting of validation errors--the jsp:id attribute. See "The jsp:id Attribute for Error Reporting During Validation" for information.


  1. Each time a custom tag belonging to this library (the library associated with the TLV class) is encountered, it is checked for a tag-extra-info class. If one is specified, then it is instantiated by the JSP container and its isValid() method is called to validate the attributes of the tag. The isValid() method returns true if this validation is successful, or false if not.

Validation Mechanisms

The XML view of a JSP page cannot generally be validated against a DTD and does not include a DOCTYPE statement. There are various namespace-aware mechanisms that you can use for validation. One mechanism in particular is the W3C XML Schema language. Refer to the W3C Web site for information:

http://www.w3.org/XML/

More elementary mechanisms may be suitable as well, such as simply verifying that only a certain set of elements are used in a JSP page, or that a certain set of elements are not used in a page.

Tag Library Event Listeners

The Sun Microsystems Java Servlet Specification, Version 2.3 describes the use of the following types of event listeners:

In servlet 2.3 functionality, you can specify event listeners in the application web.xml file. As a result of this, they are registered with the servlet container and notified of relevant state changes. Servlet context listeners, for example, are notified of changes in the application ServletContext object, such as application startup or shutdown.

The JSP 1.2 specification, for convenience in packaging and deploying tag libraries, adds support for <listener> elements in TLD files. You can use these elements to specify event listeners, as an alternative to specifying them in the web.xml file. This section describes the JSP 1.2 features, covering the following topics:

TLD listener Element

In a TLD file, each <listener> element is at the top level underneath the root <taglib> element. The <listener> element has one subelement, the required <listener-class> element, which specifies the listener class to be instantiated. This would be a class that implements the ServletContextListener, ServletContextAttributeListener, HttpSessionListener, or HttpSessionAttributeListener interface.

Following is an example:

<taglib>
...
   <listener>
      <listener-class>mypkg.MyServletContextListener</listener-class>
   </listener>
...
</taglib>

Activation of Tag Library Event Listeners

When an application starts, the servlet container will make a call to the JSP container to perform the following:

  1. Find and access TLD files.

  2. Read TLD files to find their <listener> elements.

  3. Instantiate and register the listeners.

This is a convenient way to manage application-level and session-level resources that are associated with the usage of a particular tag library. The functionality is essentially the same as for servlet context listeners specified in the web.xml file.


Notes:

  • For event listeners specified in TLD files, the order in which the listeners are registered is undefined, but they are all registered prior to application startup and they are all registered after listeners that are specified in the web.xml file.

  • If a TLD file is present within the WAR file structure, it will be scanned for listeners, and any listeners will be registered, even if the associated tag library is not actually used in the application.


Access of TLD Files for Event Listener Information

You must take certain standard measures to ensure that the JSP container can access TLD files to find their <listener> elements. For general information about TLD file location, accessibility, and packaging, see "Tag Library and TLD Setup and Access". That section includes information about the OC4J shared tag library directory ("well-known" URI location).

In addition, for any TLD file in the well-known tag library directory, you must specify the tag library in a <taglib> element in the application web.xml file if you want the application to activate any listeners specified in the TLD file. Without this step, TLD files in the shared directory are not accessed to search for their <listener> elements. This is to protect against needless performance impact for any application that does not use a tag library that happens to be in the shared directory.

End-to-End Custom Tag Examples

This section provides complete examples of custom tag usage, including sample JSP pages, tag handler classes, and tag library descriptor files. It includes the following samples:


Note:

These examples are for illustrative purposes only and do not necessarily reflect the most realistic or efficient approaches.


Example: Using the IterationTag Interface

This sample shows the use of a custom tag, myIterator, to make the current item in a collection available as a scripting variable. It defines a scripting variable through a <variable> element in the TLD file.

For complete information about this example, including unpacking and deploying it, refer to the following Oracle Technology Network Web site:

http://otn.oracle.com/tech/java/oc4j/htdocs/how-to-jsp-iterationtag.html

(You must register for membership, but registration is free of charge.)

Sample JSP Page: exampleiterator.jsp

The following JSP page uses the myIterator tag:

%@ page contentType="text/html;charset=windows-1252"%> 
<HTML> 
<HEAD> 
<TITLE> 
OJSP 1.2 IterationTag Sample 
</TITLE> 
</HEAD> 
<%@ taglib uri="/WEB-INF/exampleiterator.tld" prefix="it"%> 
<BODY> 

<% java.util.Vector vector = new java.util.Vector(); 
   vector.addElement("One"); 
   vector.addElement("Two"); 
   vector.addElement("Three"); 
   vector.addElement("Four"); 
   vector.addElement("Five"); 
%> 
  Collection to Iterate over is <%=vector%> ..... <p> 

 <B>Iterating ...</B><br> 
 <it:myIterator collection="<%= vector%>" > 
      Item  <B><%= item%></B><br> 
 </it:myIterator> 
</p> 
</BODY> 
</HTML> 

Sample Tag Handler Class: MyIteratorTag.java

In this sample tag handler class, MyIteratorTag, the doStartTag() method checks whether the collection is null. If not, it retrieves the collection object. If the iterator contains at least one element, then doStartTag() makes the first item in the collection available as a page-scope object and returns EVAL_BODY_INCLUDE. This alerts the JSP container to add the contents of the tag body to the response object and to call the doAfterBody() method.

This class extends the tag handler support class TagSupport, which implements the IterationTag interface.

package oracle.taglib; 

import java.util.*; 
import javax.servlet.jsp.*; 
import javax.servlet.jsp.tagext.*; 

/** 
 * MyIteratorTag extends TagSupport. The TagSupport class in JSP 1.2 implements 
the IterationTag 
 */ 

public class MyIteratorTag extends TagSupport 
{ 
  private Iterator iterator; 
  private Collection _collection; 

  public void setCollection(Collection collection) 
  { 
        this._collection = collection; 
  } 

  public int doStartTag() throws JspTagException 
  { 
    if (_collection == null) 
    { 
      throw new JspTagException("No collection with name " 
        + _collection 
        + " found"); 
    } 

    iterator = _collection.iterator(); 
    if (iterator.hasNext()) 
    { 
      pageContext.setAttribute("item", iterator.next()); 
      return EVAL_BODY_INCLUDE; 
    } 
    else 
    { 
       return SKIP_BODY; 
    } 
  } 

  public int doAfterBody() 
  { 

     if (iterator.hasNext()) 
     { 
      pageContext.setAttribute("item", iterator.next()); 
      return EVAL_BODY_AGAIN; 
     } 
     else 
     { 
      return SKIP_BODY; 
     } 
  } 

}

Sample Tag Library Descriptor File: exampleiterator.tld

Here is a sample TLD file to define the myIterator tag. This example takes advantage of the JSP 1.2 feature allowing definition of scripting variables directly in TLD files through <variable> elements. This TLD file defines the scripting variable item of type java.lang.Object. (In a JSP 1.1 environment, this would require use of a tag-extra-info class.) The variable is to be newly declared.

The myIterator tag has an attribute collection to specify the collection. This attribute is required and can be set as a runtime expression. The tag also has a <body-content> value of JSP, which means the JSP translator should process and translate the body code.

For JSP 1.2 syntax, be sure to specify the JSP 1.2 tag library DTD path.

<?xml version = '1.0' encoding = 'windows-1252'?> 
<!DOCTYPE taglib 
        PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" 
        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> 

<taglib> 
   <tlib-version>1.0</tlib-version> 
   <jsp-version>1.2</jsp-version> 
   <short-name>iterate</short-name> 
   <description>This tag lib implements new JSP 1.2 IterationTag
                interface</description> 
   <tag> 
      <name>myIterator</name> 
      <tag-class>oracle.taglib.MyIteratorTag</tag-class> 
      <body-content>JSP</body-content> 
      <attribute> 
          <name>collection</name> 
          <required>true</required> 
          <rtexprvalue>true</rtexprvalue> 
      </attribute> 
      <variable> 
        <name-given>item</name-given> 
        <variable-class>java.lang.Object</variable-class> 
        <declare>true</declare> 
        <!-- default scope: nested --> 
        <description>Scripting Variable item</description> 
      </variable> 
    </tag> 
</taglib>

Example: Using the IterationTag Interface and a Tag-Extra-Info Class

This section provides an end-to-end example of the definition and use of a custom tag, loop, that is used to iterate through the tag body a specified number of times. It defines a scripting variable through a tag-extra-info class.

Included in the example are the following:


Note:

Sample code here uses extended datatypes in the oracle.jsp.jml package. "Extended Type JavaBeans" has an overview of these types. For more information, refer to the Oracle9iAS Containers for J2EE JSP Tag Libraries and Utilities Reference.


Sample JSP Page: exampletag.jsp

Following is a sample JSP page, exampletag.jsp, that uses the loop tag, specifying that the outer loop be executed five times and the inner loop three times:

<%@ taglib uri="/WEB-INF/exampletag.tld" prefix="foo" %>
<% int num=5; %>
<br>
<pre>
<foo:loop index="i" count="<%=num%>">
body1here: i expr: <%=i%> 
           i property: <jsp:getProperty name="i" property="value" /> 
  <foo:loop index="j" count="3">
  body2here: j expr: <%=j%> 
  i property: <jsp:getProperty name="i" property="value" />
  j property: <jsp:getProperty name="j" property="value" /> 
  </foo:loop>
</foo:loop>
</pre>

Sample Tag Handler Class: ExampleLoopTag.java

This section provides source code for the tag handler class, ExampleLoopTag. Note the following:

Here is the code:

package examples;

import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.util.Hashtable;
import java.io.Writer;
import java.io.IOException;
import oracle.jsp.jml.JmlNumber;

public class ExampleLoopTag 
    extends TagSupport
{
    
    String index;
    int count;
    int i;
    JmlNumber ib;

    public ExampleLoopTag() {
      resetAttr();
    }

    public void release() {
      resetAttr();
    }

    private void resetAttr() {
      index=null;
      count=0;
      i=0;
      ib=null;
    }

    public void setIndex(String index)
    {
      this.index=index;
    }
    public void setCount(String count)
    {
      this.count=Integer.parseInt(count);
    }

    public int doStartTag() throws JspException {
        ib=new JmlNumber();
        pageContext.setAttribute(index, ib);
        i++;
        ib.setValue(i);
        return EVAL_BODY_INCLUDE;
    }

    public int doAfterBody() throws JspException {
        if (i >= count) {
            return SKIP_BODY;
        } else
            pageContext.setAttribute(index, ib);
        i++;
        ib.setValue(i);
        return EVAL_BODY_AGAIN;
    }
}

Sample Tag-Extra-Info Class: ExampleLoopTagTEI.java

This section provides the source code for the tag-extra-info class that describes the scripting variable used by the loop tag.

A VariableInfo instance is constructed that specifies the following for the variable:

In addition, the tag-extra-info class has an isValid() method that determines whether the count attribute is valid--it must be an integer.

package examples;

import javax.servlet.jsp.tagext.*;

public class ExampleLoopTagTEI extends TagExtraInfo {
    public VariableInfo[] getVariableInfo(TagData data) {
        return new VariableInfo[] 
            {
                new VariableInfo(data.getAttributeString("index"),
                                 "oracle.jsp.jml.JmlNumber",
                                 true,
                                 VariableInfo.NESTED)
            };
    }

    public boolean isValid(TagData data)
    {
      String countStr=data.getAttributeString("count");
      if (countStr!=null)   // for request-time case
      {
        try {
          int count=Integer.parseInt(countStr);
        }
        catch (NumberFormatException e)
        {
          return false;
        }
      }
      return true;
    }
}

Sample Tag Library Descriptor File: exampletag.tld

This section presents the TLD file for the tag library. In this example, the library consists of only the one tag, loop.

This TLD file follows JSP 1.2 syntax, specifying the following for the loop tag:

Here is the TLD file:

<?xml version = '1.0' encoding = 'ISO-8859-1'?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" 
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>simple</short-name>
  <description>
       A simple tab library for the examples
  </description>
  <!-- example tag -->
  <!-- for loop -->
  <tag>
    <name>loop</name>
    <tag-class>examples.ExampleLoopTag</tag-class>
    <tei-class>examples.ExampleLoopTagTEI</tei-class>
    <body-content>JSP</body-content>
    <description>for loop</description>
    <attribute>
        <name>index</name>
        <required>true</required>
    </attribute>
    <attribute>
        <name>count</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>
</taglib>

Compile-Time Tags

Standard tag libraries, as described in the Sun Microsystems JavaServer Pages Specification, Version 1.2, use a runtime support mechanism. They are typically portable, not requiring any particular JSP container.

It is also possible for vendors to support custom tags through vendor-specific functionality in their JSP translators. Such tags are not portable to other containers.

It is generally advisable to develop standard, portable tags that use the runtime mechanism, but there may be scenarios where tags using a compile-time mechanism are appropriate, as this section discusses.

General Compile-Time Versus Runtime Considerations

The JSP 1.2 specification describes a runtime support mechanism for custom tag libraries. This mechanism, using an XML-style TLD file to specify the tags, is covered earlier in this chapter.

Creating and using a tag library that adheres to this model generally assures that the library will be portable to any standard JSP environment.

There are, however, reasons to consider compile-time implementations:

JSP Compile-Time Versus Runtime JML Library

OC4J provides a portable tag library called the JSP Markup Language (JML) library. This library uses the standard JSP 1.2 runtime mechanism. However, the JML tags are also supported through a compile-time mechanism. This is because the tags were first introduced with JSP implementations that preceded the JSP 1.1 specification, which is when the runtime mechanism was introduced. The compile-time tags are still supported for backward compatibility.

The general advantages and disadvantages of compile-time implementations apply to the Oracle JML tag library as well. There may be situations where it is advantageous to use the compile-time JML implementation. There are also a few additional tags in that implementation, and some additional expression syntax that is supported.

The Oracle9iAS Containers for J2EE JSP Tag Libraries and Utilities Reference describes both the runtime version and the compile-time version of the JML library.


Go to previous page Go to next page
Oracle
Copyright © 2000, 2002 Oracle Corporation.

All Rights Reserved.
Go To Core Documentation
Core
Go To Platform Documentation
Platform
Go To Table Of Contents
Contents
Go To Index
Index