Oracle Application Server Containers for J2EE 10g (OC4J)

Date: 08-Sep-2003

Implementing Tag Files in OC4J 10g (10.0.3)

 
After completing this How-To you should be able to: 
Understand the key features of Tag Files that is part of the JSP 2.0 specification 
Create and use a Tag File
Deploy and run the Tag Files in OC4J

Table of Contents:

Introduction

JavaServer Pages (JSP) is the Java 2 Platform Enterprise Edition (J2EE) technology for building applications that generate dynamic web content, such as the HTML, DHTML, XHTML, and XML. JSP technology enables the authoring of web pages that create dynamic content with maximum power and flexibility.

JSP 2.0
JSP 2.0 is an upgrade to JSP 1.2 with several new and interesting features that make the life of Web application designers and developers easier. The objective of JSP 2.0 is to make JSP easier to use than ever, and more importantly to be used without having to learn the Java programming language itself. 

In addition to several other improvements, the new key features that have been introduced in JSP 2.0 are listed below:

  • A simple Expression Language (EL), that can be used to easily access data from JSP pages. The EL simplifies writing scriptless JSP-based applications without using Java scriptlets or Java expressions.
  • It simplifies the Tag APIs by adding a new extension mechanism called SimpleTag. 
  • New syntax for defining reusable custom actions using JSP technology directly. The syntax is delivered into .tag and .tagx files that can be written by developers and page authors.
  • Substantial improvement in the XML syntax - The new standard filename extensions (.tagx for tag files and .jspx for JSP files) have been added.
Tag Handlers
The APIs for classic tag handlers in JSP 1.2 is complicated by the allowing of scriptlets in the body of the tags. With the expression language, however, it is now feasible to develop scriptless JSP pages. To this end, JSP 2.0 has introduced a new type of tag extension called a Simple Tag Extension that can be used in one of the two ways below: 
  • Java developers: by defining a class that implements the javax.servlet.jsp.tagext.SimpleTag interface (Simple Tag Handler). 
  • Page authors who do not know Java: by using tag files. 

Note: In this article we will be demonstrating the second approach i.e. the Tag Files approach.

Tag Files
The tag files feature allows one to quickly write simple tag extensions using only JSP syntax. In the past, the ability to encapsulate presentation logic into reusable, full-featured tag libraries was only available to developers that had a reasonable amount of Java experience. Tag files bring the power of reuse to the basic page author, who is not required to know Java. When used together with JSP Fragments and Simple Tag Handlers, these concepts have the ability to simplify JSP development substantially, even for developers who do know Java. The required file extension for a tag file are .tag or .tagx.

For each tag file in the web application, the Web Container makes a tag handler available to JSP pages and other tag files. The key features of the tag files that are demonstrated in this document include:

1. Simple Attributes
2. Dynamic Attributes
3. JSP Fragments
4. Scoped Variables
5. JSTL Core tags - forEach, set, choose, when and otherwise. SQL Tags - setDataSource and query

Simple Attributes

Attributes serve to customize the behavior of a tag just as parameters are used to affect the outcome of executing a method of an object. The container, prior to being passed to the tag file, evaluates simple attributes that are listed in the start tag and have the syntax attr="value". You can set a simple attribute value from a String constant, an EL expression, or with a jsp:attribute element. To demonstrate this, in the following example, a JSP page calls EmpDetails tag file that takes a simple attribute. Here, the value of the attribute is being set with a String constant. The attribute refers to a department number.

  <tags:EmpDetails deptNum="80">

Dynamic Attributes

It is sometimes useful to be able to define a tag file that accepts attributes with dynamic names that are not known until the page author uses the tag. For example, it is time consuming and error-prone to anticipate what attributes a user may wish to pass to a tag that mimics an HTML element. New to JSP 2.0 is the ability to declare a tag file that accepts additional attributes with dynamic names.

JSP Fragments

A JSP fragment is a portion of JSP code passed to a tag file that can be invoked as many times as needed. One can think of a fragment as a template that is used by a tag file to produce customized content. The value of the fragment attribute can be defined with a jsp:attribute element. JSP fragments can be parameterized via expression language (EL) variables(scoped variables) in the JSP code that composes the fragment. The EL/scoped variables are set by the tag file, thus allowing the tag file to customize the fragment each time it is invoked.

Scoped Variables

