This tutorial will give you an overview of how some of the basic tags in the Jakarta-Taglibs library were created. Tag libraries allow you to create custom actions and encapsulate functionality. Custom tags can clearly separate the presentation layer from the business logic. They are easy to maintain reusable components that have access to all the objects available to JSP pages. Please consult the JavaServer Pages Specification, version 1.2 for more details.
Servers that implement JSP, v1.1+ support tag libraries. You can find a description of various servers and what they currently support at the JavaServer Pages Industry Momentum page. There is also has a very good Java Web Services Tutorial available on Sun's website that includes sections on Custom Tags and the JSP Standard Tag Library (JSTL) .
taglib
directive
The Tag Handler is responsible for the interaction between the JSP page and
additional server-side objects. The handler is invoked during the execution
of a JSP page when a custom tag is encountered. The doStartTag()
and doEndTag() methods are invoked when the start and end custom
tags, respectively, are encountered. The release() method releases
resources allocated by the tag handler.
There are two interfaces that describe a tag handler:
Tag |
used for simple tag handlers not interested in manipulating their body content |
BodyTag |
an extension of Tag and gives the handler access to its body |
The Tag Handler has two main action methods:
doStartTag() |
process the start tag of this action. |
doEndTag() |
process the end tag of this action. Called after returning from doStartTag. |
release() |
release resources |
doStartTag() returns the following:
EVAL_BODY_INCLUDE
- process the body of the action but do not create a new BodyContent. Pass the body through without manipulating it. Only valid if you DON'T implement the
BodyTaginterface.EVAL_BODY_TAG
- process the body of the action and create a new BodyContent. Only valid if you DO implement the
BodyTaginterface.SKIP_BODY
- do not evaluate the body of the tag
doEndTag() returns the following:
EVAL_PAGE
- the rest of the JSP page will be evaluated
SKIP_PAGE
- the rest of the JSP page will not be evaluated
The return values direct the JSP container on how to evaluate the rest of the
JSP page. The release() method releases resources allocated by
the tag handler.
TagSupport and BodyTagSupport are subclasses of Tag
and can be used as base classes when creating new tag handlers.
The TagSupport class is a utility class that implements the Tag
interface and adds additional convenience methods including:
Tag propertiesIf the tag handler manipulates the body of an action, it must implement the
BodyTag interface. doStartTag() must return EVAL_BODY_TAG
in order for the body of the tag to be evaluated. If SKIP_BODY
is returned, the body will be ignored. Methods that interact with the body content
include:
doInitBody() |
invoked before the body of the tag is evaluated but after body content is set |
doAfterBody() |
invoked after body content is evaluated |
The BodyTagSupport class implements the BodyTag
interface and adds additional convenience methods. Some of these methods include:
bodyContent propertyout JSPWriterIn a Web Application handlers must reside in one of the following standard locations for Java classes:
/WEB-INF/lib directory/WEB-INF/classes directoryA tag handler has access to some properties that are set by the JSP container
using setter methods. This includes the pageContext and parent
objects. The tag handler also has access to server-side objects and enclosing
actions. If the tag is nested, the parent handler of the enclosing tag can be
accessed by using either:
TagSupport.getParent()TagSupport.findAncestorWithClass(from, class)The parent handler's statically and dynamically created objects can be obtained once the parent object is retrieved.
The Tag Library Descriptor (TLD) is used by the JSP container to interpret pages that include the taglib directives referring to that tag library. It is an XML document that maps action tags to tag handler classes. You can locate a TLD in two ways:
web.xmltaglib element
taglib-uritaglib-locationYou can find more information about the web.xml taglib element in the Servlet 2.2 and JSP 1.1 specifications.
You will need to explicitly reference the external DOCTYPE because of a recent change to call the validating parser:
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
The TLD taglib element is the document root. It has the following subelements:
tlibversion |
version of the tag library implementation |
jspversion |
version of the JSP specification the tag library requires |
shortname |
name that could be used to reference the tag library from a JSP page |
uri |
uri uniquely identifying the tag library - info string describing the "use" of the tag library |
info |
string describing the "use" of the tag library |
The tag element defines an action in the tag library. It may have several subelements that define the action:
name |
unique action name |
tagclass |
tag handler class implementing javax.servlet.jsp.tagext.Tag |
teiclass |
optional subclass of javax.servlet.jsp.tagext.TagExtraInfo |
bodycontent |
one of three body content types |
info |
optional tag-specific information |
attribute |
all attributes of the action |
bodycontentis included if the tag has a body. It is used by page composition tools so it does not affect the composition of the body. It can be one of the three following types:
JSP(default)
- the JSP container should evaluate any body of the tag, but it can also be empty
tagdependent
- any body of the tag would be handled by the tag itself, but it can also be empty
empty
- body must be empty
the
teiclassdefines the scripting variable and includes the following information:
- name
- type
- whether variable needs to be created or not
- scope
attributescan have the following fields:
name(required)
- attribute name
required
- if attribute is required or optional
rtexprvalue
- if attribute value may be dynamically calculated at runtime by a scriptlet. NOTE: default value is "false", meaning that the attribute has a static value. Make sure you set it to "true" if the attribute value is determined at request time.
For every attribute you must have a JavaBeans style get and set methods in the Tag Handler. If your attribute is named
id, theTagSupportclass defines thesetId() andgetId() methods for you.
JavaServer Pages can handle XML content encapsulated in Tag Library actions.
<%@ taglib uri="identifier" prefix="prefix" %>
To use a Tag Library, you need to tell the JSP container where it is located
using a taglib directive. The directive must come before
any actions.
<taglib-uri>
in the web.xml file.To Install a tag library you need to take the following steps:
{library}.tld file located in the /WEB-INF directory{library}.jar file to the CLASSPATH{library}.jar file to the /WEB-INF/lib directory/WEB-INF/web.xml file. For example:
<taglib>
<taglib-uri>http://jakarta.apache.org/taglibs/{library}</taglib-uri>
<taglib-location>/WEB-INF/{library}.tld</taglib-location>
</taglib>
<taglib-uri> and the uri directive must match. The prefix identifies the tags in the tag library within the jsp page. For example:
<%@ taglib uri="http://jakarta.apache.org/taglibs/{library}" prefix="x" %>
To add a tag library subproject to Jakarta-Taglibs you need to do the following:
build.shbuild.batbuild.xmltaglib.name property to the new custom tag library subproject namebuild.xml file to include the new libraryUse the build scripts in the jakarta-taglibs project to create the war files.
Once you have a war file built you can simply place that file in the $TOMCAT_HOME/webapps
directory. Tomcat will load your classes and create the new context.
The war file should have the following structure:
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/lib/
WEB-INF/lib/{tagLibrary}.jar
WEB-INF/web.xml
WEB-INF/{tagLibrary}.tld
If you do not want to use a jar file, you can place all the class files in the
/WEB-INF/classes directory.
Consult the Java Servlet Specification, v2.2 for more information on war files.
This basic tag is the "Hello World" example. The text "Hello World" will print whenever the tag is encountered.
You can find the Tag Handler for the Hello World tag in the /WEB-INF/classes/basic
directory since it is a part of the basic package
package basic;
Import the jsp and tag classes:
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
The Hello World Tag Handler implements the doStartTag() method which is invoked when the start tag is encountered.
public int doStartTag() throws JspException {
try {
pageContext.getOut().print("Hello World");
} catch (Exception ex) {
throw new JspException("IO problems");
}
return SKIP_BODY;
}
The pageContext is set by the JSP container and is available to
the Tag Handler. The SKIP_BODY value makes sure that no evaluation
of the tag body takes place.
<?xml version="1.0" encoding="ISO-8859-1" ?>
XML header describing the deployment descriptor DOCTYPE. The deployment descriptor includes the elements and configuration information of a web application.
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd">
Initial taglibrary description
<taglib>
<!-- The version number of this tag library -->
<tlibversion>1.0</tlibversion>
<!-- The JSP specification version required to function -->
<jspversion>1.1</jspversion>
<!-- The short name of this tag library -->
<shortname>utility</shortname>
<!-- Public URI that uniquely identifies this version of the tag library -->
<uri>http://jakarta.apache.org/taglibs/utilitytags</uri>
<!-- General information about this tag library -->
<info>
A simple tag library for the examples
</info>
Hello World tag description.
bodycontent tag tells us that the tag will not contain any body
<!-- Hello tag -->
<tag>
<name>Hello</name>
<tagclass>basic.Hello</tagclass>
<bodycontent>empty</bodycontent>
<info>
Print Hello World
</info>
</tag>The web.xml file describes the mapping between the taglib uri
and the location of the Tag Library Descriptor.
Here the unique taglib-uri "http://jakarta.apache.org/taglibs/utilitytags"
is associated with the Tag Library Descriptor in /WEB-INF/tld/utilitytags.tld.
<web-app>
<taglib>
<taglib-uri>
http://jakarta.apache.org/taglibs/utilitytags
</taglib-uri>
<taglib-location>
/WEB-INF/tld/utilitytags.tld
</taglib-location>
</taglib>
</web-app>
The following directive tells the JSP container to use the "http://jakarta.apache.org/taglibs/utilitytags"
uri defined in web.xml. "jLib" is defined
as the prefix value for the tag.
<%@ taglib uri="http://jakarta.apache.org/taglibs/utilitytags" prefix="jLib" %>
The Hello World tag is called. The tag name "Hello" is defined in the the Tag Library Descriptor.
<jLib:Hello/>
This nested tag is an example of an "If" conditional tag. Based on the value of the attribute the included scriptlet will be evaluated or skipped.
The BodyTagSupport class implements the BodyTag interface and has getter methods for the bodyContent property.
public class IfTag extends BodyTagSupport {
The doStartTag() method which is invoked when the start tag is encountered and calls the local getPredicate() method. If the return value is true, the rest of the the tag body is evaluated, otherwise it is skipped.
public int doStartTag() {
if (getPredicate()) return EVAL_BODY_TAG;
else return SKIP_BODY;
}
doAfterBody() is called after some body has been evaluated. It is not invoked
in empty tags or in tags returning SKIP_BODY in doStartTag().
public int doAfterBody() throws JspException {
try {
bodyContent.writeOut(bodyContent.getEnclosingWriter());
return SKIP_BODY;
} catch (IOException ex) {
throw new JspTagException(ex.toString());
}
}
<!-- IF tag -->
<tag>
<name>If</name>
<tagclass>lang.IfTag</tagclass>
The If tag has one required attribute. Since the rtexprvalue is set to true, the attribute can have scriptlet expressions as a value. The value can be dynamically calculated at request time.
<attribute>
<name>predicate</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<info>
Conditional Tag.
</info>
</tag>
The web.xml file describes the mapping between the taglib uri
and the location of the Tag Library Descriptor.
Here the unique taglib-uri "http://jakarta.apache.org/taglibs/utilitytags"
is associated with the Tag Library Descriptor in /WEB-INF/tld/utilitytags.tld.
The If tag requires one attribute. The predicate attribute includes a scriptlet
which will be evaluated at runtime. Based on the predicate attribute value,
the jLib:Hello tag will be evaluated or skipped.
<jlib:if predicate="<%= x==5 %>">
<jLib:Hello/>
</jlib:if>
The utilitytags custom tag library contains examples of some basic
tags. It illustrates several straightforward custom tag library code techniques.
This custom tag library requires no software other than a servlet container that supports the JavaServer Pages Specification, version 1.1 .
Follow these steps to configure your web application with this tag library:
utilitytags/utilitytags.tld)
to the /WEB-INF subdirectory of your web application.utilitytags/utilitytags.jar)
to the /WEB-INF/lib subdirectory of your web application.<taglib> element to your web application deployment
descriptor in /WEB-INF/web.xml like this:
<taglib>
<taglib-uri>http://jakarta.apache.org/taglibs/utilitytags</taglib-uri>
<taglib-location>/WEB-INF/utilitytags.tld</taglib-location>
</taglib>
To use the tags from this library in your JSP pages, add the following directive at the top of each page:
<%@ taglib uri="http://jakarta.apache.org/taglibs/utilitytags" prefix="x" %>
where "x" is the tag name prefix you wish to use for tags from this library. You
can change this value to any prefix you like.
The utilitytags Tag Library contains the following tags:
Hello tag prints out the text "Hello World". It does not
have any attributes.Attribute |
Description |
Required |
|---|---|---|
- |
- |
- |
MacroCopy tag copies the attribute text to a Writer.Attribute |
Description |
Required |
|---|---|---|
name |
Name associated with the text to be copied. Any
string value. |
yes |
MacroPaste tag pastes the text specified by a Writer.Attribute |
Description |
Required |
|---|---|---|
name |
Name associated with the text to be pasted. Any
string value. |
yes |
ShowSource tag takes a jspFile and copies the contents
to a Writer.Attribute |
Description |
Required |
|---|---|---|
jspFile |
The filename and relative path of the jsp file.
Any string value. |
yes |
Include tag includes in-line the output of the specified
url.Attribute |
Description |
Required |
|---|---|---|
url |
Any valid url. |
yes |
If tag is a basic conditional tag.Attribute |
Description |
Required |
|---|---|---|
predicate |
Any string value. |
yes |
For tag is a basic looping tag.Attribute |
Description |
Required |
|---|---|---|
iterations |
Number of loop iterations to be completed. Any string
integer value. |
yes |
varName |
Variable name associated with the For loop. Any
string value. |
no |
begin |
Loop starting value. Any string integer value. |
no |
useBean tag associates an instance of a Java object with the given id.Attribute |
Description |
Required |
|---|---|---|
id |
Uniquely identifies the bean to the JSP container and page. Any string value. |
yes |
scope |
page|request|session|application |
no |
classname |
name of class that defines the implementation of the object. |
no |
type |
type of the scripting variable defined |
no |
beanName |
The name of the bean as expected by the instantiate() method of the java.beans.Beans class |
yes |
processRequest |
true|false. JSP 0.92 compatibility. |
no |
Validate tag generates Javascript to validate the HTML
form.Attribute |
Description |
Required |
|---|---|---|
name |
Name of the form. Any string value. |
yes |
method |
Name of the Javascript function to be generated. Any string value. |
yes |
reqdFields |
Comma separated mandatory field list. Any string value. |
yes |