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. It simplifies the Tag APIs by adding a
new extension mechanism called SimpleTag.
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.
- 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 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
first approach i.e. the Simple Tag Handler approach.
Simple Tag Handler
JSP 2.0 makes it much easier to write custom tags with
Simple Tag Handler. Here, the user has to implement only the doTag()
method. This is intended for use by advanced page authors and tag library
developers who need the flexibility of the Java language in order to write
their tag handlers.
The key features that are demonstrated in this document
include:
1. Simple Attributes
2. Dynamic Attributes
3. JSP Fragments
4. Scoped Variables
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 handler, 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 an emp tag
which takes a simple attribute. Here, the value of the attribute is being
set with a String constant. The attribute refers to a department number.
<jspcr:emp deptNum="80"/>
Dynamic Attributes
Prior to JSP 2.0, the name of every attribute that a
tag handler accepted was predetermined at the time the tag handler was developed.
It is sometimes useful, however, to be able to define a tag handler 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 handler
that accepts additional attributes with dynamic names. This is done by having
the tag handler implement the javax.servlet.jsp.tagext.DynamicAttributes
interface. This also allows one to have optional attributes for a tag.
JSP Fragments
A JSP fragment is a portion of JSP code passed to a tag handler that can
be invoked as many times as needed. One can think of a fragment as a template
that is used by a tag handler 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 variables are set by the tag handler, thus allowing the handler to
customize the fragment each time it is invoked.
Scoped Variables
As mentioned in JSP Fragments, the scoped variables are set by the tag
handler, thus allowing the handler to customize the fragment each time it
is invoked. The JSP fragments have access to the same page scope variables
as the page in which they were defined (in addition to variables in the
request, session, and application scopes).
We will see how the above features are used and implemented
when we create an example later in this document.
Here, we will create a Simple Tag Handler
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 - Modification
of the retrieved details if dynamic attributes like the name and salary
are also specified.
- 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 Simple Tag Handler:
Step 1: Create the Simple Tag Handler
Class
Step 2: Define the Tag Library Descriptor
file
Step 3: Write a JSP that uses the Simple
Tag
Step 4: Deploy and run the example in OC4J
Step 1. Create the Simple Tag Handler
Class (EmployeeDetails.java)
We will create a simple tag handler that will define the
"emp" tag. This tag will be used in the JSP to get the Employee
details from the database. The complete source code for the simple tag handler
can be viewed here.
Let us see how the key features of JSP 2.0 are demonstrated through this Tag
Handler class.
Simple attributes:
The employee details are retrieved based on the department number. Thus the
department number is passed as a simple attribute to the tag handler. For
each simple attribute (here it is only department number), there must be a
setter method in the tag handler which gets the attribute value and stores
it in a field for later use by the tag handler.
public void setdeptNum( int deptNum ) {
this.deptNum = deptNum;
}
|
Dynamic Attributes:
The tag handler should implement the
DynamicAttributes interface to enable the tag to be able to accept
dynamic attributes. The setDynamicAttribute() method handles
the dynamic attributes.
/**
* This method implements the "setDynamicAttribute" method defined in the
* "javax.servlet.jsp.tagext.DynamicAttributes" interface.
* Here "keys" Arraylist object will maintain the names of the dynamic attributes that will be * passed as parameters to the Tag Handler. And the "values" Arraylist object will maintain the values of
* the dynamic attributes that will be passed as parameters to the Tag Handler
*/
public void setDynamicAttribute( String uri, String localName, Object value )
throws JspException {
keys.add( localName );
values.add( value );
}
|
JSP Fragments:
For the employee details with salary amount 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.
The tag handler will invoke one of these fragments depending on the salary
amount of the employee. These fragments are passed to the tag handler as fragment
type attributes.
For each fragment type attribute, there must be a setter
method in the tag handler, which gets the attribute value and stores it in
a field for later use by the tag handler.
// Setter method for fragment type attribute - Fragement1
public void setFragment1( JspFragment fragment1 ) {
this.fragment1 = fragment1;
}
|
Invoking different fragments based on the salary amount.
// Based on the salary of the employee, a different JSP fragment will be invoked in the JSP. // If the salary of employee > 10000 then fragment1 is invoked otherwise fragment2
if ( salary >= 10000 ) {
fragment1.invoke( null );
}
else {
fragment2.invoke( null );
}
|
Scoped Variables:
The JSP fragments need to use the employee details like the name, phone and
salary that are available in the Tag Handler. The doTag() method
uses the JspContext.setAttribute() to create the scoped variables,
namely name, phone, salary, to hold the required values. By default the scoped
variables values are stored in the page scope:
// Set the value of the name, phone and salary in the
// JSP context so that they are available for the JSP Fragments as scoped variables
JspContext ctx = getJspContext( );
ctx.setAttribute( "name", name );
ctx.setAttribute( "phone", phone );
ctx.setAttribute( "salary", Integer.toString( salary ) );
|
The JSP page uses these scoped variables, by making use
of ${name}, ${phone}, ${salary} Expression Language constructs, to display
the values that are set by the Tag Handler.
Once the Tag handler is successfully
created, the next step is to define the tag description in the Tag Library
Descriptor (TLD) file.
Step 2. Define the Tag Library Descriptor
(Emp.tld)
The Tag Library Descriptor(TLD) is an XML document that
describes a tag library. The TLD for a tag library is used by the JSP container
to interpret pages that include taglib directives referring to that tag library.
Emp.tld, in Listing 1 below includes
documentation on the library as a whole and on the individual tag named "emp".
Information on each of the actions defined in the tag library is also included.
Each action in the library is described by providing - its name, the class
of its tag handler, information on any scripting variables created by the
action, and information on attributes of the action.
| Listing 1 |
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/SimpleTagLibrary</uri> <tag> <name>emp</name> <tag-class>oracle.otnhowto.simpletag.EmployeeDetails</tag-class> <body-content>JSP</body-content> <variable> <name-given>name</name-given> </variable> <variable> <name-given>phone</name-given> </variable> <variable> <name-given>salary</name-given> </variable> <attribute> <name>deptNum</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute>
<attribute> <name>fragment1</name> <required>true</required> <fragment>true</fragment> </attribute> <attribute> <name>fragment2</name> <required>true</required> <fragment>true</fragment> </attribute> <dynamic-attributes>true</dynamic-attributes> </tag> </taglib>
|
|
Simple attribute deptNum and fragment type attributes namely
fragment1, fragment2 are defined in this TLD. Scoped variables namely name,
phone, salary are also defined in the TLD. For each valid attribute there
is an indication about whether it is mandatory, whether it can accept request
time expressions, and additional information. The <dynamic-attributes>
element for the tag must contain true so that the method parameters,
name and salary, can be accepted as dynamic attributes at runtime.
And finally, we need to create a JSP page that uses the
"emp" tag that we have created.
Step 3. Write a JSP that uses the "emp"
tag (EmpList.jsp)
EmpList.jsp in Listing
2 below describes the JSP which uses the "emp" tag. View the
complete source code for EmpList.jsp here.
Before calling the "emp" tag in the JSP, one must specify the tag
handler class prefix and the library's Uniform Resource Identifier (URI) that
specifies the location of the Tag Library Descriptor. The tag handler had
used JspContext.setAttribute()method to create the scoped variables
name, phone and salary to display the values available in the Tag Handler.
These variables are used directly in the JSP page using the Expression Language
(EL) syntax to display the respective details of the employees. Please refer
to the documentation in Listing 2 on "emp" tag invocation
and passing JSP Fragment type attributes. The EmpList.jsp invokes the "emp"
tag twice. In the first invocation, dynamic attributes name and salary are
passed and in the second invocation there are no dynamic attributes passed.
| Listing 2 |
<%@ taglib prefix="jspcr" uri="/WEB-INF/Emp.tld" %> <html> ....
....
.... <%--
Call the "emp" tag for getting the employee details. Here the employee details are retrieved for department number = 80. In the call to "emp" tag here, 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 --%> <jspcr:emp deptNum="80" firstname="Al" salary="1200"> <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> </jspcr:emp> ... ...
... <%--
Call the "emp" tag for getting the employee details. Here the employee details are retrieved for department number = 80. Here, 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 --%> <jspcr:emp 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> </jspcr:emp> ...
...
... </html>
|
|
Step 4. 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 10G.
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 Oracle8i or 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
- Copy the EmployeeDetails.java
source file to the
<OC4J_HOME>\default-web-app\WEB-INF\classes
directory. Make sure that the <OC4J_HOME>\jdbc\lib\classes12dms.jar
and <OC4J_HOME>\j2ee\home\lib\servlet.jar files are
in the CLASSPATH. Open a shell/command window and go to the <OC4J_HOME>\default-web-app\WEB-INF\classes
directory. Here, run the following command to create the Tag Handler class.
javac -d . EmployeeDetails.java
Note: javac executable is available as part of Java Development Kit(JDK)
downloadable from http://java.sun.com/.
- Copy the Emp.tld
file that serves as descriptor for the Tag Handler to the
<OC4J_HOME>\default-web-app\WEB-INF
directory.
- Copy the EmpList.jsp
that will access this "emp" tag to the
<OC4J_HOME>\default-web-app
directory.
-
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 howtosimpletag.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="howtosimpletag" name="howtosimpletag-web" root="/technology/howtosimpletag"/>
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="howtosimpletag" path="../applications/howtosimpletag.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>/howtosimpletag.ear
-deploymentName howtosimpletag
b) To bind the URI for the web module
java -jar admin.jar ormi://<host>:<ormi-port
> < uid> <pwd>
-bindWebApp
howtosimpletag howtosimpletag-web http-web-site /howtosimpletag
5. To run the example, access the following url:
http://<hostname>:<port>/howtosimpletag/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.