As mentioned in JSP Fragments, the scoped variables are set by the tag file, thus allowing the tag file to customize the fragment each time it is invoked. The JSP fragments have access to the same page scoped variables as the page in which they were defined (in addition to variables in the request, session, and application scopes).

JSTL Tags

The JavaServer Pages Standard Tag Library (JSTL) encapsulates core functionality common to many JSP applications. For example, instead of iterating over lists using a scriptlet or different iteration tags from numerous vendors, JSTL defines a standard set of tags. This standardization allows you to learn a single set of tags and use them on multiple JSP containers. JSTL has support for common, structural tasks such as iteration and conditionals (named core tags) , tags for manipulating XML documents, internationalization tags, and tags for accessing databases using SQL (named SQL tags). In this document, we will be using the JSTL core and SQL tags.

We will see how the above features are used and implemented when we create an example later in this document.

Prerequisites

Notation Used

  • <OC4J_HOME> refers to the directory where OC4J  is installed.

Implementing a tag file

Here, we will create a tag file that connects to an Oracle database and retrieves the employee details from the HR sample schema. The functionality includes: 
  • Retrieval of employee details like the name, phone number and salary details.
  • Demonstration of the simple attributes feature - The details retrieved are based on the department number.
  • Demonstration of the dynamic attribute feature - The SQL query used for retrieving employee details gets modified if dynamic attributes like the name and salary are also specified. In this example we set name to have the string "Al" (%Al%) and        salary >= 9000
  • Demonstration of the JSP fragments feature -The employee details with salary greater than or equal to 10000 will be appearing in different color compared to the ones with salary less than 10000.
Following are the steps involved in implementing the tag file:

Step 1: Create the tag file
Step 2: Write a JSP that uses the tag file
Step 3: Deploy and run the example in OC4J

Step 1. Create the tag file (EmpDetails.tag)

A tag file is a source file that contains a fragment of JSP code that is reusable as a custom tag. The tag file allows one to create custom tags using JSP syntax. Just as a JSP page gets translated into a servlet class before compilation, a tag file gets translated into a tag handler before compilation. The tag file directives are used to control aspects of tag file translation to a tag handler, specify aspects of the tag, attributes of the tag, and variables exposed by the tag.

In this example, we will create a tag file named EmpDetails.tag. This tag file will be used in the JSP to get the employee details from the database. The complete source code for the tag file can be viewed here. Let us see how the key features of JSP 2.0 are demonstrated through this tag file.

Simple attributes:

A simple attribute is communicated between the calling page and the tag file when the tag is invoked. No further communication occurs between the calling page and tag file. The employee details are retrieved based on the department number. Thus the department number is passed as a simple attribute to the tag file. One needs to declare the simple attributes defined in the tag file with the attribute directive of the tag file directive. Thus the department number attribute is defined as follows in the tag file.
 
<%@ attribute name="deptNum"%>

Dynamic Attributes:

For the tag file to support dynamic attributes, one needs to define the dynamic-attributes attribute in the tag directive. The tag directive is similar to the JSP page's page directive, but applies to tag files. The presence of this attribute indicates that the tag supports additional attributes with dynamic names.
The attribute value identifies a scoped attribute (columnMap in this example) which is used to place a Map containing the names and values of the dynamic attributes passed during the invocation of the tag.
 
<%@ Tag dynamic-attributes="columnMap"%>

This columnMap collection object is iterated using JSTL in the example to get the names and values of the dynamic attributes being passed. The example checks for the existence of two dynamic attributes namely name and salary. If these attributes are specified then the SQL query will include additional search criteria in the WHERE clause. The query altered is based on the dynamic attributes values being encountered. Refer to the JSTL tags section below for more details on usage of the JSTL tagsin this example.

<c:forEach var="column" begin="0" items="${columnMap}">
  <c:choose>
    <c:when test="${column.key == 'name'}">
      <c:set var= "sql" value="${sql} and first_name||last_name like '%${column.value}%'" />
    </c:when> 
    <c:when test="${column.key == 'salary'}">
      <c:set var= "sql" value="${sql} and salary >= ${column.value}"/>
    </c:when> 
  </c:choose>
</c:forEach>

JSP Fragments:

For the employee details with salary greater than or equal to 10000, the records have to appear in a different color (say yellow) compared to the employees with salary amount less than 10000 in a different color (say blue). For this purpose we will use two different fragments namely fragment1 and fragment2. The tag file will invoke one of these fragments depending on the salary of the employee. These fragments are passed to the tag file as fragment type attributes.

