Custom Tags
Custom Tags
Tag Libraries
Lecture 12
Core Servlets & JSP book: www.coreservlets.com
More Servlets & JSP book: www.moreservlets.com
Servlet and JSP Training Courses: courses.coreservlets.com
2 Slides © Marty Hall, http://www.coreservlets.com, book © Sun Microsystems Press
Agenda
• Components of a tag library
• Basic tags
• Tags that use attributes
• Tags that use body content
• Tags that optionally use body content
• Advanced tags
1
Uses of JSP Constructs
Simple
• Scripting elements calling servlet
Application
code directly
• Scripting elements calling servlet
code indirectly (by means of
utility classes)
• Beans
• Custom tags
Complex
• Servlet/JSP combo (MVC),
Application
with beans and possibly custom
tags
2
Defining a Simple Tag Handler
Class
• Extend the TagSupport class
• Import needed packages
– import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
• Override doStartTag
– Obtain the JspWriter by means of pageContext.getOut()
– Use the JspWriter to generate JSP content
– Return SKIP_BODY
– Translated into servlet code at page-translation time
– Code gets called at request time
3
Defining a Simple Tag Library
Descriptor
• Start with XML header and DOCTYPE
• Top-level element is taglib
• Each tag defined by tag element with:
– name, whose body defines the base tag name.
In this case, I use <name>simplePrime</name>
– tagclass, which gives the fully qualified class name of the
tag handler. In this case, I use
<tagclass>coreservlets.tags.SimplePrimeTag</tagclass>
– bodycontent, which gives hints to development
environments. Optional.
– info, which gives a short description. Here, I use
<info>Outputs a random 50-digit prime.</info>
8 Custom Tags www.coreservlets.com
4
Accessing Custom Tags From
JSP Files
• Import the tag library
– Specify location of TLD file
<%@ taglib uri="csajsp-taglib.tld" prefix="csajsp" %>
– Define a tag prefix (namespace)
<%@ taglib uri="csajsp-taglib.tld" prefix="csajsp" %>
• Use the tags
– <prefix:tagName />
• Tag name comes from TLD file
• Prefix comes from taglib directive
– E.g., <csajsp:simplePrime />
<UL>
<LI><csajsp:simplePrime />
<LI><csajsp:simplePrime />
<LI><csajsp:simplePrime />
<LI><csajsp:simplePrime />
</UL>
</BODY>
</HTML>
5
Using simplePrime Tag:
Result
6
Attributes:
The Tag Handler Class
• Use of an attribute called attribute1
simply results in a call to a method called
setAttribute1
– Attribute value is supplied to method as a String
• Example
– To support
Attributes: PrimeTag.java
package coreservlets.tags;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
import java.math.*;
import coreservlets.*;
7
PrimeTag (Continued)
• Why release?
– Servers are permitted to reuse tag instances
• No synchronization issues, since reuse occurs only after tag
processing is totally finished.
– Few current servers reuse tags, but you should plan ahead
– Not needed if attribute is required. (Why not?)
16 Custom Tags www.coreservlets.com
Attributes:
The Tag Library Descriptor File
• The tag element must contain a nested
attribute element
• The attribute element has three further-
nested elements
– name, a required element that defines the case-sensitive
attribute name. In this case, I use <name>length</name>
– required, a required element that stipulates whether the
attribute must always be supplied (true) or is optional
(false). Here, to indicate that length is optional, I use
<required>false</required>
– rtexprvalue, an optional attribute that indicates whether
the attribute value can be a JSP expression like
<%= expression %> (true) or whether it must be a fixed
17 string (false). The default value is false. www.coreservlets.com
Custom Tags
8
TLD File for PrimeTag
...
<taglib>
<tag>
<name>prime</name>
<tagclass>coreservlets.tags.PrimeTag</tagclass>
<info>Outputs a random N-digit prime.</info>
<attribute>
<name>length</name>
<required>false</required>
</attribute>
</tag>
</taglib>
<UL>
<LI>20-digit: <csajsp:prime length="20" />
<LI>40-digit: <csajsp:prime length="40" />
<LI>80-digit: <csajsp:prime length="80" />
<LI>Default (50-digit): <csajsp:prime />
</UL>
</BODY>
</HTML>
9
Using prime Tag: Result
10
Using Tag Body:
The Tag Handler Class
• doStartTag
– Usually returns EVAL_BODY_INCLUDE
instead of SKIP_BODY
• doEndTag
– Define this method if you want to take action after
handling the body
– Return EVAL_PAGE
11
Using Tag Body:
HeadingTag.java (Continued)
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.print("<TABLE BORDER=" + border +
" BGCOLOR=\"" + bgColor + "\"" +
" ALIGN=\"" + align + "\"");
if (width != null) {
out.print(" WIDTH=\"" + width + "\"");
}
...
} catch(IOException ioe) {
System.out.println("Error in HeadingTag: " + ioe);
}
return(EVAL_BODY_INCLUDE); // Include tag body
}
12
Using Tag Body:
The Tag Library Descriptor File
• Only difference is bodycontent element
– Should be JSP instead of empty:
<tag>
<name>…</name>
<tagclass>…</tagclass>
<bodycontent>JSP</bodycontent>
<info>…</info>
</tag>
• Purpose is primarily for development
environments
– Advanced IDEs may have drag-and-drop support for
custom tags
– Defined as optional in JSP specification
• I will omit in my examples
26 Custom Tags www.coreservlets.com
13
Using heading Tag
<%@ taglib uri="csajsp-taglib.tld" prefix="csajsp" %>
<csajsp:heading bgColor="#C0C0C0">
Default Heading
</csajsp:heading>
<P>
<csajsp:heading bgColor="BLACK" color="WHITE">
White on Black Heading
</csajsp:heading>
<P>
<csajsp:heading bgColor="#EF8429" fontSize="60" border="5">
Large Bordered Heading
</csajsp:heading>
<P>
<csajsp:heading bgColor="CYAN" width="100%">
Heading with Full-Width Background
</csajsp:heading>
...
14
Optional Tag Bodies
• First examples had no tag bodies
– doStartTag returned SKIP_BODY
• Most recent examples always included
tag bodies
– doStartTag returned EVAL_BODY_INCLUDE
• Now: decide whether or not to include tag
body at request time
– Have doStartTag return either SKIP_BODY or
EVAL_BODY_INCLUDE depending on values of
request time information
15
TLD File for DebugTag
...
<taglib>
<tag>
<name>debug</name>
<tagclass>coreservlets.tags.DebugTag</tagclass>
<info>
Includes body only if debug param is set.
</info>
</tag>
</taglib>
16
Using debug Tag: Results
17
Manipulating Tag Body:
The Tag Handler Class
• Extend BodyTagSupport
– TagSupport does not have enough infrastructure to
support reading/manipulating the tag body
• New method to override: doAfterBody
– Return SKIP_BODY when done
• getBodyContent returns object of type
BodyContent that has three key methods
– getEnclosingWriter -- returns the JspWriter being used by
doStartTag and doEndTag
– getReader -- returns a Reader that can read tag’s body
– getString -- returns a String containing entire tag body
18
Manipulating Tag Body:
The Tag Library Descriptor File
• No new capabilities needed
<tag>
<name>filter</name>
<tagclass>coreservlets.tags.FilterTag</tagclass>
<info>
Replaces HTML-specific
characters in body.
</info>
</tag>
<TD>
<EM>Some emphasized text.</EM><BR>
<STRONG>Some strongly emphasized text.</STRONG><BR>
<CODE>Some code.</CODE><BR>
...
</TABLE>
39 Custom Tags www.coreservlets.com
19
Using the filter Tag:
Results
20
Manipulating the Body Multiple
Times: the repeat Tag
<%@ taglib uri="csajsp-taglib.tld" prefix="csajsp" %>
<OL>
<!-- Repeats N times. A null reps value
means repeat once. -->
<csajsp:repeat
reps='<%= request.getParameter("repeats") %>'>
<LI><csajsp:prime length="40" />
</csajsp:repeat>
</OL>
21
Nested Tags: the if Tag
<%@ taglib uri="csajsp-taglib.tld" prefix="csajsp" %>
<csajsp:if>
<csajsp:condition>true</csajsp:condition>
<csajsp:then>Condition was true</csajsp:then>
<csajsp:else>Condition was false</csajsp:else>
</csajsp:if>
...
Some coin tosses:<BR>
<csajsp:repeat reps="20">
<csajsp:if>
<csajsp:condition>
<%= Math.random() > 0.5 %>
</csajsp:condition>
<csajsp:then><B>Heads</B><BR></csajsp:then>
<csajsp:else><B>Tails</B><BR></csajsp:else>
</csajsp:if>
</csajsp:repeat>
44 Custom Tags www.coreservlets.com
22
Open Source Tag Libraries
http://jakarta.apache.org/taglibs/
• JSP Standard Tag Library (JSTL)
– Covered in Ch. 12 of More Servlets and JavaServer Pages
• Internationalization (I18N)
• Database access
• Sending email
• JNDI
• Date/time
• Populating/validating form fields
• Perl regular expressions
• Extracting data from other Web pages
• XSL transformations
• Etc.
46 Custom Tags www.coreservlets.com
Summary
• For each custom tag, you need
– A tag handler class (usually extending
TagSupport or BodyTagSupport)
– An entry in a Tag Library Descriptor file
– A JSP file that imports it, specifies prefix, and uses it
• Simple tags
– Generate output in doStartTag, return SKIP_BODY
• Attributes
– Define setAttributeName method. Update TLD file
• Body content
– doStartTag returns EVAL_BODY_INCLUDE
– Add doEndTag method
47 Custom Tags www.coreservlets.com
23
Questions?
More Information
• Source code for all examples
– http://www.coreservlets.com
• Servlet/JSP Training Courses
– http://courses.coreservlets.com
• Core Servlets & JSP
– http://www.coreservlets.com
• More Servlets & JSP
– Sequel to Core Servlets & JSP
– http://www.moreservlets.com
• Servlet home page
– http://java.sun.com/products/servlet/
• JavaServer Pages home page
– http://java.sun.com/products/jsp/
49 Custom Tags www.coreservlets.com
24