You are on page 1of 90

JSP Custom Tags

Keyton Weissinger
Key Focus, Inc.
keytonw@mindspring.com

27 March 2001
O’Reilly Conference on Enterprise Java
Santa Clara, CA
Agenda, Part I
• Tags? Actions? Huh?
• Tag Interface
• Tag Attributes
• Tags and Scripting Variables
• BREAK

JSP Custom Tags 2


Agenda, Part II
• Body Tags
• Nested Tags
• Iterating Tags
• Tags and the JSP Container
• Packaging and Deployment
• Wrap-up and Q&A

JSP Custom Tags 3


Tags? Actions? Huh?

A brief introduction to
custom tags.

JSP Custom Tags 4


Definitions
• A “tag” is an XML element that can
be used in a JSP to incorporate
functionality without using scriptlet
code.
• An “action” is the task performed by
the tag.

JSP Custom Tags 5


Definitions, cont.
• A “tag handler” is basically a JavaBean
that implements the Tag interface and
has property setter methods
corresponding to each tag attribute. The
JSP container uses this class to process
the tag.
• A “tag library” or “taglib” is a collection of
one or more custom tags.

JSP Custom Tags 6


Tag Syntax
A custom tag consists of a start tag
with a taglib-identifying prefix (possibly
containing attributes), a body (which
can be empty) and an end tag:

<log:logMessage categoryName="testCat"
priority="fatal">
The body contents…
</log:logMessage>

JSP Custom Tags 7


Alternate Tag Syntax
If a tag does not contain any body
contents, it can be used like this:

<log:logMessage categoryName="testCat"
priority="fatal" message="test"/>

JSP Custom Tags 8


The <%@taglib%> Directive
Before using a tag library, you must
inform the JSP container about the tag
library using the <%@taglib%>
directive before the first use of a tag:

<%@ taglib uri="/logtags" prefix="log" %>

The taglib directive also allows you to


specify a prefix to use with a given tag
library in its use in your JSP.
JSP Custom Tags 9
Tag Libraries
• One or more tags can be packaged
together as a “tag library.”
• A tag library is described in a tag library
descriptor (.TLD) file.
• Tags from different libraries can be called
from the same JSP, but each must be
declared separately with its own
<%@taglib%> directive and must be
uniquely identified with its own prefix.

JSP Custom Tags 10


What Can Tags Do?
A custom tag can:
• Know about its JSP environment.
• Perform simple tasks.
• Perform formatting or other
customization of output.
• Introduce variables usable from
scriptlets later in the JSP.
• Work together either as nested pairs
or separately.
JSP Custom Tags 11
Why Are Tags Important?
• Simplification of complex tasks
across multiple JSPs in a web
application.
• Complex code hiding.
• Design tool incorporation.
• Portable to any JSP container.
• Incorporation of functionality into
JSPs not using Java as the scripting
language.
JSP Custom Tags 12
Tag Interface

All tag handler classes


must implement the
Tag interface.

JSP Custom Tags 13


Tag Interface
public interface Tag {
void setPageContext(PageContext pc)
void setParent(Tag t)
Tag getParent()
int doStartTag() throws
JspException
int doEndTag() throws JspException
void release()
}
JSP Custom Tags 14
Tag Interface Constants
The Tag interface also includes the
following constants:
public final static int SKIP_BODY = 0;
public final static int
EVAL_BODY_INCLUDE = 1;
public final static int SKIP_PAGE = 5;
public final static int EVAL_PAGE = 6;

JSP Custom Tags 15


Return Values
int doStartTag()
• SKIP_BODY
• EVAL_BODY_INCLUDE
int doEndTag()
• SKIP_PAGE
• EVAL_PAGE

JSP Custom Tags 16


TagSupport Class Additions
In addition to those methods in Tag, the
TagSupport class also provides the following:
public static final Tag
findAncestorWithClass(Tag from,
Class klass)
public void setId(String id)
public String getId()
public void setValue(String k, Object o)
public Object getValue(String k)
public void removeValue(String k)
public Enumeration getValues()
JSP Custom Tags 17
Tag Library Descriptor Files
• The JSP container generates code in
the JSP implementation class for a
tag according to information you set
in the TLD.
• The TLD is an XML document.
• It contains a single <tag/> element
for each tag in the library.