One needs to also declare the fragment type attributes in the tag file with the attribute directive. Thus fragment1 and fragment2 are defined in the tag file with attribute directive and fragment attribute value set to "true".
 
<%@ Attribute name="fragment1" fragment="true" %>
<%@ attribute name="fragment2" fragment="true" %>

The fragment attribute specifies, if the attribute is a fragment to be evaluated by the tag file (true) or a normal attribute to be evaluated by the container prior to being passed to the tag file. Different fragments are invoked based on the salary amount. Here the JSTL core tags are used for iteration and conditional checking. Refer to the JSTL tags section below for more details on usage of the JSTL tagsin this example.

 
<c:forEach var="empRow" begin="0" items="${emp.rowsByIndex}"> 
  <c:choose>
    <c:when test="${empRow[2] >= 10000}">
      <c:set var="name" value="${empRow[0]}"/>
      <c:set var="phone" value="${empRow[1]}"/>
      <c:set var="salary" value="${empRow[2]}"/>
      <jsp:invoke fragment="fragment1"/>
    </c:when> 
    <c:otherwise>
      <c:set var="name" value="${empRow[0]}"/>
      <c:set var="phone" value="${empRow[1]}"/>
      <c:set var="salary" value="${empRow[2]}"/>
      <jsp:invoke fragment="fragment2"/>
    </c:otherwise>
  </c:choose>
</c:forEach> 

Scoped Variables:

The JSP fragments need to use the employee details like the name, phone and salary that are available in the tag file. To emulate OUT or nested parameters, scoped variables can be used. The scope variable is not initialized by the calling page, but is set by the tag file. Thus one needs to declare a scope variable exposed by a tag file with the variable directive. In this example, scoped variables namely name, phone and salary are defined in the tag file so that the value of these details available with the tag file can be set in them.
 
<%@ variable name-given="name" %>
<%@ variable name-given="phone" %>
<%@ variable name-given="salary" %>

The JSP fragments use these scoped variables by making use of ${name}, ${phone}, ${salary} Expression Language constructs to display the values that are set in the tag file.

JSTL tags:

In this EmpDetails tag file of the example, JSTL core tags are used for providing structural tasks such as iteration and conditionals and JSTL SQL tags are used to make direct calls to the database. In order to use the JSTL core and the SQL tags, the tag library descriptor's location for these tags need to be specified in the tag file.
 
<%@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql_rt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>

JSTL Core tags:
The Core tag library provides common support for everyday tasks, such as presenting and setting variables, iterating over a collection of items, testing conditions, and other actions such as importing and redirecting Web content. In the example, variable support tag in core tags like the set is used for setting the value of a scoped variables namely the name, phone and salary.
 
<c:set var="name" value="${empRow[0]}"/>
<c:set var="phone" value="${empRow[1]}"/>
<c:set var="salary" value="${empRow[2]}"/>

To execute the flow control logic, page authors must generally resort to using scriptlets, but the flow control tags in core tags like the choose, when and otherwise eliminate the need for scriptlets. The choose tag performs conditional block execution by the embedded when sub tags. It renders the body of the first when tag whose test condition evaluates to true. If none of the test conditions of nested when tags evaluate to true, then the body of an otherwise tag is evaluated, if present. To invoked different JSP fragments namely the fragment1 and fragment2 based on the salary and to generate the SQL to be processed based on the dynamic attributes being passed or not, the core tags like the choose, when and otherwise are used in the example. 
 
<c:choose>
  <c:when test="${empRow[2] >= 10000}">
    ...
    <jsp:invoke fragment="fragment1"/>
  </c:when> 
  <c:otherwise>
    ...
    <jsp:invoke fragment="fragment2"/>
  </c:otherwise>
</c:choose>

The forEach tag provides an easy way to iterate through a collection's elements. Here, it is used to iterate over the resultset returned by the SQL query. This tag is also used for iterating over the columnMap object that holds the dynamic attributes.
 
<c:forEach var="empRow" begin="0" items="${emp.rowsByIndex}"> 
  ...
  ..
</c:forEach>

The collection is specified via the items attribute, and the current item is available through a scope variable named by the item attribute.

JSTL SQL Tags:
The SQL tag library provides standardized support for accessing and anipulating data in the database.
In the example, the 
setDataSource tag is used for setting the JNDI datasource information.
 
 <sql:setDataSource dataSource="jdbc/hr"/> 

