<taglib:tutorial lesson="1"/>

In this part of the tutorial, we will build your first Tag, the ever-returning "Hello World" sample!

1 Lesson 1, Your first Tag

    In this part of the tutorial, we will build your first Tag, the ever-returning "Hello World" sample!

    First we will create the Tag, and then we will add a descriptor and finally we will test it.

    Throughout this tutorial, we will use the file structure defined in the setup section.

2 What is a Tag?

    A Tag is a class that implements the javax.servlet.jsp.tagext.Tag interface. It is used to encapsulate functionality that can be used from a JSP page. Examples might be conditional logic, database access, iterations and so on.


    Figure 1: The Tag interface.

    Currently, a Tag can be either of two flavours (a third showing up with JSP 1.2): Body Tag or Tag (sometimes referred to as 'simple Tag'). We will focus on the Tag in this lesson, and look at the Body Tag in lesson 3. For now, lets just say that the body of a Tag is evaluated once, while the body of a Body Tag might be evaluated multiple times.


    Figure 2: Tag interaction.

    As seen in figure 2 above, when a JSP page is parsed and a tag is encountered, the Container will:

    1. Use the setPageContext() method of the Tag to set the current PageContext for it to use.

    2. Use the setParent() method to set any parent of the encountered Tag (or null if none).

    3. Set any attributes defined to be given to the Tag.

    4. Call the doStartTag() method. This method can either return EVAL_BODY_INCLUDE or SKIP_BODY. If EVAL_BODY_INCLUDE is returned, the Tags body will be evaluated. If SKIP_BODY is returned, the Container will not evaluate the body of the Tag.

    5. Call the doEndTag() method. This method can either return EVAL_PAGE or SKIP_PAGE. IF EVAL_PAGE is returned, the Container will continue to evaluate the JSP page when done with this Tag. If SKIP_PAGE is returned, the Container will stop evaluating the page when it's done with this Tag.

    6. Call the release() method. This method can be used by the Tag developer to release any resources that the Tag was using. Please notice that it is up to the Container to call the release() method when seemed fit, so you can't rely on this method being called at any specific time. In theory, this method could be called 12 days after the Tag was used. For this reason, any code that must be executed at the end of the Tag usage should be called from the doEndTag() method (see 5 above).

    Now, the PageContext passed into the Tag by the Container is a very interesting class from a Tag development perspective.


    Figure 3: The PageContext class.

    With the help of this class, a lot of neat stuff can be accomplished. For example, we will use it's getOut() method to get hold of the pages JspWriter so that we can write directly to the page. Or we could use it to get hold of the Page, Response, Request, Session or Application object. Or how about forwarding and including other pages?

    Whenever something goes wrong in the doStartTag() or doEndTag() methods, a JspTagException might be thrown.


    Figure 3: The JspTagException class.

    Enough talked about the Tag interface. If you want to learn more or get a deeper understanding, read the JSP API or the JSP 1.1 Specification.

3 Writing the Hello World Tag

    We will now develop our first Tag. As this is our first Tag, we will not use any of the existing convenience classes for writing the Tag, but instead implement the necessary methods of the Tag interface.


    Figure 4: The HelloWorldTag

    1. In the '/WEB-INF/classes/com/acme/tag/' directory, create a new class called 'HelloWorldTag.java' with the following content:


      package com.acme.tag;

      Listing 1: Starting off the HelloWorldTag.java file.

    2. Having done that, let us add some import statements:


      import javax.servlet.jsp.*;
      import javax.servlet.jsp.tagext.*;
      Listing 2: Adding the import statements.

    3. Now, we need to implement the javax.servlet.jsp.tagext.Tag interface:


      public class HelloWorldTag implements Tag
      {
      Listing 3: Implementing the Tag interface.

    4. Now, we need to keep track of the Tag's parent and the PageContext, so lets add the following variables:


      private PageContext pageContext;
      private Tag parent;
      Listing 4: Adding some variables.

    5. Now lets implement a constructor for your Tag:


      public HelloWorldTag()
      {
      super();
      }
      Listing 5: Adding a constructor.

    6. Next we will implement the method that gets called at the start of your tag:


      public int doStartTag() throws javax.servlet.jsp.JspTagException
      {
      return SKIP_BODY;
      }
      Listing 6: Implementing the doStartTag method.

      Note how this method returns the SKIP_BODY value. This will make sure that no evaluation of the tags body will take place. If we wanted evaluation of the body of the tag, we would have returned EVAL_BODY_INCLUDE instead.

    7. Following that, we will implement the method that gets called at the end of your tag:


      public int doEndTag() throws javax.servlet.jsp.JspTagException
      {
      try
      {
      pageContext.getOut().write("Hello World!");
      }
      catch(java.io.IOException e)
      {
      throw new JspTagException("IO Error: " + e.getMessage());
      }
      return EVAL_PAGE;
      }
      Listing 7: Implementing the doEndTag method.

      The method above will try to write "Hello World!" to the output stream back to the client, which in the end is our JSP page.

      Note that the method returns the EVAL_PAGE value. This means that the rest of the JSP page will be evaluated. If you don't want that to happen, you would return the SKIP_PAGE value.

    8. But we are not done yet. We need to include the following method:


      public void release() {}
      Listing 8: Implementing the release method.

      The method above is where you normally do your cleaning up. Due to the nature of this simple tag, we will not do anything.

    9. We also need the following method:


      public void setPageContext(final javax.servlet.jsp.PageContext pageContext)
      {
      this.pageContext=pageContext;
      }
      Listing 9: Implementing the setPageContext method

      The method above gets called by the JSP container and is used to set the Tag's PageContext. You will never have to worry about this method, as long as you just remember to let your Tag remember it's PageContext.

    10. The JSP container also calls the following method:


      public void setParent(final javax.servlet.jsp.tagext.Tag parent)
      {
      this.parent=parent;
      }
      Listing 10: Implementing the setParent method

      The method above gets called by the JSP container and is used to set the Tag's parent-Tag. As with the PageContext, you need to remember your parent.

    11. Finally, this method has to be implemented:


      public javax.servlet.jsp.tagext.Tag getParent()
      {
      return parent;
      }
      }
      Listing 11: Implementing the getParent method

      By now, your HelloWorldTag.java should look like this. Store the sourcecode in the /WEB-INF/classes/com/acme/tag/ directory as HelloWorldTag.java

    12. Compile your Tag. If needed, details are given here. The result should be a file named HelloWorldTag.class in the /WEB-INF/classes/com/acme/tag/ directory.

