JSP Simple Tag Handlers

JSP Simple tags

  • All standard JSP tags are handled by tag libraries.
  • JSP provides the capability for you to encapsulate reusable functionality into your own custom tags.
  • These custom tags will get their behavior from a Java class known as a tag handler.
  • In this section we will look at the simple tag handler, which is more easy then the classic tag handler found in the next section.
  • For a class to bee a simple tag handler we must implement the interface javax.servlet.jsp.tagext.SimpleTag, but for the further we will extend the javax.servlet.jsp.tagext.SimpleTagSupport class which implements defaults for all the methods of the interface.

    The tag handler must also follow the required rules of a Javabean with a no-argument constructor and include private members with setXXX and getXXX methods for the tag attributes.

The SimpleTagSupport class

  • The SimpleTagSupport class has the following methods which can be overwritten:
    Method Description
    void doTag() Default processing of the tag does nothing (At least overide this).
    static JspTag findAncestorWithClass (JspTag from, java.lang.Class class) Find the instance of a given class type that is closest to a given instance.
    protected JspFragment getJspBody() Returns the body passed in by the container via setJspBody.
    protected JspContext getJspContext() Returns the page context passed in by the container via setJspContext.
    JspTag getParent() Returns the parent of this tag, for collaboration purposes.
    void setJspBody(JspFragment jspBody) Stores the provided JspFragment.
    void setJspContext(JspContext pc) Stores the provided JSP context in the private jspContext field.
    void setParent(JspTag parent) Sets the parent of this tag, for collaboration purposes.
  • When the tag appears in a JSP file, the translator(container) creates code that:
    1. Creates an instance of the tag handler.
    2. Calls first the setJspContext() method and then the setParent() method.
    3. Initializes the tag handler attributes.
    4. If a body exists, the setJspBody() method is called by the container to set the body of this tag, as a JspFragment.
    5. The doTag() method is called by the container. All tag logic, iteration, body evaluations, etc. occur in this method.
    Example using doTag() method:
    public HelloWorldSimpleTag extends SimpleTagSupport {
      public void doTag() throws JspException, IOException {
        getJspContext().getOut().write("Hello, world.");
      }
    }

    All tags must be defined in a Tag Library Descriptor File (a XML type file) that can be placed under the WEB-INF/tlds directory.