JSP Custom Tags 18


TLD Elements
The TLD has the following elements:
• The <taglib/> element contains all the
other elements in the TLD.
• <tlibversion/>
• <uri/>
• <jspversion/>
• <shortname/>

JSP Custom Tags 19


TLD Elements, cont.
The <taglib/> element contains a <tag/>
element for each tag in the library. The possible
sub-elements of <tag/> are as follows:
• <name/>
• <tagclass/>
• <teiclass/>
• <bodycontent/>
• <info/>
• <attribute/>
JSP Custom Tags 20
TLD Example
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP
Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>logtags</shortname>
<uri></uri>
<info>Log4J Wrapper Tags</info>
<tag>
<name>initLog</name>
<tagclass>
com.oreilly.jsp.taglibs.logtags.InitLogTag
</tagclass>
<info>Logging system initialization tag.</info>
</tag>
</taglib> JSP Custom Tags 21
Example Background
• Log4j is an open source project.
• Allows developers to fully control
logging of an application.
• Fully runtime configurable.
• Gentle learning curve.
• See http://jakarta.apache.org/log4j/

JSP Custom Tags 22


Example Background
• A category is a named entity that
categorizes a part of the logging space.
• An appender is a logging output
destination.
• A layout is a formatter for output to an
appender.
• Priority is the minimum level of
messages to be logged for a category.

JSP Custom Tags 23


Example Background
root appender1
category1 appender2
category2 appender3
category 3 appender4

JSP Custom Tags 24


Example

Simple Tag Demo

JSP Custom Tags 25


Tag Attributes

A tag can have zero or


more attributes.
Attribute values provide
information to the tag’s
tag handler class at
execution time.
JSP Custom Tags 26
Tag Attributes
• Each attribute has a corresponding
setXxxx() method.
• Each attribute value included in the
tag triggers a call to its corresponding
setter. No particular order.
• The setter called can be determined
by capitalizing the first letter of the
attribute name and adding the word
“set” as a prefix.
JSP Custom Tags 27
Tag Attribute Setters
<log:logMessage
message=“test msg”/>
would call
setMessage(String pMessage)
with the String value “test msg”

JSP Custom Tags 28


Attribute Data Types
• The signature of the attribute setter
method in the tag handler class
dictates the data type expected for
that attribute.

JSP Custom Tags 29


Tag Attribute Setters
<log:initLog override=“true”/>
would call
setOverride(boolean pOverride)
with the boolean value true.

JSP Custom Tags 30


Tag Attribute Value Conversion
Property Type Conversion Method
• boolean or Boolean • Boolean.valueOf(String)

• byte or Byte • Byte.valueOf(String)

• char or Character • String.charAt(int)

• double or Double • Double.valueOf(String)

• int or Integer • Integer.valueOf(String)

• float or Float • Float.valueOf(String)

• long or Long • Long.valueOf(String)

JSP Custom Tags 31


JSP Container Call Sequence
The JSP container call sequence goes as
follows:
• Instantiates tag handler.
• Calls setup methods
(setPageContext(), etc).
• Calls each setXxxx() method
depending on each attribute’s presence in
the tag.
• Calls doStartTag().
• Calls doEndTag().
JSP Custom Tags 32
Call Sequence Diagram

<%@ taglib …%>


<log:category
priority=“fatal” 1-> setPriority()
> 2-> doStartTag()
Body contents.
</log:category> 3-> doEndTag()

JSP Custom Tags 33


Runtime Attribute Values
Attribute values can be the result of a
runtime expression:
<%
Collection roomsCol = new
ArrayList();
%>
<log:logCollection
collection="<%=roomsCol%>“/>
NOTE: This is how to handle other data types.
JSP Custom Tags 34
<attribute/> Element
There is an <attribute/> element in the
TLD for each attribute for each tag:

<attribute>
<name>message</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>

JSP Custom Tags 35


Example Background
root appender1
category1 appender2
category2 appender3
category 3 appender4

JSP Custom Tags 36


