You are on page 1of 115

08/01/2006

JSP 1.2 Custom Tags


1

In this session, we will look into how to build and deploy custom tags based on JSP 1.2. Later, in a separate session, we will talk about newly introduced custom tag features in JSP 2.0.

08/01/2006

Disclaimer & Acknowledgments


?

Even though Sang Shin is a full-time employees of Sun Microsystems, the contents here are created as his own personal endeavor and thus does not reflect any official stance of Sun Microsystems. Sun Microsystems is not responsible for any inaccuracies in the contents. Acknowledgements The slides, speaker notes, and example code of this presentation are created from ? Core Servlets and JavaServer Pages book written by Marty Hall
?

Custom Tags section of Java WSDP 1.2 tutorial written by Stephanie Bodoff of Sun Microsystems

Many slides are borrowed from Sevlet/JSP codecamp material authored by Doris Chen of Sun Microsystems
2

08/01/2006

Revision History
? ?

10/13/2003: version 1: created by Sang Shin Things to do speaker notes need to be added and polished some concepts need to be explained better advanced usage scenarios (tag variables, listener, etc in JSP 1.2) still need to be discussed how does it work part needs to be polished up a bit

08/01/2006

Agenda I
? ? ?

Evolution of Web-tier technology What is and why custom tags? Components that make up custom tag architecture How to build, configure, and deploy custom tag library? How does it work?
4

08/01/2006

Agenda II
?

Usage scenarios of custom tags (in the increasing order of complexity)


Defining a tag without attributes or tag bodies Assigning attributes to tags Including tag body Optionally including tag body Manipulating tag body Including or manipulating tag body multiple times Using nested tags
5

The majority of this session is devoted to explain usage scenarios of custom tags in increasingly order of complexity. For example, we will define first simplest tag which does not have any attributes nor tag bodies. Then we will create a tag that receive attributes from the calling JSP page. Then we will create a tag that includes a tag body. Next we will see how we can create a tag that can optionally include tag body depending on some business logic or input parameter. Next we will build a tag that manipulates and modify the tag body. And then we will see how we can include or manipulate tag body multiple times. Finally we will see how we can use nested tags.

08/01/2006

Evolution of Web tier technology


6

OK, let's talk about where JSP fits in from a big picture perspective of J2EE architecture.

08/01/2006

Web Application Designs

This picture shows the evolution of web application starting from a simplest one which then evolves into more sophisticated and more robust design. So in the first phase of the evolution, just static HTML pages were used to display static information. Then in the subsequent evolution phase, dynamic contents generation technologies such as CGI initially, then servlet and JSP are introduced to generate and display dynamic contents along with static contents. When you are using JSP pages, you can use only the basic features that come with it. Or you can leverage more sophisticated features such as component-based dynamic contents generation, for example, leveraging JavaBeans or custom tags, which provide more reusable, more maintainable, more flexible development and deployment options. Then in a more sophisticated environment, people use so-called template based design or eventually they might want to delegate their business logic processing to EJB tier.

08/01/2006

Where does custom tags fit in?

This picture shows how custom tags fit into the Web application architecture. Typically HTTP requests coming from the client are handled by the centralized controller, which in turn forwards them to JSP pages. The JSP pages then call server side objects for business logic processing. These server side objects can be either in the form of Java Beans or custom tags.

08/01/2006

Standard Action Tags (or Tags)


?

<jsp:useBean>
Instantiate JavaBean object

<jsp:getProperty>
Allow accessing bean properties

<jsp:setProperty>
Allow setting bean properties

Now JSP container already provides simple but standard tags that allows JSP page designer to set and get properties of Java Beans instances. For example, the <jsp:useBean> tag instantiates Java Bean class without forcing page designers to use Java programming language. And <jsp:getProperty> and <jsp:setProperty> allows page designers to access and set properties of Java Bean instances.

08/01/2006

Standard Action Tags (or Tags)


?

<jsp:forward>
Forwards request to another HTML page, JSP, or servlet

<jsp:include>
Includes output of another JSP file

<jsp:plugin>
Downloads Java plugin to browser to execute applet or bean

10

JSPalso provides standard tags for forwarding and including other JSP pages. <jsp:forward> tag forward request to other Web components while <jsp:include> includes data in a JSP page from another file. And <jsp:plugin> instructs the container to download Java plug-in to the browser to execute applet or bean.

10

08/01/2006

What is a Custom Tag?


11

Now let's talk about what custom tag is.

11

08/01/2006

What is a Custom Tag?


?

? ?

User defined JSP language elements (as opposed to standard tags) Encapsulates recurring tasks Distributed in a custom made tag library

12

Custom tags are user-defined JSP language elements that encapsulate recurring tasks. Custom tags are distributed in a tag library, which defines a set of related custom tags and contains the objects that implement the tags.

12

08/01/2006

Custom Tags Can


? ? ? ?

Be customized via attributes passed from the calling JSP page Pass variables back to the calling page Access all the objects available to JSP pages Communicate with each other

You can create and initialize a JavaBeans component, create a public EL variable that refers to that bean in one tag, and then use the bean in another tag

Be nested within one another and communicate via private variables


13

Custom tags have a rich set of features. They can * Be customized via attributes passed from the calling page. * Pass variables back to the calling page. * Access all the objects available to JSP pages. * Communicate with each other. You can create and initialize a JavaBeans component, create a public EL variable that refers to that bean in one tag, and then use the bean in another tag. * Be nested within one another and communicate via private variables.

13

08/01/2006

Custom Tag Examples


? ? ? ? ? ?

Getting/setting Implicit objects Processing forms Accessing database Flow control Iterations Many more

14

The standard JSP tags simplify JSP page development and maintenance. JSP technology also provides a mechanism for encapsulating other types of dynamic functionality in custom tags, which are extensions to the JSP language. Some examples of tasks that can be performed by custom tags include operations on implicit objects, processing forms, accessing databases and other enterprise services such as e-mail and directories, and flow control.

14

08/01/2006

Ready-to-usable Custom Tag Library


?

Java Standard Tag Library (JSTL)


Tags for setting/getting attributes, iteration, etc Tags for database access Tags for internationalized formatting Tags for XML

Jakarta-Taglibs

15

Now there are ready to usable custom tag libraries. They are Java Standard Tag Library (JSTL), which contains custom tags for setting and getting attributes, handles iterations, and so on. It also contains tags for database access, tags for internationalized formatting and tags for XML manipulation. Also Jakarta tag library from Apache has been quite popular.

15

08/01/2006

Why Custom Tags?


16

Now let's talk about why you want to use custom tags.

16

08/01/2006

Why Custom Tags?


?

Separate presentation from business (and other functionality) logic


page authors author presentation Business logic developers create custom tags

Encapsulate business logic


Reusable & Maintainable

Help page authors


Page authors use simpler syntax

Provide
Portable semantics
17

Custom tags separate presentation from business logic in that page content is created by page designers while the business logic's are captured in the form of custom tags. Now custom tags is not just for business logic but it can encapsulate other relatively complex functionality such as complex display, iteration, formatting and so on. Because custom tags encapsulate business logic, they are reusable and easier to maintain. In fact, in most cases, you will use custom tags that are created by someone else. Because custom tags hide complexity from page authors, it is easier to author pages. And there are many tools that support custom tags. Custom tags provide portable semantics.

17

08/01/2006

Custom Tags against JavaBeans


?

Pros

Custom tags can manipulate JSP contents while beans cannot Complex operations can be reduced to a significantly simpler form with custom tags than beans Custom tags require quite a bit of more work to set up than do beans

Cons

source: more Servlets and JSP[2]

18

(read the slide)

18

08/01/2006

Quick Introduction on Components that make up Custom tag architecture (in JSP 1.2)
19

Now let's me give you a quick introduction on 3 components that make up custom tag architecture.

19

08/01/2006

Three things make up custom tag architecture


?

Tag handler class

Defines tag's behavior Maps XML elements to tag handler class Uses tags

Tag library descriptor (TLD)

JSP file (user of custom tags)

20

To use a custom tag in a JSP page, you must: * Declare the tag library containing the tag before the usage of any custom tags from that tag library * Use custom tags using custom tag syntax in a JSP page It is assumed that the tag library has been configured and deployed with individual Web application or globally for all Web applications running on the server.

20

08/01/2006

Steps for implementing & using & deploying custom tags


?

Implementing custom tags


Write tag handlers Write Tag library descriptor (TLD) file Package tag handlers and TLD file into tag library (either unpacked or packed form) Write JSP pages that use tags Configure and deploy tag library along with JSP pages
21

Using custom tags

Deploying custom tags as part of web app

The steps you follow in order to implement and deploy custom tags are relatively straight-forward. First, you write tag handlers. Under JSP 1.2 architecture, tag handlers are Java classes. Second, you write so called tag library descriptor, TLD file, in short. Third, you package a set of tag handlers and TLD file into what is called tag library in either unpacked or packed form. Then, you write JSP pages that use these tags. Then you deploy the tag library along with JSP pages. Now let's talk about 3 things here by using examples - tag handler, TLD file, and JSP pages.

21

08/01/2006

Tag handler class


?

Implements interface

javax.servlet.jsp.tagext.Tag or javax.servlet.jsp.tagext.Bodytag interface javax.servlet.jsp.tagext.TagSupport or javax.servlet.jsp.tagext.BodyTagSupport class

Usually extends utility class


Located in the same directory as servlet class files

/WEB-INF/classes/<package-directory-structure>
22

First, tag handler class. Tag handler class implement Tag interface or Bodytag interface. If you are writing your tag handler from scratch, you will typically extend utility classes, TagSupport or BodyTagSupport classes, which are implementation of the interfaces with some built-in set up functions. As you will learn later on, you will choose to use either TagSupport or BodyTagSupport class depending on whether you need to manipulate or modify the body content. (By the way, by body content, I mean the JSP fragment that reside between starting tag and ending tag.) The tag handler classes are normal Java classes that reside under /WEBINF/classes. The classes should follow normal package directory structure.

22

08/01/2006

Example: Tag Handler (page 1) ExampleTag.java


package moreservlets.tags; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; /** Very simple JSP tag that just inserts a string * ("Custom tag example...") into the output. * The actual name of the tag is not defined here; * that is given by the Tag Library Descriptor (TLD) * file that is referenced by the taglib directive * in the JSP file. * <P> * Taken from More Servlets and JavaServer Pages * from Prentice Hall and Sun Microsystems Press, * http://www.moreservlets.com/. * &copy; 2002 Marty Hall; may be freely used or adapted. */
23

This is the simplest tag handler, ExampleTag.java, from Marty Hall's sample code you can download free. The package structure is ./ moreservlets.tags.ExampleTag.class.

23

08/01/2006

Example: Tag Handler (page 2) ExampleTag.java


public class ExampleTag extends TagSupport { public int doStartTag() { try { JspWriter out = pageContext.getOut(); out.print("Custom tag example " + "(moreservlets.tags.ExampleTag)"); } catch(IOException ioe) { System.out.println("Error in ExampleTag: " + ioe); } return(SKIP_BODY); } }

24

The ExampleTag class extends TagSupport class. It does include doStartTag() method in which you get JspWriter object which you get from pageContext object. Since the ExampleTag does not include nor manipulate body contents, it returns SKIP_BODY. (We will talk about this again later on.)

24

08/01/2006

Tag Library Descriptor (TLD)


?

XML file that describes


tag name bodycontent attributes tag handler class

Container knows which tag is associated with which tag handler class via this file Located

Usually under WEB-INF directory Via uri attribute of taglib directive

Custom location can specified in JSP file

25

Once you create a set of tag handlers, which can be packaged into a single tag library, then you are ready to create a corresponding Tag Library Descriptor, TLD file. TLD file is an XML file that describes each tag with tag name, information on how body content should be handled, information on attributes, and full path of tag handler class. The web container knows which tag is associated with which tag handler class via this file. The TLD file can be located in any place such as the same directory of JSP pages, but normally you want to keep the TLD file under /WEB-INF directory. And this location is specified in the uri attribute of taglib directive. So let's take a look an example.

25

08/01/2006

Example: TLD (page 1) msajsp-tags.tld


<?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"> <!-- a tag library descriptor --> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>msajsp-tags</shortname> <info> A tag library from More Servlets and JavaServer Pages, http://www.moreservlets.com/. </info>
26

This is the starting page of the msajsp-tags.tld file for all the tag handler examples from Marty Hall's sample code. Here in this example, this TLD file is based on JSP 1.1 as indicated by <jspversion> tag, which will be understood by JSP 1.2 container.

26

08/01/2006

Example: TLD (page 2) msajsp-tags.tld


<tag> <name>example</name> <tagclass>moreservlets.tags.ExampleTag</tagclass> <bodycontent>empty</bodycontent> <info>Simplest example: inserts one line of output</info> </tag> <tag> <name>simplePrime</name> <tagclass>moreservlets.tags.SimplePrimeTag</tagclass> <bodycontent>empty</bodycontent> <info>Outputs a random 50-digit prime.</info> </tag> ... </taglib>
27

This is continuation of the TLD file. In this page, you can see descriptions on two tag handlers, ExampleTag.class and SimplePrimeTag. Since both tag handlers do not include nor manipulate the body content, the <bodycontent> element is set to empty.

27

08/01/2006

What is Tag Library?


?

Is a collection of related tags

Tag(s) can be packaged in a Tag Library

Typically packaged as a jar file containing


A tag library descriptor (TLD) e.g. META-INF/taglib.tld *.class files for the tag handler class(es) Any additional associated resource(s)

28

We already talked about tag library. A tag library is a collection of related tags. It is a customary that you package related tags into a single tag library. A tag library is typically packaged as a jar file which contains TLD file along with tag handler classes and any related classes. When a tag library is packaged as a jar file, the TLD file should reside under META-INF directory and the tag handler classes should reside under classes directory.

28

08/01/2006

JSP page
? ?

Declare the tag library via taglib directive Use tags using custom tag syntax

29

To use a custom tag in a JSP page, you must: * Declare the tag library containing the tag before the usage of any custom tags from that tag library * Use custom tags using custom tag syntax in a JSP page It is assumed that the tag library has been configured and deployed with individual Web application or globally for all Web applications running on the server.

29

08/01/2006

Declaring a tag library


? ?

Include taglib directive before tags are used Syntax


<%@ taglib prefix="myprefix" uri=myuri %> prefix: identifies the tag library uri: uniquely identifies the tag library descriptor (TLD) directly or indirectly

30

You declare that a JSP page will use tags defined in a tag library by including a taglib directive in the page before any custom tag from that tag library is used. If you forget to include the taglib directive for a tag library in a JSP page, the JSP compiler will treat any invocation of a custom tag from that library as template data, and simply insert the text of the custom tag call into the response. The syntax of taglib directive is as following: <%@ taglib prefix="tt" uri=URI %> The prefix attribute defines the prefix that distinguishes tags defined by a given tag library from those provided by other tag libraries. The tagdir attribute specifies the location of tag files. And uri attribute uniquely identifies the tag library descriptor (TLD) either directly or indirectly.

30

08/01/2006

Custom Tag Syntax in a JSP page


<prefix:tag attr1="value" ... attrN="value" /> or <prefix:tag attr1="value" ... attrN="value" > body </prefix:tag> prefix: distinguishes tag library tag: identifies a tag (within the tag library) attr1 ... attrN: modify the behavior of the tag
31

Custom tags have the syntax <prefix:tag attr1="value" ... attrN="value" /> or <prefix:tag attr1="value" ... attrN="value" > body </prefix:tag> where prefix distinguishes tags for a library, tag is the tag identifier, and attr1 ... attrN are attributes that modify the behavior of the tag.

31

08/01/2006

Example: JSP page SimpleExample.jsp


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-Illustration of very simple JSP custom tag. Taken from More Servlets and JavaServer Pages from Prentice Hall and Sun Microsystems Press, http://www.moreservlets.com/. (C) 2002 Marty Hall; may be freely used or adapted. --> <HTML> <HEAD> <%@ taglib uri="/WEB-INF/msajsp-taglib.tld" prefix="msajsp" %> <TITLE><msajsp:example /></TITLE> <LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <BODY> <H1> <msajsp:example /></H1> <msajsp:example /> </BODY> </HTML>

32

This is the SimpleExample.jsp page which uses the tags. Here it declares the tag library it wants to use first through <% taglib .. %> directive. The location of the TLD file is specified via uri attribute and the prefix is set to msajsp. In this example, the TLD file, msajsp-taglib.tld file, resides under /WEB-INF directory. As for the usage of example tag, it is used twice in this JSP page. Now let's see the result of accessing this JSP page in the following slide.

32

08/01/2006

Example: Accessing SimpleExample.jsp

33

This picture shows when the JSP page in the previous slide is accessed.

33

08/01/2006

How to build, configure and deploy tag library

34

OK. Since you get some big picture on how custom tags are working, let's see how you can build, configure and deploy tag library from a developer standpoint.

34

08/01/2006

Source Directory Structure


?

Use the following source directory structure (as in J2EE 1.4 Tutorial's web/iterator directory)

<j2ee14tutorial-install>/j2eetutorial14/examples/web ? iterator build.xml (ant build file) src (dir where *.java files with proper package structure reside) web (dir) ? WEB-INF (dir) ? *.tld ? tags (dir - needed for JSP 2.0 tag files) ? *.jsp
35

First, let's see what would be a desired source directory structure. Of course, how you structure your development directory structure is dependent on individual taste, a recommended approach is to have separate the source tree from the build/deployment tree. And that is what Java WSDP tutorial code is structured and that is what we will use here as well. Java WSDP 1.2 has iterator custom tag and it comes with ant build.xml file. So for our custom tag development, we will have a source directory structure mentioned in the slide. That is, build.xml is in the top directory. And we will have src directory which contains *.java source files. And the web directory has WEB-INF subdirectory which will contain the TLD file and JSP files will be under web directory.

35

08/01/2006

Build Directory Structure (under build or dist directory)


?

Use the following build directory structure (as in J2EE 1.4 Tutorial's web/iterator directory)

<j2eetutorial14-install>/j2eetutorial14/examples/web ? iterator build (unpacked *.war file) dist (packed *.war file)

36

OK, now let's see what would be the build directory structure. We will have build directory and dist directory. The build directory will reflect the unpacked form of the custom tag library while the dist directory contains the *.jar file.

36

08/01/2006

Usage Scenarios of Custom Tags (in JSP 1.2)


37

Now we will spend the rest of the class talking about usage scenarios of custom tags. These are from Marty Hall's book. I decided to use his approach of explaining custom tags since he explains the custom tags by explaining the most simple one first and then gradually move up the ladder with more sophisticated usage of custom tags.

37

08/01/2006

Usage Scenarios of Custom Tags


?

Defining a basic tag

A tag without attributes or tag bodies

? ? ? ? ?

Assigning attributes to tags Including tag body Optionally including tag body Manipulating tag body Including or manipulating tag body multiple times Using nested tags
38

So Marty deals with the usage scenarios of custom tags as mentioned in this slide. This set of usage scenarios are for both JSP 1.1 and JSP 1.2. He also explained newly introduced features of custom tags in JSP 1.2 in later chapter of his book, more Servlets and JSP.

38

08/01/2006

Usage Scenarios of Custom Tags


? ? ?

Bundling listeners with tag libraries Checking syntax with TagLibraryValidator Handling Exceptions with TryCatchFinally interface Looping without generating BodyContent

39

So this is the list of custom tag features and usage scenarios that are newly supported in JSP 1.2.

39

08/01/2006

Defining a basic tag (We already saw an example.)


40

So let's start with the most simple tag usage scenario and we will call this as a basic tag.

40

08/01/2006

Defining a basic tag


? ? ?

A tag without attributes or body Extend TagSupport class All you have to do is to override doStartTag () method

doStartTag() method defines code that gets called at request time at the place where the element's start tag is found doStartTag() returns SKIP_BODY since the tag does not have a body
?

It instructs the container to ignore any body content between start and end tags
41

Basic tag is a tag that does not have attribute nor body content. Since we do not manipulate or modify body content, the tag handler simply extends the TagSupport class. Now in order to display whatever you want to display to the client, the only method you have to override is doStartTag(). We will spend some time later on tag handler methods later on but it is important for you to understand when these methods are invoked by the container. The doStartTag() method gets called at request time. That is, when a client accesses the JSP page (actually servlet code) which contains tags, what happens behind the scene is that when the opening tag is encountered by the container, the container invokes the doStartTag() method of the tag handler. Now in this example, the doStartTag() method just returns SKIP_BODY since, in this simplest usage scenario, the tag either does not contain the body content or want to ignore the body content. By returning SKIP_BODY, the tag handler basically instructs the container to ignore any body content.

41

08/01/2006

Assigning attributes to tags

42

Next, let's move on to the next usage example. In this example, we will see how to assign attributes to tags.

42

08/01/2006

Why assigning attributes to tags?


?

Provides a way to pass attribute/value pairs from JSP pages to custom tag handlers Custom tag handlers can use them in whatever business logic they have

43

Now why do you assign attributes to tags? The reason is rather simple, you want to provide a way to pass attribute/value pairs from the calling JSP pages to the tag handlers. And the tag handlers can use them in whatever business logic they have.

43

08/01/2006

Tag handler class


?

Use of an attribute X in a JSP page results in a call to a method setX() in the tag handler class

Tag handler must implement setX() method


public void setX(String value1){ doSomethingWith(value1); }

44

Now let's see how attribute/value pairs specified in the JSP pages are passed to the tag handler. The mechanism is rather simple. Whenever attribute X/value pairs are encountered in the JSP page, the container invokes setX() in the tag handler class. What this means is that the tag handler must implement setX () method. For example, if there is attribute X=value1 in the opening tag element, the tag handler is expected to have setX(String value1) method.

44

08/01/2006

Example: Tag Handler (page 1) SimplePrimeTag.java


import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; import java.math.*; import moreservlets.*; /** Generates a prime of approximately 50 digits. * (50 is actually the length of the random number * generated -- the first prime above that number will * be returned.) * <P> * Taken from More Servlets and JavaServer Pages * from Prentice Hall and Sun Microsystems Press, * http://www.moreservlets.com/. * &copy; 2002 Marty Hall; may be freely used or adapted. */
45

So let's see an example tag handler, SimplePrimeTag.java, that contains setX() method. This code is actually made of two tag handler classes. The first one is SimplePrimeTag.java and the other one is PrimeTag.java which extends SimplePrimeTag.java.

45

08/01/2006

Example: Tag Handler (page 2) SimplePrimeTag.java


public class SimplePrimeTag extends TagSupport { protected int len = 50; public int doStartTag() { try { JspWriter out = pageContext.getOut(); BigInteger prime = Primes.nextPrime(Primes.random(len)); out.print(prime); } catch(IOException ioe) { System.out.println("Error generating prime: " + ioe); } return(SKIP_BODY); } }

46

This is SimplePrimeTag.java. Here we have a variable called len, which will be set by the setLength() method. The default value is set to 50. This example code basically computes a prime number using the length as as the length of the random number. Now some point, you might want to change the length of the random number from the calling JSP page.

46

08/01/2006

Example: Tag Handler (page 3) PrimeTag.java


package moreservlets.tags; /** Generates an N-digit random prime (default N = 50). * Extends SimplePrimeTag, adding a length attribute * to set the size of the prime. The doStartTag * method of the parent class uses the len field * to determine the length of the prime. * <P> * Taken from More Servlets and JavaServer Pages * from Prentice Hall and Sun Microsystems Press, * http://www.moreservlets.com/. * &copy; 2002 Marty Hall; may be freely used or adapted. */

47

This is PrimeTag.java which extends SimplePrimetag.java.

47

08/01/2006

Example: Tag Handler (page 4) PrimeTag.java


public class PrimeTag extends SimplePrimeTag { public void setLength(String length) { try { len = Integer.parseInt(length); } catch(NumberFormatException nfe) { len = 50; } } /** Servers are permitted to reuse tag instances * once a request is finished. So, this resets * the len field. */ public void release() { len = 50; } }
48

Here the length can be set via setLength() method. So if the calling page contains length=60, this method will be called with length set to String value to 60.

48

08/01/2006

TLD
?

Attributes must be declared inside tag element by means of attribute sub-elements Attribute element has 5 sub-elements of its own

name (required) required (required) rtexprvalue (optional) type (optional) example (optional)

49

Now how does the container knows that the calling JSP page could pass attribute/value pairs to the tag handler? This is where TLD file comes into the picture. That is, the attribute must be declared inside the tag element by means of attribute sub-element. Now the attribute subelement has its own subelements as mentioned in the slide above that specify the characteristics of the attribute. The name element is a required subelement and specifies the name of the attribute. The required element is a required subelement and specifies whether it is a mandatory element or not. That is, if specified with true, the calling page must to have the attribute. Now rtexprvalue and type elements are optional and deserves a bit detailed explanation. So let's do that in the following slides.

49

08/01/2006

TLD: Attribute's rtexprvalue/type subelements


?

rtexprvalue (optional)

true if attribute value can be <%= expression %>


?

attribute value can be determined at request time

false if attribute value is a fixed string (default) specifies the class to which the value of the rtexprvalue should be typecast only legal when rtexprvalue is set to true

type (optional)

50

If rtexprvalue element is set to true, the attribute value be set as an expression. That is, the attribute value can be determined at request time. By request time, I mean the time the JSP page is being accessed by HTTP request. You can consider the request time as runtime equivalent. If it is set to false, the value is considered as String type and this is the default. The type element when specified specifies the type (in the form of a Java class) that the resulting value of the expression that is specified with rtexprvalue is to be typecasted. So the type element is legal only when rtexprvalue is set to true.

50

08/01/2006

Example: TLD (page 1)


<?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"> <!-- a tag library descriptor --> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>msajsp-tags</shortname> <info> A tag library from More Servlets and JavaServer Pages, http://www.moreservlets.com/. </info>

51

So let's take a look at an example of TLD file. The first page looks the same.

51

08/01/2006

Example: TLD (page 2)


... <tag> <name>prime</name> <tagclass>moreservlets.tags.PrimeTag</tagclass> <bodycontent>empty</bodycontent> <info>Outputs a random N-digit prime.</info> <attribute> <name>length</name> <required>false</required> </attribute> </tag> ... </taglib>

52

Here the PrimeTag tag handler accepts an attribute called length. And the required element is set to false, which means this attribute is optional.

52

08/01/2006

Example: JSP Page (PrimeExample.jsp)


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-- Illustration of PrimeTag tag. Taken from More Servlets and JavaServer Pages from Prentice Hall and Sun Microsystems Press, http://www.moreservlets.com/.(C) 2002 Marty Hall; may be freely used or adapted. --> <HTML> <HEAD> <TITLE>Some N-Digit Primes</TITLE> <LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <BODY> <H1>Some N-Digit Primes</H1> <%@ taglib uri="/WEB-INF/msajsp-taglib.tld" prefix="msajsp" %> <UL> <LI>20-digit: <msajsp:prime length="20" /> <LI>40-digit: <msajsp:prime length="40" /> <LI>60-digit: <msajsp:prime length="60" /> <LI>Default (50-digit): <msajsp:prime /> </UL> </BODY> 53 </HTML>

This slide shows the calling JSP page. Here again, the tag library is declared with taglib directive first. Then the tag is called 4 times, three of which has length attribute set to 20, 40, 60, and the last one with a default. Please note that the values 20, 40, 60 are passed as String type instead of Integer type since rtexprvalue and type is not set in the TLD file. And that is why the setLength() method has to change the String type to Integer type.

53

08/01/2006

Example: Accessing PrimeExample.jsp

54

This is the result of accessing PrimeExample.jsp page of the previous slide.

54

08/01/2006

Including Tag Body

55

So far in the past two use scenarios, we have not dealt with body content. Now let's move to the next level. This time, we will see how body content can be included (or sometimes called evaluated).

55

08/01/2006

Including Tag body


? ? ?

<prefix:tagname>body</prefix:tagname> Body content contains typical JSP constructs JSP constructs inside of body content get translated at page translation time In this usage pattern, we are just including body content without any modification

56

By the way, by body content, I mean the JSP fragment between the starting tag and ending tag. For example, if you have <prefix:tagname>body</prefix:tagname> in the calling JSP page, the body content here is body. The body content contains typical JSP constructs. And these JSP constructs inside the body content get translated at page translation time, that is, at the time, the JSP page gets translated into servlet code, which typically happens when JSP pages are loaded into the system (as opposed to request time at which actual tag handler code is being invoked.) In this use scenario, we are just including the body content without any manipulation or modification.

56

08/01/2006

Tag handler class


?

doStartTag() method should return EVAL_BODY_INCLUDE doEndTag() gets called after body is evaluated

return EVAL_PAGE for continued processing return SKIP_PAGE for aborting processing rest of the page

57

In this use case scenario, the doStarttag() method should return EVAL_BODY_INCLUDE. Otherwise, the container will skip evaluating the content. Now in addition to doStartTag() method that gets invoked by the container when the starting tag is encountered, you also want to override doEndTag() method after the body is evaluated. Here you return EVAL_PAGE for continued processing or SKIP_PAGE for aborting processing the rest of the JSP page.

57

08/01/2006

Example: Tag Handler (page 1) HeadingTag.java


package moreservlets.tags; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; /** Generates an HTML heading with the specified background * color, foreground color, alignment, font, and font size. * You can also turn on a border around it, which normally * just barely encloses the heading, but which can also * stretch wider. All attributes except the background * color are optional. * <P> * Taken from More Servlets and JavaServer Pages * from Prentice Hall and Sun Microsystems Press, * http://www.moreservlets.com/. * &copy; 2002 Marty Hall; may be freely used or adapted. */

58

So let's take a look at the tag handler example. This is HeadingTag.java from the Marty Hall's sample code.

58

08/01/2006

Example: Tag Handler (page 2) HeadingTag.java


public class HeadingTag extends TagSupport { private String bgColor; // The one required attribute private String color = null; private String align="CENTER"; private String fontSize="36"; private String fontList="Arial, Helvetica, sans-serif"; private String border="0"; private String width=null; public void setBgColor(String bgColor) { this.bgColor = bgColor; } public void setColor(String color) { this.color = color; } ...
59

Please note that we are still extending TagSupport since we are not manipulating or modifying the body content.

59

08/01/2006

Example: Tag Handler (page 3) HeadingTag.java


public int doStartTag() { try { JspWriter out = pageContext.getOut(); out.print("<TABLE BORDER=" + border + " BGCOLOR=\"" + bgColor + "\"" + " ALIGN=\"" + align + "\""); if (width != null) { out.print(" WIDTH=\"" + width + "\""); } out.print("><TR><TH>"); out.print("<SPAN STYLE=\"" + "font-size: " + fontSize + "px; " + "font-family: " + fontList + "; "); if (color != null) { out.println("color: " + color + ";"); } out.print("\"> "); // End of <SPAN ...> } catch(IOException ioe) { System.out.println("Error in HeadingTag: " + ioe); } return(EVAL_BODY_INCLUDE); // Include tag body }

60

This is doStartTag() method. Here we spit out various HTML tags that create starting part of table and then return EVAL_BODY_INCLUDE, which instructs the container to include the body content after that.

60

08/01/2006

Example: Tag Handler (page 4) HeadingTag.java


public int doEndTag() { try { JspWriter out = pageContext.getOut(); out.print("</SPAN></TABLE>"); } catch(IOException ioe) { System.out.println("Error in HeadingTag: " + ioe); } return(EVAL_PAGE); // Continue with rest of JSP page } }

61

After body content is written, the ending part of table HTML tags are written out via doEndTag() method. Since doEndTag() method returns EVAL_PAGE, the container continues processing with rest of the JSP page.

61

08/01/2006

TLD
?

The bodycontent element should contain the value JSP

<bodycontent>JSP</bodycontent>

62

The bodycontent element now must contain the value JSP instead of empty.

62

08/01/2006

Example: TLD
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE ...> <taglib> ... <tag> <name>heading</name> <tagclass>moreservlets.tags.HeadingTag</tagclass> <bodycontent>JSP</bodycontent> <info>Outputs a 1-cell table used as a heading.</info> <attribute> <name>bgColor</name> <required>true</required> <!-- bgColor is required --> </attribute> <attribute> <name>color</name> <required>false</required> </attribute> ...

63

This is an example TLD for the HeadingTag.

63

08/01/2006

Example: JSP Page (HeadingExample.jsp)


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-Illustration of HeadingTag tag. Taken from More Servlets and JavaServer Pages from Prentice Hall and Sun Microsystems Press, http://www.moreservlets.com/. (C) 2002 Marty Hall; may be freely used or adapted. --> <HTML> <HEAD> <TITLE>Some Tag-Generated Headings</TITLE> </HEAD> <BODY> <%@ taglib uri="/WEB-INF/msajsp-taglib.tld" prefix="msajsp" %> <msajsp:heading bgColor="#C0C0C0"> Default Heading </msajsp:heading> <P> <msajsp:heading bgColor="BLACK" color="WHITE"> White on Black Heading </msajsp:heading> 64

This is the calling JSP page. Here we call the heading tag with multiple times with different body content.

64

08/01/2006

Example: JSP Page (HeadingExample.jsp)


<P> <msajsp:heading bgColor="#EF8429" fontSize="60" border="5"> Large Bordered Heading </msajsp:heading> <P> <msajsp:heading bgColor="CYAN" width="100%"> Heading with Full-Width Background </msajsp:heading> <P> <msajsp:heading bgColor="CYAN" fontSize="60" fontList="Brush Script MT, Times, serif"> Heading with Non-Standard Font </msajsp:heading> </BODY> </HTML>

65

This is the continuation of JSP page of heading tag.

65

08/01/2006

66

This is the result of accessing the JSP page.

66

08/01/2006

Optionally Including Tag Body

67

Now let's move on to the next usage scenario - we want include body content depending on the value of the form input parameter.

67

08/01/2006

Optionally Including Tag body


?

Decision of usage of body content is decided at request time Body content is not modified

68

So in this usage scenario, decision of including body content is decided at request time (runtime) instead of translation time. Also in this usage scenario, we are not modifying the body content.

68

08/01/2006

Tag handler class


?

doStartTag() method returns either EVAL_BODY_INCLUDE or SKIP_BODY

depending on the value of some request time expression, for example

Call getRequest() from pageContext field of TagSupport

Typecast the return of getRequest() to HttpServletRequest since getRequest() returns ServletRequest type

69

So in this usage scenario, the tag hander method returns either EVAL_BODY_INCLUDE or SKIP_BODY depending on the value of the some request time expression or some business logic processing. Now how do you get hold of the HttpServletRequest object? You call getRequest() method of pageContext of TagSupport class. Now you would need to typecast the result of getRequest() method to HttpServletRequest since getRequest() returns ServletRequest type.

69

08/01/2006

Example: Tag Handler (page 1) DebugTag.java


package moreservlets.tags; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; import javax.servlet.*; /** A tag that includes the body content only if * the "debug" request parameter is set. * <P> * Taken from More Servlets and JavaServer Pages * from Prentice Hall and Sun Microsystems Press, * http://www.moreservlets.com/. * &copy; 2002 Marty Hall; may be freely used or adapted. */

70

So let's take a look at the DebugTag.java code.

70

08/01/2006

Example: Tag Handler (page 2) DebugTag.java


public class DebugTag extends TagSupport { public int doStartTag() { ServletRequest request = pageContext.getRequest(); String debugFlag = request.getParameter("debug"); if ((debugFlag != null) && (!debugFlag.equalsIgnoreCase("false"))) { return(EVAL_BODY_INCLUDE); } else { return(SKIP_BODY); } } }

71

So here the doStartTag() method returns either EVAL_BODY_INCLUDE or SKIP_BODY depending on whether there is a input parameter debug is set to true.

71

08/01/2006

Example: TLD
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE ...> <taglib> ... <tag> <name>debug</name> <tagclass>moreservlets.tags.DebugTag</tagclass> <bodycontent>JSP</bodycontent> <info>Includes body only if debug param is set.</info> </tag> ...

72

This is TLD. As is the case of previous example, the value of <bodycontent> is set to JSP.

72

08/01/2006

Example: JSP Page (DebugExample.jsp)


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-Illustration of DebugTag tag. Taken from More Servlets and JavaServer Pages from Prentice Hall and Sun Microsystems Press, http://www.moreservlets.com/. (C) 2002 Marty Hall; may be freely used or adapted. --> <HTML> <HEAD> <TITLE>Using the Debug Tag</TITLE> <LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <BODY> <H1>Using the Debug Tag</H1> <%@ taglib uri="/WEB-INF/msajsp-taglib.tld" prefix="msajsp" %> Top of regular page. Blah, blah, blah. Yadda, yadda, yadda. <P> 73

This is the first part of JSP page.

73

08/01/2006

Example: JSP Page (DebugExample.jsp)


<msajsp:debug> <B>Debug:</B> <UL> <LI>Current time: <%= new java.util.Date() %> <LI>Requesting hostname: <%= request.getRemoteHost() %> <LI>Session ID: <%= session.getId() %> </UL> </msajsp:debug> <P> Bottom of regular page. Blah, blah, blah. Yadda, yadda, yadda. </BODY> </HTML>

74

Here there is body content between starting debug tag and end tag. This bodycontent will be displayed only when there is debug input parameter set with value true at request time.

74

08/01/2006

DebugTag without debug input parameter

75

This is the case where the client does not send any debug input parameter. So the bodycontent is not displayed.

75

08/01/2006

Accessing DebugExample.jsp with debug=true input param

76

This is the case where the client is calling the JSP page setting the debug input parameter set to true. This time, the body content is displayed.

76

08/01/2006

Manipulating Tag Body

77

Now let's move on to the next usage scenario. Here we are going to see how the body content can be manipulated (modified).

77

08/01/2006

Tag handler class


?

Tag handler class should extend BodyTagSupport class BodyTagSupport class has 2 convenience methods

doAfterBody(): override this method in order to manipulate the tag body


? ?

return SKIP_BODY if no further body processing is needed return EVAL_BODY_TAG (JSP 1.1) or EVAL_BODY_AGAIN (JSP 1.2) if the body content needs to be evaluated and handled again

getBodyContent(): returns BodyContent object


78

In this usage scenario in which the body content needs to be manipualted and/or modified, the tag handler should extend BodyTagSupport class. The BodyTagSupport class provides 2 more methods - doAfterBody() and getBodyContent() method. Normally the doAfterBody() method returns SKIP_BODY to indicate that the body does not need to reevaluated.

78

08/01/2006

BodyContent class
?

? ?

An encapsulation of the evaluation of the body A subclass of JspWriter BodyContent class has 3 methods

getEnclosingWriter(): returns JspWriter getReader(): returns a Reader that can read tag body getString(): returns a String containing entire tag body

79

The BodyContent class is an encapsulation of the body. It is a subclass of JspWriter. The BodyContent class has three methods.

79

08/01/2006

Example: Tag Handler (page 1) FilterTag.java


package moreservlets.tags; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; import moreservlets.*; /** A tag that replaces <, >, ", and & with their HTML * character entities (&lt;, &gt;, &quot;, and &amp;). * After filtering, arbitrary strings can be placed * in either the page body or in HTML attributes. * <P> * Taken from More Servlets and JavaServer Pages * from Prentice Hall and Sun Microsystems Press, * http://www.moreservlets.com/. * &copy; 2002 Marty Hall; may be freely used or adapted. */
80

This is the first page of the FilterTag.java tag handler code. Skip to the next slide.

80

08/01/2006

Example: Tag Handler (page 2) FilterTag.java


public class FilterTag extends BodyTagSupport { public int doAfterBody() { BodyContent body = getBodyContent(); String filteredBody = ServletUtilities.filter(body.getString()); try { JspWriter out = body.getEnclosingWriter(); out.print(filteredBody); } catch(IOException ioe) { System.out.println("Error in FilterTag: " + ioe); } // SKIP_BODY means we're done. If we wanted to evaluate // and handle the body again, we'd return EVAL_BODY_TAG // (JSP 1.1/1.2) or EVAL_BODY_AGAIN (JSP 1.2 only) return(SKIP_BODY); } }
81

Here the FilterTag handler extends BodyTagSupport class. And the doAfterBody() method gets called by the container after the body content has been evaluated. Now the tag handler can access the evaluated body content in the form of BodyContent object by calling getBodyContent() method. And the body content can be returned in the form of String object via getString() method of the BodyContent object.

81

08/01/2006

Example: TLD
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE ...> <taglib> ... <tag> <name>filter</name> <tagclass>moreservlets.tags.FilterTag</tagclass> <bodycontent>JSP</bodycontent> <info>Replaces HTML-specific characters in body.</info> </tag> ...

82

Here the TLD file looks the same as in the cases of previous examples.

82

08/01/2006

Example: JSP Page (FilterExample.jsp)


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-Illustration of FilterTag tag. Taken from More Servlets and JavaServer Pages from Prentice Hall and Sun Microsystems Press, http://www.moreservlets.com/. (C) 2002 Marty Hall; may be freely used or adapted. --> <HTML> <HEAD> <TITLE>HTML Logical Character Styles</TITLE> <LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <BODY> <H1>HTML Logical Character Styles</H1> Physical character styles (B, I, etc.) are rendered consistently in different browsers. Logical character styles, however, may be rendered differently by different browsers. Here's how your browser (<%= request.getHeader("User-Agent") %>) renders the HTML 4.0 logical character styles: <P>

83

This is the calling JSP page. Skip to the next page.

83

08/01/2006

Example: JSP Page (FilterExample.jsp)


<%@ taglib uri="/WEB-INF/msajsp-taglib.tld" prefix="msajsp" %> <TABLE BORDER=1 ALIGN="CENTER"> <TR CLASS="COLORED"><TH>Example<TH>Result <TR> <TD><PRE><msajsp:filter> <EM>Some emphasized text.</EM><BR> <STRONG>Some strongly emphasized text.</STRONG><BR> <CODE>Some code.</CODE><BR> <SAMP>Some sample text.</SAMP><BR> <KBD>Some keyboard text.</KBD><BR> <DFN>A term being defined.</DFN><BR> <VAR>A variable.</VAR><BR> <CITE>A citation or reference.</CITE> </msajsp:filter></PRE> <TD> <EM>Some emphasized text.</EM><BR> <STRONG>Some strongly emphasized text.</STRONG><BR> <CODE>Some code.</CODE><BR> <SAMP>Some sample text.</SAMP><BR> <KBD>Some keyboard text.</KBD><BR> <DFN>A term being defined.</DFN><BR> <VAR>A variable.</VAR><BR> <CITE>A citation or reference.</CITE> </TABLE> </BODY> </HTML>

84

This JSP page contains two sets of same information.

84

08/01/2006

To be added

85

This is the result of the accessing the JSP page.

85

08/01/2006

Including or Manipulating Tag Body Multiple Times

86

The next usage scenario is to include or manipulate the body multiple times.

86

08/01/2006

Tag handler class


?

Tag handler class should extend BodyTagSupport class doAfterBody() now returns EVAL_BODY_TAG (EVAL_BODY_AGAIN in JSP 1.2)

87

The tag handler extend BodyTagSupport class. And the doAfterBody() method this time returns EVAL_BODY_TAG (under JSP 1.1) or EVAL_BODY_AGAIN (under JSP 1.2).

87

08/01/2006

Example: Tag Handler (page 1) RepeatTag.java


package moreservlets.tags; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; /** A tag that repeats the body the specified * number of times. * <P> * Taken from More Servlets and JavaServer Pages * from Prentice Hall and Sun Microsystems Press, * http://www.moreservlets.com/. * &copy; 2002 Marty Hall; may be freely used or adapted. */

88

This is the first page of RepeatTag.java. Skip to the next page.

88

08/01/2006

Example: Tag Handler (page 2) RepeatTag.java


public class RepeatTag extends BodyTagSupport { private int reps; public void setReps(String repeats) { try { reps = Integer.parseInt(repeats); } catch(NumberFormatException nfe) { reps = 1; } }

89

The tag handler has setReps() method.

89

08/01/2006

Example: Tag Handler (page 3) RepeatTag.java


public int doAfterBody() { if (reps-- >= 1) { BodyContent body = getBodyContent(); try { JspWriter out = body.getEnclosingWriter(); out.println(body.getString()); body.clearBody(); // Clear for next evaluation } catch(IOException ioe) { System.out.println("Error in RepeatTag: " + ioe); } // Replace EVAL_BODY_TAG with EVAL_BODY_AGAIN in JSP 1.2. return(EVAL_BODY_TAG); } else { return(SKIP_BODY); } }
90

The doAfterBody() keeps evaluating the body content until number of repetition is satisfied.

90

08/01/2006

Example: TLD
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE ...> <taglib> ... <tag> <name>repeat</name> <tagclass>moreservlets.tags.RepeatTag</tagclass> <bodycontent>JSP</bodycontent> <info>Repeats body the specified number of times.</info> <attribute> <name>reps</name> <required>true</required> <!-- rtexprvalue indicates whether attribute can be a JSP expression. --> <rtexprvalue>true</rtexprvalue> </attribute> </tag> ...

91

This the TLD file. Here the characteristics of reps attribute has been defined.

91

08/01/2006

Example: JSP Page (RepeatExample.jsp)


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-Illustration of RepeatTag tag. Taken from More Servlets and JavaServer Pages from Prentice Hall and Sun Microsystems Press, http://www.moreservlets.com/. (C) 2002 Marty Hall; may be freely used or adapted. --> <HTML> <HEAD> <TITLE>Some 40-Digit Primes</TITLE> <LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <BODY> <H1>Some 40-Digit Primes</H1> Each entry in the following list is the first prime number higher than a randomly selected 40-digit number.

92

This is the calling JSP page. Skip to the next slide.

92

08/01/2006

Example: JSP Page (RepeatExample.jsp)


<%@ taglib uri="/WEB-INF/msajsp-taglib.tld" prefix="msajsp" %> <OL> <!-- Repeats N times. A null reps value means repeat once. --> <msajsp:repeat reps='<%= request.getParameter("repeats") %>'> <LI><msajsp:prime length="40" /> </msajsp:repeat> </OL> </BODY> </HTML>

93

Here the body content which itself is a custom tag will be evaluated by the value of repeats input parameter.

93

08/01/2006

To be added

94

Here the value of repeats is set to 9 and the prime number is repeated 9 times.

94

08/01/2006

More detailed information on How to declare tag library using taglib directive

95

Now you should be relatively comfortable with taglib directive in the JSP page. Here let's go over the syntax of the taglib directive in a bit more detail.

95

08/01/2006

Declaring a tag library: uri attribute (3 different ways - 2 on this slide)


?

Direct reference to TLD file

<%@ taglib prefix="tlt" uri="/WEB-INF/iterator.tld"%>

Indirect reference to TLD file using a logical name


<%@ taglib prefix="tlt" uri="/tlt"%> Mapping of the logical name to path to the TLD file has to be defined in web.xml
<jsp-config> <taglib> <taglib-uri>/tlt</taglib-uri> <taglib-location>/WEB-INF/iterator.tld</taglib-location> </taglib> </jsp-config>

96

The uri attribute refers to a URI that uniquely identifies the tag library descriptor (TLD), a document that describes the tag library (See Tag Library Descriptors). Tag library descriptor file names must have the extension .tld. TLD files are stored in the WEB-INF directory or subdirectory of the WAR file or in the META-INF/ directory or subdirectory of a tag library packaged in a JAR. You can reference a TLD directly or indirectly. The following taglib directive directly references a TLD filename: <%@ taglib prefix="tlt" uri="/WEB-INF/iterator.tld"%> This taglib directive uses a short logical name to indirectly reference the TLD: <%@ taglib prefix="tlt" uri="/tlt"%>

96

08/01/2006

Declaring a tag library: uri attribute (3 different ways - 1 on this slide)


?

Absolute URI - examples of JSTL tag libraries


<%@ taglib prefix="core" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="xml" uri="http://java.sun.com/jsp/jstl/xml"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>

97

You can also reference a TLD in a taglib directive with an absolute URI. For example, the absolute URIs for the JSTL library are: * Core: http://java.sun.com/jsp/jstl/core * XML: http://java.sun.com/jsp/jstl/xml * Internationalization: http://java.sun.com/jsp/jstl/fmt * SQL: http://java.sun.com/jsp/jstl/sql * Functions: http://java.sun.com/jsp/jstl/functions When you reference a tag library with an absolute URI that exactly matches the URI declared in the taglib element of the TLD (see Tag Library Descriptors), you do not have to add the taglib element to web.xml; the JSP container automatically locates the TLD inside the JSTL library implementation.

97

08/01/2006

More detailed information on How to Configure tag library with Web application
98

Let's see how tag library can be configured with Web application.

98

08/01/2006

Configuring tag library with individual Web app


?

In unpacked form

tag handler classes are packaged under the /WEB-INF/classes/ directory *.tld file under the /WEB-INF/ directory *.jar file is in the /WEB-INF/lib/ directory

In packaged form (*.jar file)

99

In addition to declaring the tag library, you also need to make the tag library implementation available to the Web application. There are several ways to do this. Tag library implementations can be included in a WAR in an unpacked format: tag files are packaged in the /WEB-INF/tag/ directory and tag handler classes are packaged in the /WEB-INF/classes/ directory of the WAR. Tag libraries already packaged into a JAR file are included in the /WEB-INF/lib/ directory of the WAR.

99

08/01/2006

How does it Work?

100

Here in this segment of the presentation, we will look into internal mechanisms of custom tags. Much of the information is something that has been already talked about.

100

08/01/2006

How does it work?


?

JSP translator locates the TLD file via uri attribute of taglib directive

The TLD file describes the binding between an action (tag handler) and a Tag

Using a tag in a JSP page generates the appropriate servlet code

The servlet code contains tag handler

101

Now when JSP page is loaded into the web container, the JSP translator translates the JSP page into the servlet code. Now when the translator encounters the taglib directive, it knows where to find the TLD file via uri attribute. As we know now, the TLD file describes the binding between an action (tag handler) and a tag. Now tags in a JSP page results in the appropriate servlet code which contains the tag handler.

101

08/01/2006

Sequence of Calls from Container

102

This slides shows the Tag interface's methods on the left side and how these methods are invoked in sequence by the container on the right side of the slide. Tag handler methods defined by the Tag and BodyTag interfaces are called by the JSP page's servlet at various points during the evaluation of the tag. When the start element of a custom tag is encountered, the JSP page's servlet calls methods to initialize the appropriate handler and then invokes the handler's doStartTag method. When the end element of a custom tag is encountered, the handler's doEndTag method is invoked for all but simple tags. Additional methods are invoked in between when a tag handler needs to manipulate the body of the tag.

102

08/01/2006

TagSupport Implements Tag Interface

103

This slide shows the TagSupport class that implements Tag interface.

103

08/01/2006

doStartTag() and doEndTag()


?

doStartTag()
Processes starting element (semantics) Returns EVAL_BODY_INCLUDE to process body Returns SKIP_BODY to skip body

doEndTag()
Completes element processing (flush) Returns EVAL_PAGE to continue processing Returns SKIP_PAGE to terminate processing

Both can throw JspException


104

Just sums up what doStartTag() and doEndTag() methods are for.

104

08/01/2006

Calling Sequence from the Container


Obtain Obtain handler handler Set Setproperties properties s e t P a g e C o n t e x t( )
setParent( )

Set Setattribute attribute values values

Eval_body_include doStartTag( ) Process Processbody body Skip_body Skip_page doEndTag( ) Eval_page

Release( Release())

Release( Release())

Stop

Continue Continue

105

This is the calling sequence from the container. The container obtains the tag handler and invokes setPageContext() and setParent() methods of Tag interface. It then calls methods for setting attributes (if attribute elements are defined in the TLD file). Then it calls doStartTag() method. If the doStartTag() method returns EVAL_BODY_INCLUDE, the container wll evaluate the body content. Then it calls doEndTag() method. And depending the return value, it will continue processing of the page or stop.

105

08/01/2006

How Is a Tag Invoked?


?

? ? ?

JSP technology creates (or reuses) a Tag class instance associated with the element in the page source Class is named in the TLD Container calls setPageContext() and setParent() parent (possibly null, unless nested) PageContext provides access to: request, response, out, session, page and attributes Container calls setX() methods for attributes specified Container calls doStartTag() and doEndTag() Container invokes release() to free Tag instance for reuse
106

This is a repeat of what I explained in the previous slide.

106

08/01/2006

How Is a Tag Invoked?


setPageContext() setParent() setAttr1(values1) setAttr2(value2) doStartTag( ) setBodyContent( ) doInitBody( ) doAfterBody( ) doEndTag( )

<prefix:actionName attr1=value1 attr2=value2 > The body </prefix:actionName>

107

The Tag interface defines the basic protocol between a tag handler and a JSP page's servlet. It defines the life cycle and the methods to be invoked when the start and end tags are encountered. The JSP page's servlet invokes the setPageContext, setParent, and attribute setting methods before calling doStartTag. The JSP page's servlet also guarantees that release will be invoked on the tag handler before the end of the page. Here is a typical tag handler method invocation sequence: ATag t = new ATag(); t.setPageContext(...); t.setParent(...); t.setAttribute1(value1); t.setAttribute2(value2); t.doStartTag(); t.doEndTag(); t.release();

107

08/01/2006

JSP Page Response Output


?

The output of the page is written into a JSPWriter provided by the page implementation This is flushed to the output stream of the ServletResponse. Output is buffered in the JSPWriter by default. Tags output to nested JSPWriter streams.

108

108

08/01/2006

BodyTag, BodyTagSupport
For manipulating or evaluating body multiple times,

use BodyTagSupport which is BodyTag type


Example of iteration: such as order rows, search results and etc

109

The BodyTag interface extends Tag by defining additional methods that let a tag handler access its body. The interface provides three new methods: * setBodyContent--Creates body content and adds to the tag handler * doInitBody--Called before evaluation of the tag body * doAfterBody--Called after evaluation of the tag body

109

08/01/2006

How Does BodyTag Work?

110

A typical invocation sequence is: t.doStartTag(); out = pageContext.pushBody(); t.setBodyContent(out); // perform any initialization needed after body content is set t.doInitBody(); t.doAfterBody(); // while doAfterBody returns EVAL_BODY_AGAIN we // iterate body evaluation ... t.doAfterBody(); t.doEndTag(); out = pageContext.popBody(); t.release();

110

08/01/2006

BodyContent

111

111

08/01/2006

Manipulating BodyContent (1)


?

? ? ?

JSP technology creates a nested stream (BodyContent) to contain the body text The BodyContent is passed to the BodyTag via setBodyContent() doStartBody() is invoked doInitBody() is invoked The body text is evaluated into the BodyContent
112

If the tag handler needs to manipulate the body, the tag handler must implement BodyTag (or be derived from BodyTagSupport). When a tag handler implements the BodyTag interface, it must implement the doInitBody and the doAfterBody methods. These methods manipulate body content passed to the tag handler by the JSP page's servlet. Body content supports several methods to read and write its contents. A tag handler can use the body content's getString or getReader methods to extract information from the body, and the writeOut(out) method to write the body contents to an out stream. The writer supplied to the writeOut method is obtained using the tag handler's getPreviousOut method. This method is used to ensure that a tag handler's results are available to an enclosing tag handler. If the body of the tag needs to be evaluated, the doStartTag method needs to return EVAL_BODY_BUFFERED; otherwise, it should return SKIP_BODY.

112

08/01/2006

Manipulating BodyContent (2)


?

doAfterBody() is invoked:
It must process the content of the nested stream and write to nesting stream (out) It can cause the page to be re-evaluated (to support iterative tags) by returning EVAL_BODY_TAG

Invoke doEndTag().

113

The doAfterBody method is called after the body content is evaluated. doAfterBody must return an indication of whether to continue evaluating the body. Thus, if the body should be evaluated again, as would be the case if you were implementing an iteration tag, doAfterBody should return EVAL_BODY_AGAIN; otherwise, doAfterBody should return SKIP_BODY.

113

08/01/2006

BodyTag Method Semantics


?

doStartTag():
Same as Tag semantic, except:
Returns EVAL_BODY_TAG to process body

doBodyInit():
Prepare to process body

doAfterBody() :
Handle processed body in BodyContent Return EVAL_BODY_TAG to reprocess

DoEndTag() :
Same as Tag Semantics
114

114

08/01/2006

Passion!

115

115