JSP – Custom Tags

In this article, we are going to discuss the custom tags in JSP, creation custom tags and custom tag processing flow. Custom tags are user-defined tags. They help to eliminates the possibility of scriptlet tag and separates the business logic from the JSP page.

Advantages of Custom Tags

The following advantages of Custom tags are listed below:

1. The Elimination of required scripted tag: It eliminates the need for scriptlet tag in JSP.

2. It helps to separate the business logic from the JSP page: The custom tags separate the business logic from the JSP page so that it may be easy to maintain.

3. Re-use the code: It provides the reuse of the same business logic again and again.

Steps to develop the custom tags

  1. Identify the tag name and attributes required.<xadmin: hello sname=”ashish” email=”aashish2012@gmail.com”/>
  2. Identify the purpose of the tag: Display the message as follows:-

A) Hello! ashish, Welcome JSP Custom Tags.

Your Email id is aashish2012@gmail.com

<xadmin: hello sname= ”ashish”/>

B) Hello! Ashish, Welcome JSP Custom Tags.

Your Email id is not specified.

Note: sname attribute is mandatory and email attribute is optional.

3. Develop the Tag Handler Class.

-HelloTag.java

4. Describe your tag in tld file(Tag Library Descriptor)

-xadmin.tld

After developing tag using the above steps using that custom tag in JSP with a  Taglib directive.

Taglib Example:

File Required:

1) hello.jsp

2) xadmin.tld

3) HelloTag.java

1) hello.jsp

<%@taglib uri=”/WEB-INF/jtc.tld” prefix=”jtc”%>
<h1>
Xadmin Website<br>
<br>
<xadmin:hello sname=”bhagat”/>
<br>
<br>
<br>
${MSG}
</h1>

2) xadmin.tld

<?xml version=”1.0” encoding=”UTF-8” ?>
<tlib-version>1.0<tlib-version><short-name>
 xadmin custom tags
</short-name>
<uri>/WEB-INF/xadmin.tld</uri>
<tag>
<name> hello </name>
<tag-class>
com.xadmin.jsp.ctag.HelloTag
</tag-class>
<body-content>
 empty
</body-content>
<attribute>
<name>sname</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute><name>email</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag><name> for </name>
<tag-class>com.xadmin.jsp.ctag.ForTag</tag-class>
<body-content> jsp</body-content>
<attribute><name>var</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>

3) HelloTag.java

package com.xadmin.jsp.ctags;

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.TagSupport;

public class HelloTag extends TagSupport
{
private String sname;
private String email;
static {
System.out.println(“HelloTag-S.B”);
}

public HelloTag()
{
System.out.println(“HelloTag-D.C”);
}

public void setSname(String sname)
{
System.out.println(“setSname()”);
this.sname=sname;
}
public void setEmail(String email)
{
System.out.println(“setEmail()”);
this.email=email;
}
 public int doStartTag() throws JspException
{
System.out.println(“doStartTag()”);
return EVAL_BODY_INCLUDE;
}
 public int doAfterBody() throws JspException
{
System.out.println(“doAfterBody()”);
return SKIP_BODY;
}

 public int doEndTag() throws JspException
{
System.out.println(“doEndTag”);
String msg=”Hello ! “ +sname +”, Welcome JSP Custom Tags <br>”;
if(email == null || email.length() ==0)
{
msg=msg+”Your Email id is “ + email;
}
JspWriter out = pageContext.getOut();
HttpSession session = pageContext.getSession();
session.setAttribute(“MSG”, msg);
try
{
out.print(msg);
}
catch(IOException e)
{
e.printStackTrace();
}
return EVAL_PAGE;
}
}

ForTag.java

Package com.xadmin.jsp.ctags

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.TagSupport;

public class ForTag extends TagSupport
{
private String var;
private int count;
private int n;
static {
System.out.println(“ForTag-S.B”);
}

public ForTag()
{
System.out.println(“ForTag-D.C”);
}

public void setVar(String var)
{
System.out.println(“setVar()”);
this.var=var;
}

 public int doStartTag() throws JspException
{
System.out.println(“doStartTag()”);
count=1;
n=Integer.parseInt(var);
return EVAL_BODY_INCLUDE;
}

 public int doAfterBody() throws JspException
{
System.out.println(“doAfterBody()”);
if(count<n)
{
count++;
return EVAL_BODY_AGAIN;
}
return SKIP_BODY;
}
 public int doEndTag() throws JspException
{
System.out.println(“doEndTag”);
return EVAL_PAGE;
}
}