Example Background
A log4j category’s “priority” setting
specifies the “level” required for a
message to be logged for a given
category:
• Debug
• Info
• Warn
• Error
• Fatal JSP Custom Tags 37
Example Background
Each category has methods corresponding
to the various priorities. You use the
appropriate method to log a message of a
given priority for the category of interest:
• myCat.debug(“Here’s a message.”);
• myCat.info(“Here’s a message.”);
• myCat.warn(“Here’s a message.”);
• myCat.error(“Here’s a message.”);
• myCat.fatal(“Here’s a message.”);

JSP Custom Tags 38


Example

Tag Attribute Demo

JSP Custom Tags 39


Tags and Scripting Variables

Tags can introduce


variables that can be
used later in a JSP
scriptlet or another
custom tag.
JSP Custom Tags 40
Tag-Introduced Scripting Variables
This mechanism allows your tag to
introduce a variable that you can use in
scriptlets later in the JSP:

<log:category id=“myCat”/>
<%
myCat.debug(“Hello!”);
%>
JSP Custom Tags 41
Introduction of Scripting Variables
To have your tag introduce a scripting
variable, you must perform the
following steps:
• Somewhere in your tag handler class
you must add your variable to one of the
JSP scopes.
• Create a TagExtraInfo class for your
tag handler class and reference it in
your TLD.
JSP Custom Tags 42
Creating a Scripting Variable
<log:category id=“myCat”/>
From TagSupport base class:
void setId(String id) {
this.id = id;
}
From your tag’s doStartTag() method:
Category rootCat =
Category.getRoot();
pageContext.setAttribute(id,
rootCat, Page.APPLICATION_SCOPE);
JSP Custom Tags 43
TagExtraInfo Class
public class CategoryTagExtraInfo extends
TagExtraInfo {
public VariableInfo[]
getVariableInfo(TagData data) {
return new VariableInfo[] {
new VariableInfo(
data.getAttributeString("id"),
"org.apache.log4j.Category",
true,
VariableInfo.AT_END)
};
}
}

JSP Custom Tags 44


Variable Scope
Tags can introduce scripting variables with one of three scopes
represented by the three VariableInfo constants, NESTED,
AT_BEGIN, and AT_END. The following diagram explains these
three scopes:

NESTED AT_BEGIN AT_END


doStartTag()

doEndTag()

JSP Custom Tags 45


TLD Addition for TEI Class
You must also add a <teiclass/>
element to your TLD:

<teiclass>
com.foo.CategoryTagExtraInfo
</teiclass>

JSP Custom Tags 46


Example Background
SimpleAppenderTag
CategoryTag
LogMessageTag

<log:simpleAppender id="myAppender" … />


<log:category id="testCat"
appender="myAppender“ … />
<log:logMessage categoryName="testCat" … />

JSP Custom Tags 47


Example

Scripting Variable
Demo

JSP Custom Tags 48


BREAK

15 minutes.

JSP Custom Tags 49


Body Tags

Body Tags process


their tag body
contents. The body
contents can contain
JSP content.
JSP Custom Tags 50
BodyTag Syntax
An example call to a body tag:
<log:logMessage priority=“fatal”>
There was a fatal exception.
Time:
<%=Calendar.getInstance().getTime()%>
</log:logMessage>

JSP Custom Tags 51


BodyTag Interface
public interface BodyTag extends Tag
{
public final static int
EVAL_BODY_TAG = 2;
void setBodyContent(
BodyContent b);
void doInitBody() throws
JspException;
int doAfterBody() throws
JspException;
JSP Custom Tags 52
}
BodyContent Class
• The tag accesses its body contents
through a BodyContent object which is
set by the JSP container.
• BodyContent is a subclass of
JspWriter which is used to write content
to the response body.
• BodyContent also has several methods
to manipulate (flush, clear, return as a
string) the contents of the body.

JSP Custom Tags 53


JSP Container Call Sequence
The JSP container call sequence is different
for a body tag than it is for a simple tag:
• Instantiates tag handler, calls setup functions.
• Calls setters.
• JSP container calls doStartTag().
• Calls setBodyContent().
• Calls doInitBody().
• Calls doAfterBody().
• JSP container calls doEndTag().
JSP Custom Tags 54
Call Sequence Diagram

