Make delicious recipes!

JSP Custom Tags


A custom tag can contain custom and core tags, scripting elements, HTML text, and tag-dependent body content between the start and end tag. Custom-tags can register classes as event listeners too by making use of listener element in the tag.


A tag library descriptor (TLD) is an XML document that describes a tag library and it must have the extension .tld. A TLD contains information about a library as a whole and about each tag contained in the library. TLD files are stored in the WEB-INF directory of the WAR or in a subdirectory of WEB-INF.


Custom tag is declared as :

<%@ taglib uri="/WEB-INF/tutorial-template.tld" prefix="tt" %>

<tag>
<name>present</name>
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class>
<body-content>JSP</body-content>
...
<attribute>
<name>parameter</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
...
</tag>



Tag-Handler classes/interfaces are contained in the package javax.servlet.jsp.tagext:

Interfaces: Tag, BodyTag

Base Classes: TagSupport, BodyTagSupport

An object of class PageContext is available to a Tag-Handler through which it can access all objects of that page like session, request and application. Nested tags access enclosing tags by an object called parent.

A set of related tag handler classes (a tag library) is usually packaged and deployed as a JAR archive.



Fields inside a tag-handler class can be set by attribute-mechanism in corresponding Custom-Tags if the class has a corresponding set<Attribute> function.

Example:

<opera:role name="Papageno" range="baritone" description="a bird-catcher"/>

The above tag will call functions setRange(“baritone”) and setDescription(...) in the Tag-class.

More information about attributes can be set in the TLD as:

<attribute>

<name> attributeName </name>

<required> true|false </required>

<rtexprvalue> true|false </rtexprvalue>

</attribute>


If <rtexprvalue> is set to true, then the attribute can be set by a non-string value obtained from some expression too. For example, if we set <rtexprvalue> to true for attribute date, then in the custom-tag, we can set the date as:

<x:formattedDate date="<%= new java.util.Date() %>" />

This is useful when we want to set objects instead of strings as attributes.

For the above, we need to have following method defined in our tag-class:

void setDate(Date d);


Tags with Bodies implement BodyTag interface or more commonly derive from BodyTagSupoprt class. JSP creates an object of BodyContent to evaluate the body of a tag. BodyContent is derived from JspWriter. Thus, for each nested custom-tag, a new JspWriter is created via BodyContent. This helps to prevent the output generated by each body’s evaluation from going directly to the HTML output. It goes into a string buffer present in the BodyContent variable. This buffer can be accessed via variable bodyContent in doEndTag method.

P.S. In addition to SKIP_BODY, doStartTag() can return either EVAL_BODY_

INCLUDE or EVAL_BODY_TAG, both of which indicate the body should be processed.

However, tag handlers that implement BodyTag cannot return EVAL_BODY_

INCLUDE, and tag handlers that don’t implement BodyTag cannot return EVAL_

BODY_TAG. Both of these actions cause run-time exceptions.




=> Enumeration is very similar to Iterator and both can be used interchangeably.

=> Properties class inherits from HashTable and requires both keys and values to be strings.


TEI: Defining Scripting Variables in Custom-Tags

A tag that needs to define variables or perform validation on its attributes needs to

define a class that extends the TagExtraInfo class. The method of primary interest is getVariableInfo(). This method is called by the JSP parser at page translation time and is expected to return an array of VariableInfo objects. VariableInfo is essentially only a data structure having four fields:

  1. varName The name of the variable to be created.

  2. className The fully qualified name of the variable’s class.

  3. declare A boolean variable that is true if the JSP parser should create an

actual definition for the variable (as opposed to assuming a variable of that

class will have already been defined earlier in the servlet).

  1. scope An integer indicating the point at which the variable should be

defined (or considered active). It can have values AT_BEGIN, AT_END, NESTED.

So, for each element in the above array, JSP creates an object varName of class className at the given scope.

Example for TEI:

  1. TLD:

<tag>

<name>enumerate</name>

<tagclass>jspcr.taglib.util.EnumerateTag</tagclass>

<teiclass>jspcr.taglib.util.EnumerateTEI</teiclass>

<bodycontent>JSP</bodycontent>

<info>

Iterates tag body through an enumeration

</info>

<attribute>

<name>enumeration</name>

<required>true</required>

<rtexprvalue>true</rtexprvalue>

</attribute>

</tag>


  1. Tag Handler:




  1. TEI Class



  1. TEI-Usage


Another useful example present in JSP-Complete-Reference is that of a switch-case emulation in JSP by means of tags. This is done by writing TagHandler and TLD for SwitchClass, CaseClass and DefaultClass. SwitchClass tag will have a number of CaseClass tags and one DefaultClass tag. The expression of switch statement is passed as an attribute to SwitchClass tag. The nested tags inside it (CaseClass and DefaultClass) match their expression with this expression using parentClass.getValue()==this.getValue(). If they match, a flag in parent is set to true. This flag is checked by each nested tag and if its true, the nested tag skips matching and evaluation.


DB-Example:






Like us on Facebook to remain in touch
with the latest in technology and tutorials!


Got a thought to share or found a
bug in the code?
We'd love to hear from you:

Name:
Email: (Your email is not shared with anybody)
Comment:

Facebook comments:

Site Owner: Sachin Goyal