Developing a Simple Custom Tag

Unfortunately, using JSTL will not always provide the functionality you need; even when it can, there are circumstances when using your own custom tag might make the JSP simpler to maintain.

A custom tag is made up of two components:

  • A Java class file that implements the tag

  • An entry in a Tag Library Descriptor (TLD) file that defines the tag's name, its implementing Java class, and additional information necessary to deploy and use the tag

Just as with JSTL, using a custom tag requires a reference to the Tag Library Descriptor (TLD) at the start of the JSP. Multiple Tag Libraries can be used on the same Web page. After the TLD has been referenced, the custom tag from the TLD can be used like any other JSP tag.

Using a Simple Tag

To start writing and using TagLibs, you will implement a very simple custom tag that writes “Hello World” onto your Web page. This isn't a good use of a custom tag, but it will help you understand the principles involved and guide you through the deployment process. After this simple example, you will look at how to use custom tags to remove any remaining Java scriptlets from your JSP applications.

Every custom tag potentially has three parts:

  • The starting tag, such as <demo:hello>

  • The ending tag, such as </demo:hello>

  • The tag's body, which is the text between the start and end tags

A tag that does not have a body is called an empty tag and is usually written as <demo:hello/>.

The example in Listing 14.3 shows an empty tag that inserts Hello World on the JSP page.

Listing 14.3. Full Text of helloTag.jsp
<%@ taglib prefix="demo" uri="/demo.tld" %>
<HTML>
  <HEAD><TITLE>Tag Library Hello Demo</TITLE></HEAD>
  <BODY>
    <demo:hello/>
  </BODY>
</HTML>

The very first line of the JSP in Listing 14.3 defines the Tag Library and associates the tags in the library with the demo prefix. Unlike the JSTL tag libraries the custom tag doesn't use an absolute URI for the library location but defines a tag library name that will be mapped onto the actual tag library location in the Web Application deployment descriptor.

The tag itself is used inside the HTML <BODY> tag, and its name is hello.

Defining Custom Java Tags

You define custom tags by using Java classes that implement one of the javax.servlet.jsp.tagext interfaces shown in Table 14.3.

Table 14.3. Interfaces for Custom Tags
Java InterfaceDescription
TagImplement this interface for simple tags that do not need to process the tag body.
IterationTagImplement this interface for tags that need to process the body text more than once to implement an iterative loop.
BodyTagImplement this interface for tags that need to process the text in the tag body.

Implementing these interfaces requires that you define several methods to manage the lifecycle of the custom tag. To simplify custom tag development, two support classes are provided in the javax.servlet.jsp.tagext package. These classes provide default behavior for each of the required interface methods, and you will simply override the methods you require. Table 14.4 shows the two supporting classes.

Table 14.4. Support Classes for Custom Tags
java ClassDescription
TagSupport implements TagExtend this class for tags that do not have a body or do not interact with the tag body.
BodyTagSupport implements Tag,IterationTag, BodyTagExtend this class when the tag body must be processed as partof the tag, such as an iterative tag or a tag that interprets the body in some way

The Tag, TagIteration, and TagSupport interfaces in the javax.servlet.jsp.tagext package define several methods that control the processing of the custom tag. Figure 14.1 summarizes the lifecycle of a Tag Library object.

Figure 14.1. The Custom Taglifecycle


The doStartTag() Method

The doStartTag() method is called once when the start tag is processed. This method must return an int value that tells the JSP how to process the tag body. The returned value must be one of the following:

  • Tag.SKIP_BODY The tag body must be ignored. The TLD should define the <body-content> tag as empty.

  • Tag.EVAL_BODY_INCLUDE The body tag must be evaluated and included in the JSP page. The TLD should define the <body-content> tag as JSP for tags that extend TagSupport, or JSP or tagdependent for tags that extend BodyTagSupport.

The doEndTag() Method

The doEndTag() method is called once when the end tag is processed. This method must return an int value indicating how the remainder of the JSP page should be processed:

  • Tag.EVAL_PAGE Evaluate the rest of the page.

  • Tag.SKIP_PAGE Stop processing the page after this tag.

Where a tag has an empty body, the doEndTag() method is still called after the doStartTag() method.

The release() Method

The release() method is called once when the JSP has finished using the tag and is used to allow the tag to release any resources it may have acquired. This method's return type is void.

The doAfterBody() Method

The doAfterBody() method is called after the tag body has been processed and before the doEndTag() method is called. This method is only called for classes that implement IterationTag or BodyTag (those that extend BodyTagSupport). It must return one of the following values to the JSP page indicating how the tag body should be processed:

  • IterationTag.EVAL_BODY_AGAIN This value is used to inform the page that the tag body should be processed once more. The JSP processing will read and process the tag body and call the doAfterBody() method once more after the body has been processed again.

    When returning the EVAL_BODY_AGAIN result, this method will typically change some value so that when the tag body is processed again, different output is written to the Web page. A simple example would be a tag that executes a database query in the doStartTag() method and reads each row of the result set. While there are more rows to process EVAL_BODY_AGAIN is returned. After the last row is processed SKIP_BODY is returned.

  • Tag.SKIP_BODY This value marks the end of the processing of the tag body.

The doInitBody() Method

The doInitBody() method is called once after the doStartTag() method but before the tag body is processed. doInitBody() is only used in tags that implement the BodyTag interface (those that extend BodyTagSupport). This method is not called if the doStartTag() method returns SKIP_BODY. The doInitBody() method returns void.

Defining The “Hello World” Custom Tag

If all the lifecycle methods and their return values have left you a little bewildered then a simple example should help to clear things up. The example Hello World tag shown in Listing 14.3 does not have a body, so it need only implement the Tag interface, which is best achieved by extending the TagSupport class and overriding the required methods, as shown in Listing 14.4.

Listing 14.4. Full Text of HelloTag.java
package examples;

import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class HelloTag extends TagSupport {
   public int doStartTag() throws JspException {
      try {
         pageContext.getOut().print("Hello World");
      } catch (Exception ex) {
         throw new JspTagException("HelloTag: "+ex);
      }
      return SKIP_BODY;
   }

    public int doEndTag() {
      return EVAL_PAGE;
   }

   public void release() {
   }
}

All the work in this custom tag is done in the doStartTag() method. The current output stream is obtained from the page context and used to print the "Hello World" string:

pageContext.getOut().print("Hello World");

The custom tag class is defined as part of the custom tag in the TLD file for the library, as shown next.

The Tag Library Descriptor (TLD)

TLD files map the tag name used in the JSP page onto the Java class that implements the tag. A TLD file is written in XML and an example is given in Listing 14.5, which shows the TLD file for the “Hello World” tag.

Listing 14.5. Full Text of demo.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
  <tlib-version>1.0</tlib-version>
  <jsp-version>2.0</jsp-version>
  <short-name>demo</short-name>
  <tag>
    <name>hello</name>
    <tag-class>demo.HelloTag</tag-class>
    <body-content>empty</body-content>
  </tag>
</taglib>

At the present time, the J2EE RI from Sun Microsystems does not include any support for generating this file from within deploytool. You will have to write your TLD files by hand and include them in your Web application.

To write a TLD, you will need to be familiar with XML. If you are new to XML, this might be a good time to have a quick look at Appendix A, “An Overview of XML,” before continuing to learn how TLD files work. The use of XML in enterprise applications is also discussed on Day 16, “Integrating XML with J2EE.”

The start of the TLD file defines the Tag Library and JSP specification conformance for this TLD. After the Tag Library version information is defined, the rest of the TLD is used to specify the custom tags in the library.

In the TLD, a <tag> tag defines a custom tag. Several custom tags can be defined in a single library. The minimal requirements for each custom tag are as follows:

  • The tag name to be used on the Web page

  • The Java class name that implements the tag

  • The type of tag body (see Table 14.5)

In the following example, the tag class is demo.HelloTag, and the tag name is hello:

<tag>
  <name>hello</name>
  <tag-class>demo.HelloTag</tag-class>
  <body-content>empty</body-content>
</tag>

In this case, the <body-content> tag defines the tag to have an empty body. The possible values for the <body-content> tag are shown in Table 14.5.

Table 14.5. Tag Body Contents
TagDescription
emptyThe tag body must be empty. The page translation will fail if the developer puts any text between the start and end tags.
JSPThe tag contains JSP data and will normally be processed in the same manner as other parts of the page.
tagdependentThe text between the start and end tags will be processed by the Java class and will not be interpreted as JSP tagged content (the JSTL sql:query element is an example of this style of tag).

The <body-content> type must be compatible with the way the Java code processes the tag.

The TLD file itself is normally included directly in your Web application (as this simplifies distribution). The deployment descriptor <taglib> element maps the URI used on the JSP to the location of the TLD in the Web application. It is conventional to include the TLD file in the WEB-INF directory along with the deployment descriptors. The following entry defines the TLD location for the example tag:

<jsp-config>
  <taglib>
    <taglib-uri>/demo.tld</taglib-uri>
    <taglib-location>/WEB-INF/demo.tld</taglib-location>
  </taglib>
</jsp-config>

You will see how to add the <taglib> element using deploytool in the next section. If you use an absolute URI, as shown in the JSTL examples, you do not need to include a <taglib> directive in the DD.

Deploying a Tag Library Web Application

To deploy a Web Application that uses a custom Tag Library, you will follow the same steps as for a Web Application using JSTL. Using deploytool, you must add the TLD file and the Tag Library implementation class files when you create the Web component.

Using deploytool the mapping of the Tag Library URI to the TLD file location is specified on the File Refs dialogue page for the Web application. Figure 14.2 shows the mapping for the simple hello tag example.

Figure 14.2. Mapping the Tag Library URI to the TLD.


A pre-supplied WAR file is on the accompanying Web site as Day14/examples/j2ee-ri/examples.war. You can open the WAR file with deploytool and deploy the examples using the File, Deploy menu option.

Alternatively, you can use the asant build files supplied on the Web site to build and deploy the example using

asant build deploy

Use the following URL to view the page

http://localhost:8000/examples/helloTag

Beyond Simple Tags

You would not normally write tags as simple as the Hello World example. Even so, simple tags like this do serve a purpose. They can be used to retrieve information from the system and display it via the JSP page. The mechanics of accessing the information are hidden inside the custom tag code and are not shown on the JSP page. Hiding complex operations (perhaps a JNDI lookup operation or obtaining data from a database) helps simplify the writing of the Web page.

However, without the ability to pass information into the tag, this functionality has limited use.

Tag Libraries support the following two ways of passing information from the page into the tag:

  • Via attributes passed in with the tag

  • Via the text in the body of the tag

Using attributes is the most common approach and is discussed in detail in the following section. Use of tag-specific body data is outside the scope of today's exercise.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.249.210