The query tag that returns a resultset is used to perform the query to get the employee details from the database. The SQL string that is used by the query tag is the one that is generated as a result of iterating over the non-empty dynamic attributes columnMap object. If the dynamic attribute columnMap is empty then the default SQL string with simple attributes specified in the WHERE clause is used.
 
<sql:query var="emp"><c:out escapeXml="false" value="${sql}"/>
</sql:query>

Once the tag file is created, the next step is to create a JSP page that uses the "EmpDetails" tag.

Step 2. Write a JSP that uses the "EmpDetails" tag file (EmpList.jsp)

EmpList.jsp in Listing 1 below describes the JSP that uses the "EmpDetails" tag file. View the complete source code for EmpList.jsp here.

Before calling the EmpDetails tag in the JSP, one must specify the tag file prefix and the library's Uniform Resource Identifier (URI) that specifies the location of the tag file:
 
<%@ taglib prefix="tags" tagdir="/technology/WEB-INF/tags" %>

The tag file had set the values for the scoped variables namely name, phone and salary . These variables are used directly in the JSP fragments using the Expression Language (EL) syntax to display the respective details of the employees. Please refer to the documentation in Listing 1 on "EmpDetails" tag file invocation and passing JSP Fragment type attributes. The EmpList.jsp invokes the "EmpDetails" tag file twice. In the first invocation, dynamic attributes namely the name and salary are passed and in the second invocation there are no dynamic attributes passed.
 
Listing 1

<%@ taglib prefix="tags" tagdir="/technology/WEB-INF/tags" %>
<html>
  ....
  ....

  ....
  <%-- 
    Call the "EmpDetails" tag file for getting the employee details. 
    Here the employee details are retrieved for department number = 80. 
    In the call to "EmpDetails" tag file, two dynamic attributes are also passed. 
    One is the name and the second is the salary amount.
             
    For the employee details where the salary >= 10000, the fragment type 
    attribute specified by fragment1 is invoked otherwise fragment2 is invoked.
  --%>
  <tags:EmpDetails deptNum="80" name="Al" salary="9000">
    <jsp:attribute name="fragment1">
      <tr bgcolor="#FFFF99" align="center"> 
        <td ><font color="#CC0033">${name}</font></td>
        <td ><font color="#CC0033">${phone}</font></td>
        <td ><font color="#CC0033">${salary}</font></td>
       </tr>
    </jsp:attribute>
    <jsp:attribute name="fragment2"> 
      <tr bgcolor="#99FFFF" font color="#330066" align="center"> 
        <td ><font color="#330066">${name}</font></td>
        <td ><font color="#330066">${phone}</font></td>
        <td ><font color="#330066">${salary}</font></td>
      </tr>
    </jsp:attribute> 
  </tags:EmpDetails>
  ...
  ...
  ...
  <%-- 
   Call the "EmpDetails" tag file for getting the employee details. 
   Here the employee details are retrieved for department number = 80. 
   In the call to "EmpDetails" tag file there are no dynamic attributes passed. 
     
   For the employee details where the salary >= 10000, the fragment type 
   attribute specified by fragment1 is invoked otherwise fragment2 is invoked.

  --%>
  <tags:EmpDetails deptNum="80" >
    <jsp:attribute name="fragment1">
      <tr bgcolor="#FFFF99" align="center"> 
        <td ><font color="#CC0033">${name}</font></td>
        <td ><font color="#CC0033">${phone}</font></td>
        <td ><font color="#CC0033">${salary}</font></td>
       </tr>
    </jsp:attribute>
    <jsp:attribute name="fragment2"> 
      <tr bgcolor="#99FFFF" font color="#330066" align="center"> 
        <td ><font color="#330066">${name}</font></td>
        <td ><font color="#330066">${phone}</font></td>
        <td ><font color="#330066">${salary}</font></td>
      </tr>
    </jsp:attribute> 
  </tags:EmpDetails>
  ...
  ...
  ...
 </html>


Step 3. Deploy and run the example in OC4J

The example can be deployed either using the Simple Deployment method or the EAR deployment. Before deploying the example using either of these methods, please complete the 'Configuring the Datasource ' section below.

Configuring the Datasource

1. Make sure that you've downloaded and installed OC4J - Release (10.0.3)

