Creating a Custom Tag

To create a Custom Tag the following components are required :

  1. The Tag Handler class which should extend SimpleTagSupport.
  2. The Tag Library Descriptor(TLD) file
  3. Use the Custom Tag in your JSP file

Tag Handler Class

You can create a Tag Handler class in two different ways:

  1. By implementing one of three interfaces : SimpleTag, Tag or BodyTag, which define methods that are invoked during the life cycle of the tag.
  2. By extending an abstract base class that implements the SimpleTag, Tag, or BodyTag interfaces. The SimpleTagSupport, TagSupport, and BodyTagSupport classes implement the SimpleTag, Tag andBodyTag interfaces . Extending these classes relieves the tag handler class from having to implement all methods in the interfaces and also provides other convenient functionality.

Tag Library Descriptor

A Tag Library Descriptor is an XML document that contains information about a library as a whole and about each tag contained in the library. TLDs are used by the web container to validate the tags and also by JSP page development tools.

Tag library descriptor file must have the extension .tld and must be packaged 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.


Example of Custom Tag

In our example, we will be creating a Tag Handler class that extends the TagSupport class. When we extend this class, we have to override the method doStartTag(). There are two other methods of this class namely doEndTag() and release(), that we can decide to override or not depending on our requirement.

CountMatches.java

package com.studytonight.taghandler;

import java.io.IOException;
import javax.servlet.jsp.*;
import org.apache.commons.lang.StringUtils;

public class CountMatches extends TagSupport {
  private String inputstring;
  private String lookupstring;
	     
  public String getInputstring() {
    return inputstring;
  }

  public void setInputstring(String inputstring) {
    this.inputstring = inputstring;
  }

  public String getLookupstring() {
    return lookupstring;
  }

  public void setLookupstring(String lookupstring) {
    this.lookupstring = lookupstring;
  }

  @Override
  public int doStartTag() throws JspException {
    try {
      JspWriter out = pageContext.getOut();
      out.println(StringUtils.countMatches(inputstring, lookupstring));
    } 
    catch (IOException e) {
      e.printStackTrace();
    }
    return SKIP_BODY;
  }
}

In the above code, we have an implementation of the doStartTag() method which is must if we are extending TagSupport class. We have declared two variables inputstring and lookupstring. These variables represents the attributes of the custom tag. We must provide getter and setter for these variables in order to set the values into these variables that will be provided at the time of using this custom tag. We can also specify whether these attributes are required or not.

CountMatchesDescriptor.tld

<?xml version="1.0" encoding="UTF-8"?>
<taglib> 
  <tlibversion>1.0</tlibversion>
  <jspversion>1.1</jspversion>
  <shortname>cntmtchs</shortname>
  <info>Sample taglib for Substr operation</info>
  <uri>http://studytonight.com/jsp/taglib/countmatches</uri>
  
  <tag>
    <name>countmatches</name>
    <tagclass>com.studytonight.taghandler.CountMatches</tagclass>
    <info>String Utility</info>
    <attribute>
       <name>inputstring</name>
       <required>true</required>
    </attribute>
    <attribute>
       <name>lookupstring</name>
       <required>true</required>
    </attribute>
  </tag>

</taglib>

The taglib element specifies the schema, required JSP version and the tags within this tag library. Each tag element within the TLD represents an individual custom tag that exist in the library. Each of these tag should have a tag handler class associated with them.

The uri element represents a Uniform Resource Identifier that uniquely identifies the tag library.

The two attribute elements within the tag element represents that the tag has two attributes and the true value provided to the required element represents that both of these attributes are required for the tag to function properly.

test.jsp

<%@taglib prefix="mytag" uri="/WEB-INF/CountMatchesDescriptor.tld"%>  
<html>
  <mytag:countmatches inputstring="Studytonight" lookupstring="t">
  </mytag:countmatches>
</html>

If this tag works fine it should print a value 3 in the browser as there 't' occurs 3 times in the word 'Studytonight'.