Tag Library Descriptor File

  • 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 a web container to validate the tags and by JSP page development tools.
  • Tag library descriptor file names must have the extension .tld.
    The root tag is taglib and must be defined in this way:
    <?xml version="1.0" encoding="UTF-8"?>
    <taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
    
    (Here comes the taglib sub-element described below)
    
    </taglib>
    taglib sub-element(s):
    Element Description
    description (optional) A string describing the use of the tag library.
    display-name (optional) Name intended to be displayed by tools.
    icon (optional) Icon that can be used by tools.
    tlib-version The tag library’s version.
    short-name (optional) Name that could be used by a JSP page-authoring tool to create names with a mnemonic value.
    uri A URI that uniquely identifies the tag library.
    validator Defines an optional tag library validator that can be used to validate the conformance of any JSP page importing this tag library to its requirements.
    validator sub-element:
    Element Description
    validator-class The class implementing javax.servlet.jsp.tagext.TagLibraryValidator.
    init-param (optional) Initialization parameters.
    listener (optional) A tag library can specify some classes that are event listeners.
    listener sub-element:
    Element Description
    listener-class Must contain the fully qualified name of the listener class.
    tag-file | tag Declares the tag files or tags defined in the tag library. As we want to write tag handlers in Java, each tag in the library must be declared in the TLD with a tag element.
    tag sub-element:
    Element Description
    description (optional) A description of the tag.
    display-name (optional) name intended to be displayed by tools.
    icon (optional) Icon that can be used by tools.
    name The unique tag name.
    tag-class The fully qualified name of the tag handler class.
    tei-class (optional) Subclass of javax.servlet.jsp.tagext.TagExtraInfo. See Declaring Tag Variables for Tag Handlers.
    body-content The body content type.
    • tagdependent: The body of the tag is interpreted by the tag implementation itself, and is most likely in a different language, for example, embedded SQL statements.
    • empty: The body must be empty.
    • scriptless: The body accepts only static text, EL expressions, and custom tags. No scripting elements are allowed.
    variable (optional) Declares an EL variable exposed by the tag to the calling page.
    attribute Declares an attribute of the custom tag.
    attribute sub-element:
    Element Description
    description (optional) A description of the attribute.
    name The unique name of the attribute being declared. A translation error results if more than one attribute element appears in the same tag with the same name
    required (optional) Whether the attribute is required. The default is false.
    rtexprvalue (optional) Whether the attribute’s value can be dynamically calculated at runtime by an EL expression. The default is false. When this element is set to true and the attribute definition also includes either a deferred-value or deferred-method element then the attribute accepts both dynamic and deferred expressions.
    type (optional) The runtime type of the attribute’s value. Defaults to java.lang.String if not specified.
    fragment (optional) Whether this attribute is a fragment to be evaluated by the tag handler (true) or a normal attribute to be evaluated by the container before being passed to the tag handler.
    If this attribute is true:
    • You do not specify the rtexprvalue attribute. The container fixes the rtexprvalue attribute at true.
    • You do not specify the type attribute. The container fixes the type attribute at javax.servlet.jsp.tagext.JspFragment.
    • Defaults to false.
    deferred-value (optional) A description of the attribute.
    deferred-method (optional) A description of the attribute.
    dynamic-attributes Whether the tag supports additional attributes with dynamic names. Defaults to false. If true, the tag handler class must implement the javax.servlet.jsp.tagext.DynamicAttributes interface.
    example (optional) Indicates that the tag attribute accepts deferred value expressions. This element includes an optional type child element, which indicates the type of object to which the expression resolves. If no type element is included, the type is java.lang.Object. Either the deferred-value or deferred-method element (but not both) can be defined for the same attribute.
    tag-extension (optional) Indicates that the tag attribute accepts deferred method expressions. This element includes an optional method-signature child element, which indicates the signature of the method that the expression invokes. If no method signature is defined, the method signature default is void methodName(). Either the deferred-value or deferred-method element (but not both) can be defined for the same attribute.
    function (optional) Zero or more EL functions (static methods) defined in the tag library.
    tag-extension (optional) Extensions that provide extra information about the tag library for tools.

Example of using JSP Simple tags.

In the example we use Netbeans IDE and Glassfish Server.

You can download this example here (needed tools can be found in the right menu on this page).

If you like to participate in the review of this example you must first create a Web project in Netbeans (the project name is CustomSimpleTag).

In this example, we will add two files, header.jsp and footer.jsp.

  • It is customary to place all include files, which are used several times in the WEB-INF folder. Some would also like the include files should have the extension .jspf, but this is not a requirement.
    Here is the file we want to include at the top of all pages:
    <h2 class="siteblue">Searching Short Country List</h2>
    <hr>

    For those who participate in the review: create a JSP file in Netbeans and replace generated code for the JSP with that shown above (the JSP file name is Header.jsp and folder should be WEB-INF).

    Here is the file we want to include at the bottom of all pages:
    <hr >
    <span class="siteblue">Listing date <%= (new java.util.Date()).toString() %></span>

    For those who participate in the review: create a JSP file in Netbeans and replace generated code for the JSP with that shown above (the JSP file name is Footer.jsp and folder should be WEB-INF).

In this example, we will add three java files; Country.java, CountryControl.java and the taghandler CountrySearchTag.java.

  • We need a java class with information about each country that we want to list through a CountryControl class.
    Here is the Country.java:
    package jsp.data;
    
    public class Country {
    
      private String flag;
      private String name;
      private String fullName;
      private String capital;
      private String phoneCode;
      private String topLevelDomain;
      private String region;
    
      public Country(String flag, String name, String fullName, 
              String capital, String phoneCode, 
              String topLevelDomain, String region) {
        this.flag = flag;
        this.name = name;
        this.fullName = fullName;
        this.capital = capital;
        this.phoneCode = phoneCode;
        this.topLevelDomain = topLevelDomain;
        this.region = region;
      }
    
      public String getFlag() {
        return flag;
      }
    
      public String getName() {
        return name;
      }
    
      public String getFullName() {
        return fullName;
      }
    
      public String getCapital() {
        return capital;
      }
    
      public String getPhoneCode() {
        return phoneCode;
      }
    
      public String getTopLevelDomain() {
        return topLevelDomain;
      }
    
      public String getRegion() {
        return region;
      }
     }

    For those who participate in the review: create a java class in Netbeans and replace generated code for the java file with that shown above (the java file name is Country and package should be jsp.data).

  • We want to to list flag image, name, full name, capital, phone code, top level domain endings and region of each country through help of the CountryControl class.
  • We need a Java class, CountryControl.java, that handles the existence of each country in a list and can give us the list when we need it in our JSP.
    Here is the CountryControl.java:
    package jsp.data;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class CountryControl {
      private List<Country>  countries= new ArrayList<Country>();
    
      public CountryControl() {
        countries.add(new Country("images/azerbaijan.png","Azerbaijan",
                "Republic of Azerbaijan","Baku","+994",".az","Asia"));
        
        countries.add(new Country("images/bahamas.png","Bahamas",
                "Commonwealth of the Bahamas","Nassau","+1-242",".bs","America"));
        
        countries.add(new Country("images/bahrain.png","Bahrain",
                "Kingdom of Bahrain","Manama","+973",".bx","Asia"));
        
        countries.add(new Country("images/bangladesh.png","Bangladesh",
                "People's Republic of Bangladesh","Dhaka","+880",".bd","Asia"));
        
        countries.add(new Country("images/brunei.png","Burundi",
                "Republic of Burundi","Bujumbura","+257",".bi","Africa"));
        
        countries.add(new Country("images/bulgaria.png","Bulgaria",
                "Republic of Bulgaria","Sofia","+359",".bg","Europa"));
        
        countries.add(new Country("images/france.png","France",
                "French Republic","Paris","+33",".fr","Europa"));
        
        countries.add(new Country("images/mexico.png","Mexico",
                "United Mexican States","Mexico City","+52",".mx","America"));
      }
    
      public List<Country> getCountries() {
        return countries;
      }
     }

    For those who participate in the review: create a java class in Netbeans and replace generated code for the java file with that shown above (the java file name is CountryControl and package should be jsp.data).

  • In this class we have a member variable, countries, which shall contain all the registered countries at current time. This is instantiated when an instance of the class is created. We have also added some countries in the default constructor.
  • We have created a method that returns a list of all the registered countries at current time.
  • All the flag photos we need so far must be placed under the web/images directory. You can download the pictures of all the flags here and extract them to the web directory of the project
  • The last Java class, CountrySearchTag.java, is our taghandler that will return countries based on a search criteria.
    Here is the CountrySearchTag.java:
    package jsp.customtags;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    import jsp.data.Country;
    import jsp.data.CountryControl;
    
    public class CountrySearchTag extends SimpleTagSupport {
      
      private String field=null;
      private String var=null;
      private String search = null;
      private CountryControl countryControl = null;
      private List<Country> countryList=null;
     
      public CountrySearchTag() {
      }
    
      public void setVar(String var) {
        this.var = var;
      }
    
      public void setField(String field) {
        this.field = field;
      }
    
      
      public void setSearch(String search) {
        this.search=search;
      }
    
      public void setCountryControl(CountryControl countryControl) {
        this.countryControl = countryControl;
      }
    
      @Override
      public void doTag() throws JspException, IOException {
        countryList = new ArrayList<Country>();
        if (countryControl != null && search != null){
          for (Country country : countryControl.getCountries()) {
            boolean found=false;
            switch (field) {
             case  "fullName": found=country.getFullName().contains(search);
                    break;
             case  "name": found=country.getName().contains(search);
                    break;
             case  "capital": found=country.getCapital().contains(search);
                    break;
             case  "phoneCode": found=country.getPhoneCode().contains(search);
                    break;
             case  "topLevelDomain": found=country.getTopLevelDomain().contains(search);
                    break;
             case  "region": found=country.getRegion().contains(search);
                    break;
            }
            if (found) {
              countryList.add(country);
            }
          }
          getJspContext().setAttribute(var, countryList);
        }
      }
    }

    For those who participate in the review: create a java class in Netbeans and replace generated code for the java file with that shown above (the java file name is CountryControl and package should be jsp.customtags).

  • This class must extend the SimpleTagSupport class which has default implementation of the SimpleTag interface.
  • In this class we have the member variables, field, var and search with set accessors for the tag attributes with the same names.
  • The SimpleTagSupport class will create an object of the CountryControl class when created.
  • In the doTag() method of the SimpleTagSupport class we must use the tag attributes data (in field and search) and deliver the searching result to the var attribute of the tag with the method setAttribute in the JspContext.