2. Then, setup the database connection for the example using the datasources. For this, edit the data-sources.xml file under the OC4J_HOME\j2ee\home\config directory and add the following connection information within the <data-source>...</data-source> tags. 

<Data-source class="oracle.jdbc.pool.OracleDataSource"
name="hr"
location="jdbc/hr"
xa-location="jdbc/xa/hrXA"
ejb-location="jdbc/Ejbhr"
connection-driver="oracle.jdbc.driver.OracleDriver"
username="HR"
password="HR"
url="jdbc:oracle:thin:@localhost:1521:orcl"
inactivity-timeout="300"
/>

Note: If you have used a different schema to run the scripts for HR tables, then, change the username and password values appropriately in the above data-source entry.

Replace the references to localhost:1521:orcl in the url, with the hostname:port:database_sid configuration information and save the file.

where,

hostname - is the hostname of the machine where Oracle 9i database is running.
port - is the port on the hostname where the database listener is listening to.
database_sid - is the sid of your database.
3. Please restart the OC4J server if it's already running or start it if it is not running already.

Now, you can go ahead and perform the Simple deployment or the EAR deployment steps below.

Simple Deployment

  1. Create a directory named "tags" in the <OC4J_HOME>\default-web-app\WEB-INF location.
  2. Copy the EmpDetails.tag source file to the <OC4J_HOME>\default-web-app\WEB-INF\tags directory. 
  3. Copy the EmpList.jsp that will access the "EmpDetails" tag file to the <OC4J_HOME>\default-web-app directory.
  4. To define a logical mapping of the datasource to the actual JNDI name defined in the data-sources.xml file, edit the web.xml file under the <OC4J_HOME>\default-web-app\WEB-INF directory and add the following resource reference information within the <web-app>...</web-app> tags.

  5. <resource-ref>
    <res-ref-name>jdbc/hr</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    </resource-ref>
     

  6. Please restart the OC4J server if it's already running or start it if it is not running already.
  7. Access the JSP in OC4J by visiting the following URL:

    http://<hostname>:<port>/EmpList.jsp

    where,

    hostname is the name of the host where this application is deployed.
    portno is the port number where OC4J is listening. 

EAR Deployment 

1. Download the howtotagfile.ear into the <OC4J_HOME>\j2ee\home\applications directory.

2. Go to the <OC4J_HOME>\j2ee\home\config directory and edit the http-web-site.xml file.
    Add the following entry within the 
<web-site> tags :
<web-app application="howtotagfile" name="howtotagfile-web"root="/technology/howtotagfile"/>
    Save the file.


3. Go to the 
<OC4J_HOME>\j2ee\home\config directory and edit the server.xml file.
    Add the following entry within the 
<application-server> tag:
<application name="howtotagfile" path="../applications/howtotagfile.ear" /> 
    Save the file.

4. OC4J's hot-deploy feature will automatically auto-deploy and install the application for you if the server is running already. If the server is not running, please start the server and it will deploy the application automatically at start-up.

Alternatively, a less hacky way to deploy would be to use admin.jar utility. If you choose to use admin.jar, run the following two command to deploy and bind your application:
a)  To deploy
      java -jar admin.jar ormi://<host>:<ormi-port > < uid> <pwd>
                                     -deploy -file <path-to-file>/howtotagfile.ear
                                     -deploymentName howtotagfile

b) To bind the URI for the web module
    java -jar admin.jar ormi://<host>:<ormi-port > < uid> <pwd> 
                                     -bindWebApp howtotagfile howtotagfile-web http-web-site /howtotagfile
 

5. To run the example, access the following url:

http://<hostname>:<port>/howtotagfile/jsps/EmpList.jsp

where,

hostname is the name of the host where this application is deployed.
portno is the port number where OC4J is listening. 

 

List of JSP 2.0 How-tos/Demos of Interest

  • Tic-Tac-Toe Demo - Demo illustrates JSP 2.0 fragments and simple tag handler.  This demo is about the game of "Randomized TicTacToe".
  • How-to-SimpleTag-Handler - This is also a tutorial style how to that illustrates creation and use of Simple Tag Handler class.  It uses similar scenario as in How-to-tagfile.
  • Estore Demo - This demo illustrates tag files, JSTL, EL and other JSP 2.0 features. The demo is about the estore web front changing it look and feel based on the occasion and promoting the appropriate products for the occasion.

 

Resources


Please enter your comments about this sample in the OTN Sample Code Discussion Forum.
E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy