Nearby lessons
29 of 30JSP Examples - Custom Tags
- Build classic and simple tag handlers
- Understand the tag life-cycle methods
- Write tag files under /WEB-INF/tags
Custom tag development from scratch: the classic Tag/TagSupport/IterationTag/BodyTag models, SimpleTag and SimpleTagSupport, tag files, dynamic attributes, and accessing implicit objects from tag handlers — each with a TLD and handler source.
Unit 5: Custom Tags
Custom Tag
Classic Tag Simple Tag Tag Files
| (JSP 1.1) | (JSP 2.0) (JSP 2.0) |
|---|
Components of Custom Tag Application:
Custom tag application contains the following 3 components
1.Tag Handler class:
It is a simple java class which defines entire required functionality
Every tag handler class should compulsory implements Tag interface either directly or indirectly.
Web container is responsible for creation of Tag Handler object. For this it always invokes public
no-arg constructor. Hence every tag handler class should compulsory contains public no-arg
constructor.
2.TLD file(Tag Library Descriptor):
It is an xml file which provides mapping b/w JSP(where custom tag functionality is required) and
tag handler class(where custom tag functionality is available).
3.taglib directive:
It makes custom tag functionality available to the jsp. It defines the location of the tld file.
Execution Flow of Custom tag application
Custom Tag
Invocation
taglib
Directive
tld File
TagHandler
Class
1.Whenever jsp engine encounters a custom tag, it identifies prefix and checks for the
corresponding taglib directive with matched prefix.
- From the taglib directive jsp engine identifies the location of the tld file
- From the tld file JSP engine identifies the corresponding Tag handler class.
- JSP engine executes tag handler class and provides required functionality to the JSP.
Tag Extension API
It is the base interface for all custom tag handlers.
Every tag handler class should compulsory implement this interface either directly or indirectly.
This interface defines 6 methods which are applicable for any Tag Handler object.
We should go for this interface if we are not manipulating Tag body and iteration is not required.
Tag Extension API
It is the child interface of Tag. We should go for this interface ,if we want to consider tag body
multiple times without any manipulation.
It contains only one extra method: doAfterBody()
Tag Extension API
It is the child interface of IterationTag. If we want to manipulate Tag body then we should go for
BodyTag.
This interface defines 2 extra methods
setBodyContent() and doInitBody()
Tag Extension API
It implements IterationTag interface and provides default implementation for all its methods.
It acts as base class to develop simple and Iteration tags.
More or less this class acts as adapter class for Tag and IterationTag interfaces.
Tag Extension API
This class implements BodyTag interface and provides default implementation for all its methods.
It is the child class of TagSupport.
We can use this class as Base class for implementing Customtags that processes tag body.
6.BodyContent(C):
BodyContent object acts as a buffer to hold tag body.
It extends JspWriter.
We have to use BodyContent class only in BodyTag interface and BodyTagSupport class.
JspTag (I)
| Tag (I) | SimpleTag (I) |
|---|---|
| TagSupport (AC) IterationTag (I) | SimpleTagSupport (AC) |
BodyTagSupport (AC) BodyTag (I)
| Classic Tag Model | Simple Tag Model |
|---|---|
| (JSP 1.1) | (JSP 2.0) |
JspTag Interface is just for Polymorphism purpose and doesn't contain any Methods.
Implementing Tag(I)
Tag interface defines the following 4 constants
EVAL_BODY_INCLUDE
SKIP_BODY
EVAL_PAGE
SKIP_PAGE
Life Cycle of Tag Handler that implements Tag Interface
1.Whenever JSP engine encounters a custom tag in the JSP, it will identify the corresponding Tag
Handler class through tag lib directive and tld file.
2.Web container creates an instance of TagHandler by executing public no-arg constructor if it is
not already available.
3.JSP Engine calls setPageContext() method to make pageContext object available to Tag Handler
class.
public void setPageContext(PageContext p)
By using pageContext implicit object, Tag Handler class can get all other implicit objects and can
get attributes from various scopes.
4.JSP Engine calls setParent() method to make Parent Tag object available to Tag Handler. This is
helpful in nested tags.
public void setParent(Tag t)
5.Setting Attributes
attributes in custom tags are exactly similar to properties of Java beans. If a custom tag has an
attribute then compulsory Tag Handler class should contain instance variable and the
corresponding setter method.
JSP engine calls setter methods for each attribute.
Implementing Tag(I)
public int doStartTag() throws JspException
We can define entire tag functionality in this method only.
doStartTag() method can return either EVAL_BODY_INCLUDE or SKIP_BODY. If it returns
EVAL_BODY_INCLUDE then tag body will be included in the result.
If it returns SKIP_BODY then JSP Engine won't consider tag body.
7.JSP Engine calls doEndTag()
public int doEndTag()throws JspException
doEndTag() can return either EVAL_PAGE or SKIP_PAGE.
If it returns EVAL_PAGE then rest of the JSP will be executed normally.
If it returns SKIP_PAGE then JSP page will be returned without executing rest of the JSP.
- Finally JSP Engine calls release() method to perform cleanup activities whenever tag handler
object no longer required.
public void release()
Flowchart for Tag Handler Life Cycle
JSP Engine encounters
a Custom Tag in JSP
JSP Engine will Identify
the corresponding
TagHandler Class by using
taglib Directive and tld File
JSP Engine will create
TagHandler Object if it is
not available
setPageContext()
setParent()
Setting Attributes
EVAL_BODY_INCLUDE
doStartTag()
Tag Body will be
included
SKIP_BODY
| EVAL_PAGE doEndTag() | SKIP_PAGE |
|---|---|
| Rest of JSP will be | JSP will be returned without |
| executed normally | executing rest of JSP |
Demo Program for Custom Tags(cust1)
test.jsp:
Implementing Tag(I)
MyTld.tld
MyCustomTag.java
cust1
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
Output:
Hello this is Demo JSP
Hello this is from tag handler
This is body of the custom tag
This is after the custom tag invocation
If doStartTag() method resturns SKIP_BODY and doEndTag() method returns SKIP_PAGE then the
output is:
Hello this is Demo JSP
Hello this is from tag handler
How to map taglib directive with TLD file
- By hard coding the location of tld file in the taglib directive
<%@taglib prefix="mine" uri="/WEB-INF/MyTld.tld" %>
- Instead of hard coding the location and name of tld file in jsp,we can specify through web.xml
also.
MyCustomTag.java
- We can map taglib directly to the tld file by using uri attribute.
MyCustomTag.java
Q. In how many ways we can map taglib directive to tld file?
3 ways
Structure of TLD file:
MyCustomTag.java
It describes the type of content allowed in tag body.
The allowed values are:
1.empty:
The body of the tag should be empty. We cannot take any tag body. In this case we can invoke
custom tag as follows..
| <mine:mytag> | OR <mine:mytag/> |
|---|
</mine:mytag>
2.tagdependent:
Total tag body will be treated as plain text.
JSP engine sends tag body to the tag handler class without any processing.
3.scriptlet:
Tag body should not contain any scripting elements(i.e. scriptlet, expressions etc),But standard
actions and EL expressions are allowed.
4.jsp:
No restrictions on tag body. whatever allowed in JSP is by default allowed in tag body also.
The default value is jsp
Attributes:
A tag can contain any number of attributes. we can declare these attributes by using <attribute>
tag in tld.
<attribute> tag contains the following child tags.
1.<name> - Name of the attribute
2.<required>
true means attribute is mandatory
false means attribute is optional
default value is false
3.<rtexprvalue>
runtime expression value
true means runtime expressions are allowed
Eg: <mine:mytag color="${param.color}" />
false Runtime expressions are not allowed and we have to provide only literals.
Eg: <mine:mytag color="red" />
default value is false.
Things to remember about tag attributes:
A tag can contain attributes also. For each attribute we have to do the following things
1.We have to declare that attribute in tld by using <attribute> tag.
2.For each attribute in TagHandler class, we have to define one instance variable and
corresponding setter method.
3.In the case of optional attributes there may be a chance of NullPointerException. We have to
handle carefully.
Demo Program for empty Custom Tag with mandatory attribute
MyTld.tld
MyCustomTag.java
cust2
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
Demo Program for empty Custom Tag with optional attribute
MyTld.tld
MyCustomTag.java
cust3
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
IterationTag(I)
IterationTag is the child interface of Tag.
If we want to include tag body multiple times then we should go for IterationTag.
It contains only one extra method doAfterBody() and one extra constant EVAL_BODY_AGAIN.
Demo Program for IterationTag
MyTld.tld
MyCustomTag.java
cust4
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
TagSupport Class
We can develop Tag Handler class by implementing Tag and IterationTag interfaces directly. But
the problem in this approach is we have to provide implementation for all methods even though
most of the times our requirement is only doStartTag(), doAfterBody() and doEndTag() methods.
To overcome this problem we should go for TagSupport class. TagSupport class implements
IterationTag interface and provides default implementation for all its methods.
The main advantage of extending TagSupport class is we have to override only required methods
instead implementing all methods.
Internal implementation of TagSupport class:
MyCustomTag.java
Note:
- The default return type of doStartTag() and doAfterBody() methods is SKIP_BODY.
2.The default return type of doEndTag() is EVAL_PAGE
- pageContext variable is by default available to the child class. Hence we can use this variable
directly in our Tag Handler class.
Demo Program-1 by using TagSupport class:
test.jsp:
MyCustomTag.java
MyTld.tld
MyCustomTag.java
cust5
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
Demo Program-2 by using TagSupport class:
test.jsp:
MyCustomTag.java
MyTld.tld
MyCustomTag.java
cust5A
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
BodyTag(I)
It is the child interface of IterationTag.
If we want to manipulate Tag Body then we should go for BodyTag interface.
BodyTag interface defines the following 2 extra methods.
MyCustomTag.java
BodyTag interface defines the following 2 extra constants
1.EVAL_BODY_BUFFERED
2.EVAL_BODY_TAG==>Deprecated in JSP 1.2V
BodyContent
returns body content as String
BodyContent
returns Reader object to read tag body
BodyContent
Returns JspWriter object of Parent class
If there is no parent class then it returns current jsp out object.
BodyContent
It clears bodyContent object. i.e data present in bodyContent object will be removed.
Life cycle of Tag Handler that implements BodyTag:
The life cycle of BodyTag Handler is exactly similar to IterationTag Hanlder. The difference is
doStartTag() method can return EVAL_BODY_BUFFERED in addition to EVAL_BODY_INCLUDE and
SKIP_BODY.
If the method returns EVAL_BODY_INCLUDE then body will be evaluated and included exactly
similar to IterationTag.
If the method returns EVAL_BODY_BUFFERED and tag contains body then JSP engine creates
BodyContent object and call setBodyContent() method followed by doInitBody() method.
Note:
setBodyContent() and doInitBody() method won't be executed in the following case:
If doStartTag() returns either EVAL_BODY_INCLUDE or SKIP_BODY or if the tag does not contain
body.
Flow Chart for BodyTag Life Cycle
JSP Engine encounters
a Custom Tag in JSP
JSP Engine will Identify the
corresponding TagHandler
Class by using taglib Directive
and tld File
JSP Engine will create
TagHandler Object if it is
not available
setPageContext()
setParent()
Setting Attributes
| EVAL_BODY_INCLUDE | doStartTag() EVAL_BODY_BUFFERED |
|---|
Evaluate Body SKIP_BODY No If Tag
| SKIP_BODY | SKIP_BODY | has Body |
|---|
doAfterTag()
| EVAL_BODY_ | Yes |
|---|---|
| AGAIN | setBodyContent() |
| EVAL_PAGE | doInitBody() |
doEndTag()
Manipulate Tag
| Rest of JSP will be | SKIP_PAGE | Body and include in |
|---|---|---|
| executed normally | rest of JSP | |
| JSP will be returned | doAfterBody() | |
| without executing rest | EVAL_BODY_ |
of JSP
AGAIN
BodyTagSupport Class
This class extends TagSupport class and implements BodyTag interface.
This class provides default implementation for all 9 methods available in BodyTag interface.
It is very easy to develop tag handler by extending BodyTagSupport class instead of implementing
BodyTag interface directly. In this case we have to provide implementation only for required
methods instead of implementing all 9 methods.
Internal implementation of BodyTagSupport class:
BodyContent
Note:
1.pageContext and bodyContent variables are by default available to our Tag handler class and
hence we can use these directly.
- The default return type of
doStartTag() is EVAL_BODY_BUFFERED,
doAfterBody() is SKIP_BODY ,
doEndTag() is EVAL_PAGE.
Demo Program for BodyTag and BodyTagSupport
MyTld.tld
MyCustomTag.java
cust6
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
Comparison b/w TagSupport and BodyTagSupport Classes
| Method | Tag Support | BodyTagSupport |
|---|---|---|
| 1) doStartTag() | EVAL_BODY_INCLUDE, EVAL_BODY_INCLUDE, | |
| 1. Possible Return Values SKIP_BODY | SKIP_BODY, |
EVAL_BODY_BUFFERED
- Default Value from SKIP_BODY EVAL_BODY_BUFFERED
Implementation Class
- Number of times it can Only Once Only Once
be called per Tag
EVAL_BODY_AGAIN,
MyCustomTag.java
- Possible Return Values SKIP_BODY SKIP_BODY
- Default Value from SKIP_BODY
Implementation Class
- Number of times it can Zero OR More Zero OR More
be called per Tag
MyCustomTag.java
- Possible Return Values EVAL_PAGE, SKIP_PAGE EVAL_PAGE, SKIP_PAGE
- Default Value from EVAL_PAGE EVAL_PAGE
Implementation Class
- Number of times it can Only Once Only Once
be called per Tag
Executed only once iff
MyCustomTag.java
| doInitBody() | EVAL_BODY_BUFFERED |
|---|
and Tag contains Body
Circumstances under which
these Methods can be called
and Number of times per Tag
Invocation
Co-operative OR Nested tags:
Sometimes a group of tags work together to perform required functionality. Such type of tags are
called co-operative or nested tags.
Eg:
In JSTL <c:choose>,<c:when> and <c:otherwise> tags work together to implement java's switch
statement.
These tags are called co-operative tags.
Eg:
<mine:outerTag>
<mine:innerTag/>
</mine:outerTag>
From Inner Tag(Child Tag) we can get Parent Tag Referece by using getParent() method.
Tag parent=getParent();
Demo Program1 for Nested Tags
MyTld.tld
MyCustomTag.java
cust7
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
Demo Program2 for Nested Tags
MyTld.tld
MenuTag.java
MenuItemTag.java
cust8
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MenuTag.class
|-MenuItemTag.class
Getting an arbitrary Ancestor class:
We can get immediate parent by using getParent() method.
TagSupport class contains the following method to get an arbitrary ancestor class.
public static Tag findAncestorWithClass(Tag t,Class c)
Accessing JSP Implicit Objects in Tag Handler Class
Note:
Exception implicit object is available only in error pages. If the enclosing JSP is not error page then
getException() returns null
Demo Program for JSP Implicit objects
MyTld.tld
MyCustomTag.java
cust9
|-test.jsp
|-test1.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
http://localhost:7777/cust9/test1.jsp
http://localhost:7777/cust9/test.jsp
Getting and Setting Attributes by using PageContext API
PageContext class defines the following methods to perform attribute management.
MyCustomTag.java
3.public Object getAttribute(String name)
4.public Object getAttribute(String name,int scope)
MyCustomTag.java
SimpleTag Model
Implementing custom tags by using classic tag model (Tag, IterationTag, BodyTag, TagSupport,
BodyTagSupport)is very complex because each tag has its own life cycle and different possible
return types for each method.
To resolve this complexity, Sun people introduced Simple Tag Model in JSP 2.0V
In this model, we can build custom tags by using SimpleTag interface and its implementation class
SimpleTagSupport.
JspTag (I)
Tag (I) SimpleTag (I)
TagSupport (AC) IterationTag (I) SimpleTagSupport (AC)
| BodyTagSupport (AC) BodyTag (I) | Simple Tag Model |
|---|---|
| Classic Tag Model | (JSP 2.0) |
(JSP 1.1)
SimpleTag(I)
Life Cycle of SimpleTag Handler
Demo Program for SimpleTagSupport
MyTld.tld
MyCustomTag.java
cust10
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
If doTag() method throws SkipPageException then the output is:
This is Simple Tag Demo
Hello this is from simple tag handler
If doTag() method does not throw SkipPageException then the output is:
This is Simple Tag Demo
Hello this is from simple tag handler
This is rest of the JSP
Q. What is the difference b/w classic and simple tags wrt tag body?
In classic tag model we are allowed to take scripting elements in tag body. Hence the possible
values for <body-content> tag are : empty, tagdependent, scriptless, jsp.
default value is JSP.
But in Simple Tag Model Scripting elements are not allowed in tag body. Hence allowed values for
<body-content> are empty, tagdepdendent, scriptless but not jsp.
Default value is scriptless
Processing Body Content in Simple Tags
It causes evaluation of TagBody and return to supplied writer.
use "null" argument to write directly to the JspOutputStream.
Demo Program for SimpleTag to process Tag Body
MyTld.tld
MyCustomTag.java
cust12
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
Key Differences b/w Simple and Classic Tags
| Property | Simple Tags | Classic Tags |
|---|---|---|
| 1) Tag Interfaces | Tag | |
| Simple Tag | Iteration Tag |
Body Tag
MyCustomTag.java
| Imlementation Classes | BodyTagSupport | |
|---|---|---|
| 3) Key Life Cycle Methods | doTag() | doStartTag() |
| that we have to implement | doEndTag() |
doAfterBody()
MyCustomTag.java
| JspOutputStream | No need to use try - catch for | Compulsory we should enclose |
|---|---|---|
| IoException | by using try - catch for |
IoException
MyCustomTag.java
Objects and Attributes
MyCustomTag.java
| be processed | from doStartTag() |
|---|
getJspBody().invoke(null) OR
EVAL_BODY_BUFFERED in
Body Tag Interface from
doStartTag()
MyCustomTag.java
doEndTag()
| Page Evaluation to stop | doTag() |
|---|
Dynamic Attributes
In general tags can contain attributes. We can declare these attributes in tld file by using
<attribute> tag. In the tag handler class we have to maintain instance variables and corresponding
setter methods. Such type of attributes are called static attributes.
But we can use attributes, even though TLD file does not contain any <attribute> tag declarations.
Such type of attributes are called Dynamic Attributes.
Dynamic attributes are applicable for both classic and simple tags and introduced in Jsp
2.0version.
To Support dynamic attributes we have to do the following arrangements
" party="JanaSena" address="hyd" />
MyTld.tld
MyCustomTag.java
cust11D
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
Demo Program-2 for Dynamic Attributes:
test.jsp:
MyCustomTag.java
MyTld.tld
MyCustomTag.java
cust11
|-test.jsp
|-WEB-INF
|-MyTld.tld
|-classes
|-tags
|-MyCustomTag.class
Tag Files
Objective:
- Describe the semantics of tag file
- Describe application structure of Tag Files
- Write a Tag File and Explain constraints on JspContent in body of tag
Tag Files concept introduced in JSP 2.0V.
Tag File is a simple jsp page or jsp document designed to be used as Custom Tag.
The main advantage of Tag Files is we can build very easily when compared with classic and simple
tags.
The main limitation of tag files is it won't suggestible for doing much processing.
Building and using a Simple Tag File:
- Write a JSP Page or Document and save it with .tag extension.
2.Place this .tag file in /WEB-INF/tags folder.
- put a taglib directive in the jsp with "tagdir" attribute.
<%@ taglib prefix="mine" tagdir="/WEB-INF/tags" %>
Demo Program
<h1> Hello....This is from the tag file <br>
tagFileA
|-test.jsp
|-WEB-INF
|-tags
|-mytag.tag
Note: The name of custom tag and tag file should be matched.
Note:
- Tag Files are internally converted into Simple Tag Handlers and corresponding classes are
available in work folder.
- It is not required to write TLD File.
Declaring a Tag file with attribute:
We can define attributes for tag files by using attribute directive.
<%@ attribute name="title" required="true" rtexprvalue="true" %>
Demo Program
|-test.jsp
|-WEB-INF
|-tags
|-mytag.tag
Demo Program
|-test.jsp
|-WEB-INF
|-tags
|-mytag.tag
Where web container will search for Tag Files:
webapps1
WEB-INF
tags
MyTags
lib
MyJar.jar
META-INF
MyTld.tld
tags
MyTags
- Either directly or indirectly in WEB-INF/tags folder
- Either directly or indirectly in META-INF/tags folder present in jar file of WEB-INF/lib folder
Note:
Whenever we are deploying tag file in some jar then compulsory we have to write tld file.
Demo Program
MyTld.tld
<h1> Hello....This is from the tag file deployed in jar file <br>
| First we have to Create JAR File | Original Folder Structure |
|---|---|
| durga | tagfileJarDemo |
| META-INF | test.jsp |
| MyTld.tld | WEB-INF |
tags
| MyTags.tag | lib |
|---|
durga.jar
MyTld.tld
MyTags.tag
Disabling Scripting Language
Once scripting language is invalidated, we are not allowed to use scripting elements in JSP,
otherwise we will get translation time error.(Tomcat won't provide support for this feature)
Similarly we can disable expression language globally.
Disabling Scripting Language
Important 3
JSP FAQ's
Disabling Scripting Language
Differences b/w Include Directive and Include Action
| Include Directive | Include Action |
|---|---|
| 1) <%@ include file = "second.jsp" %> | 1) <jsp:include page = "second.jsp" |
| Contains only one Attribute File. | flush = "true"/> |
Contains 2 Attributes Page and File.
Disabling Scripting Language
| Translation Time. Hence it is also considered as | Runtime. Hence it is also considered as |
|---|---|
| Static Include. | Dynamic Include. |
Disabling Scripting Language
| Servlet will be generated. Hence Code sharing | separate Servlets will be generated. Hence Code |
|---|---|
| between the Components is possible. | sharing between the Components is not |
possible.
Disabling Scripting Language
| latest Version included JSP. It is Vendor | be included. |
|---|
Dependent.
Disabling Scripting Language
| frequently then it is recommended to use | frequently then it is recommended to use |
|---|---|
| Static Include. | Dynamic Include. |
Disabling Scripting Language
When compared with Servlet Programming, Developing JSPs is very easy because the required
mandatory stuff automatically available in every JSP. Implicit objects also one such area ,which are
by default available for every JSP.
The following is the list of all possible 9 JSP implicit objects.
Disabling Scripting Language
- Classic model uses doStartTag/doEndTag; simple model uses doTag
- Handlers reach JSP data via pageContext
- Tag files are JSP-like files with a tag directive