Tag Libraries

JSP Tag Libraries allow you to define and use JSP tags in much the same way as you define and use functions in standard programming languages. For a simple example:

Things to notice about these three files.

SimpleTagExample.jsp

cwp-taglib.tld
The .tld file for a library describes a (single) tag library and the various tags in that library. (See listing 20.25 in the text and the actual cwp-taglib.tld file.) Here is the example tag entry in the cwp-taglib.tld file.
  <tag>
    <!-- The tag name -->
    <name>example</name>

    <!-- The .Java file that implements the tag -->
    <tagclass>cwp.tags.ExampleTag</tagclass>

    <!-- A comment describing the tag -->
    <info>Simplest example: inserts one line of output</info>

    <!-- Whether there is a body, and how to process it.
         If the body is standard jsp, the entry would be "jsp" instead of "empty" -->
    <bodycontent>empty</bodycontent>
  </tag>

ExampleTag.java
This is a Java file that implements the <cwp:example> tag.

Methods in tag classes may be called at three stages in the processing of a tag:

The .Java file that implements tags should have a method for each of these elements it wants to handle. The methods are called, respectively: doStartTag(), doAfterBody(), doEndTag().

In this example, the <cwp:example /> tag was self-terminating, so only the doStartTag() method was defined. All that method did was generate a line of output:

out.print("Custom tag example (cwp.tags.ExampleTag)");
Notice that doStartTag() returns an int. The constant SKIP_BODY, which is presumably defined in TagSupport (of which ExampleTag is a subclass, see http://java.sun.com/j2ee/sdk_1.3/techdocs/api/), tells the tag processor not to look for or use the body, i.e., the text, if any, between the start of this tag and the end of this tag. (In this case, there is nothing there.)

Do an experiment with SimpleTagExample.jsp and ExampleTag.java.

  1. Modify
    <H1><cwp:example /></H1>
    <cwp:example />
    to be
    
    <dl>
    <dt><h2>Original</h2>
    <dd><H2><cwp:example /></H2>
    <cwp:example />
    <dt><h2>Revised</h2>
    <dd><H2><cwp:example>text</cwp:example></H2>
    <cwp:example>stuff</cwp:example>
    </dl>

  2. Access SimpleTagExample.jsp http://localhost:8080/CoreWebProgramming/cwp/SimpleTagExample.jsp again.

  3. Any differences? Why or why not?

  4. Change the return value of doStartTag() from SKIP_BODY to EVAL_BODY_INCLUDE.

  5. Any differences? Why or why not?

  6. Add
    public int doEndTag() {
      try {
        JspWriter out = pageContext.getOut();
        out.print("End tag";
      }
      catch(IOException ioe) {
        System.out.println("Error in ExampleTag: " + ioe);
      }
      return (EVAL_PAGE);
    }
    

  7. Any differences? Why or why not?

  8. Let's give the body of our tag a background color.

    1. Add code that prints <span style='background-color:teal'> at the end of the doStartTag().

    2. Add code that prints </span> at the start of the doEndTag().

    3. Compile ExampleTag.java and put the ExampleTag.class file into %TOMCAT_HOME%/webapps/CoreWebProgramming/WEB-INF/classes/cwp/tags.

    4. Access SimpleTagExample.jsp http://localhost:8080/CoreWebProgramming/cwp/SimpleTagExample.jsp again.

Custom Tags with attributes

Like all tags, custom jsp tags may have attributes. To add an attribute to a custom tag, you have to do two things.
  1. Add the attribute (and information about it) to the .tld file.
  2. Add a setAttribute() method to the .Java file that implements the tag.
Let's pass the background color into the tag as a tag attribute so that we can write <cwp:example bgColor="red">text</cwp:example>
  1. Add a bgColor attribute to the tag.
    <tag>
      <name>example</name>
      <tagclass>cwp.tags.ExampleTag</tagclass>
      <info>Simplest example: inserts one line of output</info>
      <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT
      <bodycontent>empty</bodycontent> -->
      <!-- We now have a body, and we are using 3.2.4.
           Use "jsp" instead of "empty". -->
      <bodycontent>jsp</bodycontent>
      <attribute>
        <name>bgColor</name>
      </attribute>
    </tag>
    

  2. Add a bgColor variable and a setBgColor() method to ExampleTag.java.
      private String bgColor = null;
    
      public void setBgColor(String color) {bgColor = color;}
    

  3. Change the code to use this attribute as the background color:   out.print("<span style='background-color:" + bgColor + "'>");

  4. Compile ExampleTag.java and put the ExampleTag.class file into %TOMCAT_HOME%/webapps/CoreWebProgramming/WEB-INF/classes/cwp/tags.

  5. Change the SimpleTagExample.jsp file to pass the color to the tag.
    <H1><cwp:example bgColor=red>text</cwp:example></H1>
    <cwp:example bgColor=pink>stuff</cwp:example>

  6. Access SimpleTagExample.jsp http://localhost:8080/CoreWebProgramming/cwp/SimpleTagExample.jsp again.

  7. The result:
    org.apache.jasper.compiler.ParseException:
      C:\jakarta-tomcat-3.2.4\webapps\CoreWebProgramming\cwp\Copy4TagExamples\SimpleTagExample.jsp(20,25)
      Attribute value should be quoted

  8. Quote the attributes and try again.
Now let's pass the background color to the tag from a variable in the SimpleTagExample.jsp file.
  1. Declare a variable in the SimpleTagExample.jsp file and refer to it from the tag.
    <BODY>
    <%! String bgc="orange"; %>
    <H1><cwp:example bgColor="red">text</cwp:example></H1>
    <cwp:example bgColor="<%= bgc %>">stuff</cwp:example>
    </BODY>
    

  2. Access SimpleTagExample.jsp http://localhost:8080/CoreWebProgramming/cwp/SimpleTagExample.jsp again.

  3. Why didn't it work? We have to declare the attribute as eligible to take a JSP expression. Add <rtexprvalue>true</rtexprvalue> to the cwp-taglib.tld file.
    ...
      <attribute>
        <name>bgColor</name>
        <rtexprvalue>true</rtexprvalue>
      </attribute>
    ...

  4. Try again. Still didn't work. Why?

  5. We must convince Tomcat to read the cwp-taglib.tld file again. Rename the SimpleTagExample.jsp file (or the directory it is in) and try again.
In the assignment, you will have to access a color computed in your bean rather than from a variable in the .jsp. Other than that, you should be able to follow this example pretty closely.