Basic Custom Tags
Basic Custom Tags
Intro
Tag Examples
Blah, blah, blah. <mytags:showDate/>
Blah blah
Blah, blah, blah
blah. <mytags:showDate format="short"/>
format "short"/>
Blah, blah, blah.
<mytags:translate language="spanish">
Hello World
</mytags:translate>
7
© 2010 Marty Hall
Java-Based Tags
10
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
p
import j
java.io.*;
import java.math.*;
import coreservlets.Primes;
public
bli void
id d
doTag()
T () th
throws J
JspException,
E ti IOE
IOException
ti {
JspWriter out = getJspContext().getOut();
BigInteger prime =
Primes nextPrime(Primes random(length));
Primes.nextPrime(Primes.random(length));
out.print(prime);
}
11 }
Defining a Simple Tag Library
Descriptor
• Start with XML header
• Top-level element is taglib
– Just use tlib-version and short-name as in example
• Each
E h tag
t defined
d fi d by
b tag element
l t with:
ith
– description, which gives short info. Optional.
– name,
name which defines the base tag name.
name
– tag-class, which gives the fully qualified class name of
the tag handler.
– body-content, which specifies if tag is standalone or
contains content between start and end tag.
• You can have multiple tag entries in each TLD file
• Put TLD file somewhere under WEB-INF
12
<tag>
<description>Outputs 50-digit
50 digit primes</description>
<name>simplePrime</name>
<tag-class>coreservlets.tags.SimplePrimeTag</tag-class>
<body-content>empty</body-content>
</tag>
...
</taglib>
• Don’t memorize XML header and standard
part; download and modify online version
– The important thing is to know how to write tag entries
13
– Place TLD file somewhere under WEB-INF
Accessing Custom Tags From
JSP Files
• Import the tag library
– Specify location of TLD file
<%@ taglib uri="/WEB-INF/tlds/csajsp-taglib.tld"
prefix="csajsp"
prefix csajsp %
%>
– Define a tag prefix (namespace)
<%@ taglib uri="/WEB-INF/tlds/csajsp-taglib.tld"
prefix="csajsp"
fi " j " %>
• Use the tags
– <prefix:tagName />
• Tag name comes from TLD file
• Prefix comes from taglib directive
– E.g., <csajsp:simplePrime
j i l i /> /
14
</BODY>
</HTML>
15
Using simplePrime Tag:
Result
16
17
Attributes:
The Tag Handler Class
• Use of an attribute called attribute1
simply
i l results
l ini a call
ll to a method
h d called
ll d
setAttribute1
– Attribute value is supplied to method as a String
• Example
– To support
public
bli void
id setAttribute1(String
ib ( i value1)
l ){
doSomethingWith(value1);
18 }
Attributes: PrimeTag.java
package coreservlets.tags;
19
Attributes:
The Tag Library Descriptor File
• The tag element must contain a nested
attribute element
l t
• The attribute element has three further-
nested elements
– name, a required element that defines the case-sensitive
attribute name.
– required, a required element that stipulates whether the
attribute must always be supplied (true) or is optional
(false).
(false)
– rtexprvalue, an optional attribute that indicates whether
p
the attribute value can be a JSP expression like
<%= expression %> (true) or whether it must be a fixed
string (false). The default value is false.
20
21
Using prime Tag
...
<BODY>
<H1>Some N-Digit Primes</H1>
<%@ taglib
g uri="/WEB-INF/tlds/csajsp-taglib.tld"
j p g
prefix="csajsp" %>
<UL>
<LI>20-digit: <csajsp:prime length="20"/>
<LI>40-digit:
40 di i <csajsp:prime
j i l
length="40"/>
h 40 /
<LI>80-digit: <csajsp:prime length="80"/>
<LI>Default (50-digit): <csajsp:prime/>
</UL>
</BODY>
</HTML>
22
23
Including the Tag Body
• Simplest tags
– <prefix:tagName/>
• Tags with attributes
– <prefix:tagName
fi N att1="val1"
1 " l1" ... //>
• Now
– <prefix:tagName>
Scriptless JSP Content
</prefix:tagName>
25
Including Tag Body:
HeadingTag java
HeadingTag.java
public class HeadingTag extends SimpleTagSupport {
private String
p g align;
g
private String bgColor;
private String border;
private String fgColor;
private String font;
private String size;
27
Using Tag Body:
The Tag Library Descriptor File
• Only difference is body-content element
– Should
Sh ld bbe scriptless
i tl i
instead
d off empty:
t
<tag>
<name>…</name>
<tag-class>
<tag class>…</tag
</tag-class>
class>
<body-content>scriptless</body-content>
</tag>
• Legal values for body-content
– empty: no body content
• Body content is ignored even if supplied
– scriptless: body content is included
• Can contain plain text, EL elements, other custom tags,
and p
page
g directives
• No explicit scripting allowed (<%= ... %>)
– tagdependent: body content is processed by tag
28
29
Using heading Tag
…
<BODY>
<%@ taglib uri="/WEB-INF/tlds/csajsp-taglib.tld"
prefix="csajsp" %>
<csajsp:heading align="LEFT" bgColor="CYAN"
border="10" fgColor="BLACK"
font="Arial Black" size="78">
First Heading
</csajsp:heading>
<csajsp:heading align="RIGHT" bgColor="RED"
border="1" fgColor="YELLOW"
font="Times New Roman" size="50">
Second Heading
</csajsp:heading>
<csajsp:heading align="CENTER" bgColor="#C0C0C0"
border="20" fgColor="BLUE"
font="Arial Narrow" size="100">
Third Heading
</csajsp:heading>
30
31
Optional Tag Bodies
• First examples
– No tag bodies
• body-content: empty
• doTag does not call invoke(null)
• Most recent examples
– Always included tag bodies
• body-content: scriptless
• doTag calls invoke(null)
• Now:
– Decide at request time whether or not to include tag body
• body-content: scriptless
• doTag conditionally calls invoke(null)
– Depending on run-time information
32
33
TLD File for DebugTag
...
<tag>
<description>
Conditionally outputs enclosed body
</description>
<name>debug</name>
<tag-class>coreservlets.tags.DebugTag</tag-class>
<b d
<body-content>scriptless</body-content>
t t> i tl </b d t t>
</tag>
...
34
36
Using a Pseudo-URI
Instead of TLD Location
Example:
p The <uri> Tag
g
• TLD File • JSP (Approach 1)
– In
I WEB
WEB-INF/tlds/file.tld
INF/ ld /fil ld <%@ t
taglib
lib
uri="/WEB-INF/tlds/file.tld"
<?xml ... ?> prefix="myPrefix" %>
<taglib ...> ...
<uri> <myPrefix:myTag/>
http://foo.com/bar ...
</uri>
• JSP (A
(Approach
h 2)
<tag> <%@ taglib
<name>myTag</name> uri="http://foo.com/bar"
<tag-class>...</tag-class>
g g prefix="myPrefix"
prefix myPrefix %>
<body-content> ...
empty or scriptless <myPrefix:myTag/>
</body-content> ...
</tag>
</taglib>
39
© 2010 Marty Hall
JSP-Based Tags
((Tag
g Files))
Tag Files:
Custom Tags Using JSP Syntax
• Two Approaches
– When there is lots of logic, use Java to create output
• Analagous to when you use servlets
– When there is lots of formatting,
formatting use JSP to create output
• Analagous to when you use JSP pages
• Pros
– Very good for complex text formatting
– Very concise
• Cons
C
– Not good for complicated logic
– Runs only in JSP 22.0
0 and later
• Java-based versions had “classic” syntax that worked in
older servers (e.g., BEA WebLogic 8.1, Oracle 9i AS)
41
Simple Standalone Tags
• Java-based approach requires three pieces
– Java code that overrides doTag to generate output
• Strengths and weaknesses generally similar to those of
servlets,, but more cumbersome
– Tag Library Descriptor (TLD) file that maps Java class
name to tag name
– JSP page th
thatt refers
f tto specific
ifi llocation
ti off TLD file
fil
• JSP-based approach requires two pieces
– JSP code (tag file) that shows result
• /WEB-INF/tags/someName.tag
– No TLD file: tag name taken from tag-file name
– JSP page that refers to directory containing tag file
• /WEB-INF/tags or a subdirectory thereof
42
Tag
g Files
• Look just like regular JSP files, except
– Must bbe llocated
M d iin (or
( under)
d ) WEB-INF/tags
WEB INF/
– Must be named blah.tag, not blah.jsp
– You use <%@ tag ... %> instead of <%@ page ... %>
– You use predefined variable jspContext instead of pageContext
• But you can cast it to PageContext
• Other variables (request, response, etc.) are the same
• Example
WEB-INF/tags/date.tag some-page.jsp
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
p
import j
java.io.*;
import java.math.*;
import coreservlets.Primes;
public
bli void
id doTag()
d T () th
throws J
JspException,
E ti IOE
IOException
ti {
JspWriter out = getJspContext().getOut();
BigInteger prime =
Primes nextPrime(Primes random(length));
Primes.nextPrime(Primes.random(length));
out.print(prime);
}
44 }
<tag>
<description>Outputs 50-digit primes</description>
<name>simplePrime</name>
<tag-class>coreservlets.tags.SimplePrimeTag</tag-class>
<body-content>empty</body-content>
</tag>
...
</taglib>
45
Java-Based Tags: Usage in JSP
(Simple Standalone Tag)
...
<BODY>
<H1>Some 50-Digit Primes</H1>
<%@ taglib uri="/WEB-INF/tlds/csajsp-taglib.tld"
prefix="csajsp" %>
<UL>
<LI><csajsp:simplePrime/>
<LI><csajsp:simplePrime/>
<LI><csajsp:simplePrime/>
<LI><
<LI><csajsp:simplePrime/>
j i l P i />
</UL>
</BODY></HTML>
46
47
Tag Files: Tag Code
(Simple Standalone Tag)
• WEB-INF/tags/simplePrime2.tag
– Directory name is not arbitrary; must be in
/WEB-INF/tags or a subdirectory thereof
<%= coreservlets.Primes.nextPrime
(coreservlets.Primes.random(50)) %>
48
49
Tag Files: Result
(Simple Standalone Tag)
50
52
53
Java-Based Tags: Usage in JSP
(Tag with Attributes)
…
<BODY>
<H1>Some N-Digit Primes</H1>
<%@ taglib uri="/WEB-INF/tlds/csajsp-taglib.tld"
prefix="csajsp" %>
<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):
g ) <csajsp:prime
j p p /
/>
</UL>
</BODY></HTML>
54
55
Tag Files: Tag Code
(Tag with Attributes)
<%@ attribute name="length" required="false" %>
<%
int len = 50;
try {
len = Integer.parseInt(length);
} catch(NumberFormatException nfe) {}
%>
<%= coreservlets.Primes.nextPrime
(coreservlets.Primes.random(len)) %>
56
57
Tag Files: Results
(Tag with Attributes)
58
• JSP
JSP-based
based tags (tag files)
– Use <jsp:doBody/> to output tag body
– No major syntax changes
– Access to attributes still much simpler
59
Java-Based Tags: Code
(Tag with Body)
public class HeadingTag extends SimpleTagSupport {
private String
p g align;
g
private String bgColor;
private String border;
private String fgColor;
private String font;
private String size;
61
Java-Based Tags: TLD File
(Tag with Body)
...
<tag>
g
<description>Formats enclosed heading</description>
<name>heading</name>
<tag-class>coreservlets.tags.HeadingTag</tag-class>
<body content>scriptless</body content>
<body-content>scriptless</body-content>
<attribute>
<name>align</name>
<required>true</required>
</attribute>
<attribute>
<name>bgColor</name>
<required>true</required>
</attribute>
...
</tag>
62
64
67
© 2010 Marty Hall
Wrap-Up
Questions?