<%@ taglib …%>


<log:logMessage
priority=“fatal” 1-> setPriority()
> 2-> doStartTag()
Body contents. 3->setBodyContent()
4-> doInitBody()
5-> doAfterBody()
</log:logMessage> 6-> doEndTag()

JSP Custom Tags 55


BodyTag Methods
• In most cases, it is not necessary to
override the setBodyContent() method
already provided in the BodyTagSupport
base class.
• Use the doInitBody() method to
initialize any variables you need for the
doAfterBody(). Again this is rarely
needed.
• The doAfterBody() is where you will do
the real work of your body tag.
JSP Custom Tags 56
BodyContent and out
• BodyContent allows you to write to
a JspWriter without interfering with
the JspWriter affiliated with the
JSP itself.
• This allows you to write to an output
buffer and decide whether or not to
write the buffer’s content to the
response stream after you have
completed your tag’s processing.
JSP Custom Tags 57
The out Variable

<%@taglib%>
out = JspWriter (JSP)
<tag1> out = BodyContent (tag1)
<tag2> out = BodyContent (tag2)
...
</tag2>
</tag1> out = BodyContent (tag1)
out = JspWriter (JSP)

JSP Custom Tags 58


The out Variable, Part 1
• At the beginning of a JSP, the JSP container
sets the out variable to the JspWriter
returned by the pageContext’s getOut()
method.
• The container experiences body tag 1.
• Creation of Stack of JspWriters.
• Place JSP out on stack.
• Reset out to BodyContent for tag1.

JSP Custom Tags 59


The out Variable, Part 2
1. The JSP container experiences the second
body tag, body tag 2, which is nested inside
body tag 1.
• Place out from body tag 1 onto stack.
• Reset out to BodyContent for body tag 2.
2. The JSP container experiences the end of
body tag 2.
• Reset out to body tag 1’s BodyContent
from stack.

JSP Custom Tags 60


The out Variable, Part 3
1. The JSP container experiences the end of
body tag 1.
• Reset out to the JSP’s JspWriter object
from stack.

JSP Custom Tags 61


The out Variable

<%@taglib%>
out = JspWriter (JSP)
<tag1> out = BodyContent (tag1)
<tag2> out = BodyContent (tag2)

</tag2>
</tag1> out = BodyContent (tag1)
out = JspWriter (JSP)

JSP Custom Tags 62


Output of Body Content
If your tag’s body content should be output into the response body,
you must use the writeOut() method of the BodyContent
Object (from doEndTag()):
if (null != bodyContent) {
JspWriter lastOut =
bodyContent.getEnclosingWriter();
bodyContent.writeOut(lastOut);
}

JSP Custom Tags 63


Return Values
int doStartTag()
• SKIP_BODY
• EVAL_BODY_INCLUDE (NOT ALLOWED)
• EVAL_BODY_TAG
int doAfterBody()
• EVAL_BODY_TAG
• SKIP_BODY
int doEndTag()
• SKIP_PAGE
• EVAL_PAGE
JSP Custom Tags 64
BodyTag TLD Features
To instruct the JSP container that the current
tag is a body processing tag, you must set the
<bodycontent/> element:
• empty
• tagdependent
• JSP (default)

JSP Custom Tags 65


Example

Body Tag Demo

JSP Custom Tags 66


Nested Tags

Nested actions are tags


that are processed as
part of the tag body
content. Typically these
tags rely on certain
properties of the
surrounding tag.
JSP Custom Tags 67
Nested Tags
Nested tags can take two forms:
• Nested tags may or may not use a
variable introduced by the
surrounding tag.
• Some nested tags rely on their
surrounding tags for some
information without which it will not
function.

JSP Custom Tags 68


Example

Nested Tag Demo

JSP Custom Tags 69


Iterating Tags

Tags can iterate over


their bodies
repeatedly until a
condition is met.

JSP Custom Tags 70


Iterating Tags
Iterating tags differ from other body
tags:
• Iterating tags return EVAL_BODY_TAG
from doAfterBody() until some
condition is met.

JSP Custom Tags 71


