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.
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
- Create a directory named "tags" in the <OC4J_HOME>\default-web-app\WEB-INF
location.
- Copy the EmpDetails.tag
source file to the <OC4J_HOME>\default-web-app\WEB-INF\tags
directory.
- Copy the EmpList.jsp
that will access the "EmpDetails" tag file to the <OC4J_HOME>\default-web-app
directory.
- 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.
<resource-ref>
<res-ref-name>jdbc/hr</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
- Please restart the OC4J server if it's already running
or start it if it is not running already.
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.