Then we need to write the Tag Library Descriptor File.

  • With the tag handler written and compiled, the next step is to write the TLD file (SearchTag.tld), which describes the tag, how it will be used on the page, the type of body content, whether the tag accepts any attributes, and so on.
    Here is the SearchTag.tld file:
    <?xml version="1.0" encoding="UTF-8"?>
    <taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
      <tlib-version>1.0</tlib-version>
      <description>Country search Custom Tag</description>
      <short-name>st</short-name>
      <uri>/SearchTag</uri>
      <tag>
        <name>searchCountry</name>
        <tag-class>jsp.customtags.CountrySearchTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
          <name>field</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>  
        </attribute>
        <attribute>
          <name>search</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>  
        </attribute>
        <attribute>
          <name>var</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>    
        </attribute>
      </tag>
    </taglib>

    For those who participate in the review: create a tld file in Netbeans and replace generated code for the tld file with that shown above.

  • The name of the tag is searchCountry with the taghandler class jsp.customtags.CountrySearchTag.
  • The tag (searchCountry) have three attributes where all is required and all can use EL-expression.

Then we need a JSP file to demonstrate how we use the our searchCountry tag.

  • Here is the index.jsp file:
    <%@ page import="jsp.data.Country"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ page language="java" contentType="text/html; charset=UTF-8"%>
    <%@ taglib uri="/SearchTag" prefix="st"%>
    <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Country Liste</title>
        <style>
          .gradientdown {
            background:  #e0e6ff;
            background: -webkit-linear-gradient(top, #e0e6ff 0%,#eeeeee 100%); /* Chrome10+,Safari5.1+ */
            background: -o-linear-gradient(#e0e6ff, #eeeeee); /* For Opera 11.1 to 12.0 */
            background: -moz-linear-gradient(top, #e0e6ff, #eeeeee); /* For Firefox 3.6 to 15 */
            background: linear-gradient(top, #e0e6ff 0%,#eeeeee 100%); /* W3C Standard syntax (must be last) */
          }
          table tr.data:nth-of-type(odd) { 
            background: #eeeeee; 
          }
        </style>
      </head>
      <body>
        <div style="max-width:600px; ">
          <%@ include file="/WEB-INF/header.jsp" %>
          <c:set var="field" scope="request" value="region"/>
          <c:set var="search" scope="request" value="a"/>
          <c:if test="${param.submit == 'submit'}">
            <c:set var="field" scope="request" value="${param.field}"/>
            <c:set var="search" scope="request" value="${param.search}"/>     
          </c:if>      
          <st:searchCountry  field="${field}" search="${search}" var="countryList" />
          <form  method="GET">Countries
            Field:<select name="field">
              <option "${field == 'name'}">selected="selected"</c:if> value="name">Name</option>
              <option "${field == 'fullName'}">selected="selected"</c:if> value="fullName">Full Name</option>
              <option "${field == 'capital'}">selected="selected"</c:if> value="capital">Capital</option>
              <option "${field == 'phoneCode'}">selected="selected"</c:if> value="phoneCode">Phone Number</option>
              <option "${field == 'topLevelDomain'}">selected="selected"</c:if> value="topLevelDomain">TLD</option>
              <option  "${field == 'region'}">selected="selected"</c:if>  value="region">Region</option>
              </select> 
              Search:<input name="search" type="text" width="10" value="${search}"/>
            <input name="submit" type="submit" value="submit"/>
          </form>
          <table >
            <tr class="gradientdown">
              <th style="width:40px;"><br /></th>
              <th style="width:100px;">Name</th> 
              <th style="width:200px;">Full Name</th>
              <th style="width:80px;">Capital</th>
              <th style="width:60px;">Phone code</th>
              <th style="width:60px;">TLD</th>
              <th style="width:80px;">Region</th>
            </tr>     
            <c:forEach   var="country" items="${countryList}"  >
              <tr class="data">
                <td style="text-align: center;">
                  <img src="${country.flag}" width="30" height="30"
                       alt="${country.name}" /></td>
                <td>${country.name}</td>
                <td>${country.fullName}</td>
                <td>${country.capital}</td>
                <td>${country.phoneCode}</td>
                <td>${country.topLevelDomain}</td>
                <td>${country.region}</td>
              </tr>
            </c:forEach>
          </table>
          <%@ include file="/WEB-INF/footer.jsp" %>
        </div>
      </body>
    </html>

    For those who participate in the review: create a JSP file in Netbeans and replace generated code for the JSP with that shown above (the JSP file name is index).

Creating Deployment descriptor.

  • To run this JSP you have to deploy it to a web-server or a Application server. To deploy means to install the JSP with some instruction to a such server.
  • The instructions are mainly defined to be deployment descriptors. The standard part of the deployment descriptor should be in an XML-file with the name web.xml.

    You may need to create a Deployment descriptor file, web.xml in Netbeans.

  • The contents of the web.xml file should look like this:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
     http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
      <session-config>
        <session-timeout>
          30
        </session-timeout>
      </session-config>
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
  • This file starts with the normal xml tag for a XML file and the root tag for the deployment descriptor is web-app. Every ting inside the last tag is to tell the server about our application, which in this case is a JSP file.
  • If no session-timeout (the server ends the service of the application after this time) is given a standard timeout for the server is used as timeout for the application.
  • The welcome-file tag specifies the startup for our application, which in this case and our application is the welcome file index.jsp. Reorganize the welcome-file-list to what is shown above.

Creating Web-server Deployment descriptor.

  • The context-root (in example /CustomSimpleTag) for the application will in most cases be specified by a server vendor deployment descriptor.

    For those who participate in the review: create a Glassfish deployment descriptor in Netbeans.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, 
    Inc.//DTD GlassFish Application Server 3.0 Servlet 3.0//EN" 
    "http://www.sun.com/software/appserver/dtds/sun-web-app_3_0-0.dtd">
    <sun-web-app error-url="">
      <context-root>/CustomSimpleTag</context-root>
      <class-loader delegate="true"/>
      <jsp-config>
        <property name="keepgenerated" value="true">
          <description>
            Keep a copy of the generated servlet class' java code.
          </description>
        </property>
      </jsp-config>
    </sun-web-app>

Run the application.

  • For those who participate in the review: right click the Web-project and select Run.
  • This results in that the application will be deployed to the server and started.
  • The browser will display:
© 2010 by Finnesand Data. All rights reserved.
This site aims to provide FREE programming training and technics.
Finnesand Data as site owner gives no warranty for the correctness in the pages or source codes.
The risk of using this web-site pages or any program codes from this website is entirely at the individual user.