Example Background
LogCollectionTag:
• Takes a collection and the name of a
message variable.
• Iterates through the collection and
creates a logging message for each
object.
• Creates a scripting variable to be used
by a nested LogMessageTag.
• Repeats until the end of the collection.
JSP Custom Tags 72
Example

Iterating Tag Demo

JSP Custom Tags 73


Tags and the JSP Container

Discussion of the JSP


implementation class
created by the container
for a JSP containing
custom tags.

JSP Custom Tags 74


Example

JSP Implementation
Class Demo

JSP Custom Tags 75


Packaging and Deployment

Tag libraries are


typically packaged
together into a JAR
file and deployed to a
JSP container.
JSP Custom Tags 76
Deployment: Three Options
To deploy and use your tag library, you have
three options:
3. Set the uri attribute of the taglib directive
to the location of the TLD file.
4. Set the uri attribute of the taglib directive
to the location of the JAR file.
5. Set the uri attribute of the taglib directive
to a symbolic name set in the web.xml file.

JSP Custom Tags 77


Option One
1. Deploy your files:
WEB-INF/
/classes
*.class
/tlds
logtags.tld
2. In your JSP, set the uri attribute of the
taglib directive to the location of the TLD
file:
<%@ taglib uri=“/WEB-INF/tlds/logtags.tld”
prefix=“log” %>

JSP Custom Tags 78


Option Two – File Setup
To create a JAR file, first arrange the files in
the following folder organization:
META-INF/
taglib.tld
com/
oreilly/
jsp/
taglibs/
logtags/
*.class
JSP Custom Tags 79
Option Two – JAR Creation
Change to the previously created folder
(containing the META-INF and com folders)
and execute the following:

jar cvf logtags.jar META-INF com

JSP Custom Tags 80


Option Two - Deployment
Copy the JAR file to the lib sub-directory of
WEB_INF folder for your JSP container:

WEB-INF/
lib/
logtags.jar

JSP Custom Tags 81


Option Two - Use
In your JSP, set the uri attribute of the taglib
directive to the location of your JAR file:

<%@ taglib uri=“/WEB-INF/lib/logtags.jar”


prefix=“log” %>

JSP Custom Tags 82


Option Three – Symbolic Name
You can also create a symbolic name in a taglib element
in your web application’s web.xml file:
<web-app>
<taglib>
<taglib-uri>
/logtags
</taglib-uri>
<taglib-location>
/WEB-INF/tlds/logtags.tld
</taglib-location>
</taglib>
</web-app>

JSP Custom Tags 83


Option Three – Symbolic Name Use
To use a symbolic name in your JSP, just
set the uri attribute of the taglib directive to
the symbolic name:

<%@ taglib uri=“/logtags”


prefix=“log” %>

JSP Custom Tags 84


Example

Deployment Demo

JSP Custom Tags 85


Review
To create a tag library:
2. Create a tag handler class that
implements Tag or BodyTag.
3. In the tag handler class create setters
for each attribute your tag will use.
4. In the tag handler class place
processing in the doStartTag,
doEndTag, doInitBody and doAfterBody
methods as needed.
JSP Custom Tags 86
Review, cont.
1. Create a subclass of TagExtraInfo if
your tag introduces a scripting variable
for use later in the JSP.
2. In the TagExtraInfo subclass, add code
for each variable introduced.
3. Compile your tag.
4. Create a tag library descriptor (TLD) file.
5. In the TLD file, add a <tag/> element for
each tag in your library.
JSP Custom Tags 87
Review, cont.
1. Inside each <tag/> element, set the
appropriate sub-elements for attributes,
etc.
2. Optionally create a JAR file using your
tag handler classes and your TLD file.
3. Deploy your tag library into the
appropriate subfolder of your web
application.

JSP Custom Tags 88


Review, cont.
1. For each tag library you wish to use in
your JSP, use the <%@taglib%>
directive to instruct the JSP container
how to process your tags.
2. Use your tags in the JSP, being careful
to include required attributes, etc.
3. Enjoy the accolades of those around
you for being so smart as to use tag
libraries!
JSP Custom Tags 89
Wrap-up and Q&A

Questions?

JSP Custom Tags 90

You might also like