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).
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 BodyTag interface.
- EVAL_BODY_TAG
- process the body of the action and create a new BodyContent. Only valid if you DO implement the BodyTag interface.
- 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:
If 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:
In a Web Application handlers must reside in one of the following standard locations for Java classes:
A 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:
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:
You 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 |
bodycontent is 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 teiclass defines the scripting variable and includes the following information:
- name
- type
- whether variable needs to be created or not
- scope
attributes can 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, the TagSupport class defines the setId() and getId() 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.
To Install a tag library you need to take the following steps:
<taglib> <taglib-uri>http://jakarta.apache.org/taglibs/{library}</taglib-uri> <taglib-location>/WEB-INF/{library}.tld</taglib-location> </taglib>
<%@ 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:
Use 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.
<!-- 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:
<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" %>
The Hello tag prints out the text "Hello World". It does not have any attributes.
Attribute
|
Description
|
Required
|
---|---|---|
-
|
-
|
-
|
The 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
|
The 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
|
The 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
|
The Include tag includes in-line the output of the specified url.
Attribute
|
Description
|
Required
|
---|---|---|
url
|
Any valid url.
|
yes
|
The If tag is a basic conditional tag.
Attribute
|
Description
|
Required
|
---|---|---|
predicate
|
Any string value.
|
yes
|
The 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
|
The 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
|
The 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
|