4 Describing your Tag

    Now that the Tag is compiled and ready, we need to write a descriptor for it to be able to use it from a JSP. We will call the descriptor 'taglib.tld'.

    1. Create a text file called taglib.tld in your '/WEB-INF/' directory

    2. Start with the following XML header:


      <?xml version="1.0" encoding="ISO-8859-1" ?>
      <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
      "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
      Listing 12: The XML header.

    3. Start describing your Tag library:


      <taglib>
      <tlibversion>1.0</tlibversion>
      <jspversion>1.1</jspversion>
      <shortname>mt</shortname>
      <uri>http://www.orionserver.com/tutorials/mytags.jar</uri>
      <info>My first Tag library</info>
      Listing 13: Describing the Tag Library.

      The <shortname> tag above is how you are going to reference your Tag library from your JSP page. As you can probably guess, although we are only using one Tag so far, a Tag library can hold as many tags as you like.

      The <uri> tag above is used as a unique identifier for your Tag library.

    4. Describe your Tag:


      <tag>
      <name>helloWorld</name>
      <tagclass>com.acme.tag.HelloWorldTag</tagclass>
      <bodycontent>empty</bodycontent>
      <info>A Hello World tag</info>
      </tag>
      Listing 14: Describing the Tag.

      The <bodycontent> tag tells us that this tag will not contain any body. If a body is found, the JSP container will produce an error. If we had liked to evaluate the body of the tag, we would have made that value one of the following:

      tagdependent, this means that any body of the tag would be handled by the tag itself, it can be empty.

      jsp, this means that the JSP container should evaluate any body of the tag, but it can also be empty.

    5. End your Tag library descriptor:


      </taglib>
      Listing 15: Ending the Tag Library descriptor.

    By now, your taglib.tld should look like this. Store the descriptor in the /WEB-INF/ directory as taglib.tld.

5 Reference your Tag library

    In order to use our Tag library from a JSP page, the Tag library has to be referenced. This can be done in a number of ways, such as:

    • Referencing the Tag library descriptor of an unpacked Tag library from a JSP page


      <%@ taglib uri="/WEB-INF/taglib.tld" prefix="mt" %>
      Listing 16: Referencing a unpacked Tag library from a JSP page.

    • Referencing the JAR file containing a Tag library from a JSP page


      <%@ taglib uri="/WEB-INF/mytags.jar" prefix="mt" %>
      Listing 17: Referencing a JAR:ed Tag library from a JSP page

    • Defining a reference to a Tag Library (or descriptor) from the web-application descriptor and define a short name for the JSP page to use for referencing this Tag library


      <%@ taglib uri="mytags" prefix="mt" %>
      Listing 18: Referencing a Tag library reference

    In my humble opinion, the nicest way is to define a reference to the Taglib descriptor from the web-applications descriptor. This way, we don't have to change our JSP pages at a later time when we decide that we want to package our Tag library into a JAR file.

    1. Open the 'web.xml' file found in the '/WEB-INF/' directory of your web-application.

    2. Add the following lines right before the last line of the file:


      <taglib>
      <taglib-uri>mytags</taglib-uri>
      <taglib-location>/WEB-INF/taglib.tld</taglib-location>
      </taglib>
      Listing 19: Adding a Tag library reference to the Web-modules descriptor.

      Notice that as we are not about to package our Tag library, we point out the taglib.tld file instead of any JAR file.

    By now, your web.xml should look like this. Store the descriptor in the /WEB-INF/ directory as web.xml.

6 Using your Tag

    In order to use your new Tag, we make a simple JSP that uses it.

    1. Create a file called 'helloWorld.jsp' in your '/taglib-tutorial-web/' directory.

    2. Write the following into the file:


      <%@ taglib uri="mytags" prefix="mt" %>
      <HTML>
      <HEAD>
      <TITLE>Hello World!</TITLE>
      </HEAD>
      <BODY BGCOLOR="#FFFFFF">
      <HR>
      <mt:helloWorld/>
      <HR>
      </BODY>
      </HTML>
      Listing 20: A sample JSP page.

      The first line above tells our JSP container where it will find the descriptor for our Taglib.

    By now, your helloWorld.jsp should look like this. Store the file in the taglib-tutorial-web/ directory as helloWorld.jsp.

7 Testing your Tag

    Ok, Let us take your Tag for a test spin.

    Open the URL http://localhost/taglib/helloWorld.jsp in a normal web browser. Hopefully the result looks like this.

    Continue with lesson 2, "Your first parameterized Tag".

Copyright © 2005 IronFlare AB