Custom Tag Processing Flow

  1. Whenever a tag is encountered in the JSP, then container takes tag name and prefix.
  2. Container checks whether any Taglib directive is available whose prefix is matching with a prefix of the tag encountered.
  3. If no matching Taglib directive is available then that tag will be ignored.
  4. If matching Taglib directive is available then URL of matching Taglib directive will be taken.
  5. Container checks whether any .tld file is available whose URL is matching with URI of the Taglib directive identified.
  6. If matching .tld file is found the container checks tag description in that tld file by checking the following.
    1. Checks whether tag name is found in that tld or not.
    2. If the tag name is not found then checks whether the attributes are used correctly or not.– Undefined attribute name “sname1”– Missing required attribute “sname”

3. If attributes are used correctly then the Tag Handler class will be taken.

7. Container starts the Tag Handler class lifecycle.

8. Once the tag Handler class lifecycle is completed then Tag processing is completed.

Lifecycle methods of Tag Handler class

  1. int doStartTag()
  2. void setBodyContent()
  3. void doInitBody()
  4. int doAfterBody()
  5. int doEndTag()

1) Int doStartTag(): Process the start tag for this instance. This method is invoked by the JSP page implementation object. The doStartTag method assumes that the properties pageContext and parent have been set. It also assumes that any properties exposed as attributes have been set too. When this method is invoked, the body has not yet been evaluated.

This method returns the Tag.EVAL_BODY_INCLUDE or BodyTag.EVAL_BODY_BUFFERED to indicates that the body of the action should be evaluated or SKIP_BODY to indicate otherwise.

When a tag returns EVAL_BODY _INCLUDE the result of evaluating the body (if any) is included into the current “out ” JspWriter as it happens and then doEndTag() is invoked.

2) void setBodyContent(): set the bodyContent property. This method is invoked by the JSP page implementation object at most once per action invocation. This method will be invoked before doInitBody. This method will not be invoked for empty tags or for non-empty tags whose doStartTag() method returns SKIP_BODY or EVAL_BODY_INCULDE.

When setBodyContent is invoked, the value of the implicit object out has already been changed in the pageContext object. The BodyContent object passed will have not data on it but may have been reused(and cleared) from some previous invocation.

The BodyContext object is available and with the appropriate context until after the invocation of the doEndTag method, at which case it may be reused.

3) Void doInitBody(): Prepare for evaluation of the body. This method is invoked by the JSP page implementation object after setBodyContent and before the first time the body is to evaluate. This method will not be invoked for empty tags or for non-empty tags whose doStartTag() method returns SKIP_BODY or EVAL_BODY_INCLUDE. The JSP container will resynchronize any variable values that are indicated as so in TagExtraInfo after the invocation of doInitBody().

4) int doAfterBody(): Process body (re) evaluation. This method is invoked by the JSP Page implementation object after every evaluation of the body into the BodyEvaluation object. The method is not invoked if there is nobody evaluation. If doAfterBody returns EVAL_BODY_AGAIN, a new evaluation of the body will happen (followed by another invocation of doAfterBody). If doAfterBody returns SKIP_BODY no more body evaluations will occur, the value of out will be restored using the popBody method in pageContext, and the doEndTag will be invoked. The method re-invocations may be lead to different actions because there might have been some changes to shared state, or because of external computation.

The JSP container will resynchronize any variable values that are indicated as so in TagExtraInfo after the invocation of doAfterBody().

5) int doEndTag(): process the end tag for this instance. This method is invoked by the JSP page implementation object on the Tag Handlers. This method will be called after returning from doStartTag. The body of the action may or not have been evaluated, depending on the return value of doStartTag.

If this method returns EVAL_PAGE, the rest of the page continues to be evaluated. If this method returns SKIP_PAGE, the rest of the page is not evaluated and the request is completed. If this request was forwarded or included from another page (or Servlet) only the current page evaluation is completed.

The JSP container will resynchronize any variable values that are indicated as so in TagExtraInfo after the invocation of doEndTag().

Other important methods of the Tag Handler class.

  1. Void setParent(Tag): Set the parent (closest enclosing tag handler) of this tag handler. Invoked by the JSP page implementation object prior to doStartTag().
  2. Tag getParent(): Get the parent ( closest enclosing tag handler) for this tag handler. The getParent() method can be used to navigate the nested tag handler structure at runtime for cooperation among custom actions. For example, the findAncestorWithClass() method in TagSupport provides a convenient way of doing this.
  3. Void setPageContext(PageContext): Set the current page context. This method is invoked by the JSP page implementation object prior to doStartTag().
  4. PageContext getPageContext();

 

Leave a Reply

Your email address will not be published. Required fields are marked *