ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Designing JSP Custom Tag Libraries
Pages: 1, 2

The JSP

Once your TLD and tag handlers are created, you can begin accessing the tags in your JSP. You declare that a JSP page will use tags defined in a tag library by including a taglib directive in the page before any custom tag is used. The prefix attribute is a shortcut to referencing the library throughout the page.



Sample Hello.jsp:

<%@ taglib uri="/oreillySample.tld" prefix="sample" %>
<html>
        <head>
                <title>Your Standard Hello World Demo</title>
        </head>
        <body bgcolor="#ffffff">
                <hr />
                <sample:hello name="Sue"/>
                <hr />
        </body>
</html>

The HTML source output from this JSP would look like:

<html>
        <head>
                <title>Your Standard Hello World Demo</title>
        </head>
        <body bgcolor="#ffffff">
                <hr />
		      <table border="1">
		        <tr><td> Hello Sue </td></tr>
                </table>
                <hr />
        </body>
</html>

You can see how the tag was evaluated and the contents of the tag inserted into the output stream.

If you wanted to add functionality to our tag to make it more flexible, say to evaluate a body a certain number of times and make the name attribute evaluated at runtime, you can do so fairly easily with a few changes. First you would make the following changes to the TLD file. The tag definition would look like

  <tag>
    <name>hello</name>
    <tagclass>oreilly.examples.Hello </tagclass>
	<!-- Allow for a body to be included for this tag -->
    <bodycontent>JSP</bodycontent>
    <info>
	This is a simple hello tag.
    </info>
    
    <!-- Optional attributes  -->
    <!-- personalized name -->
    <attribute>
      <name>name</name>
      <required>false</required> 
	   <rtexpvalue>true</rtexpvalue>
    </attribute>
    <!-allow for the jsp coder to specify how many times to iterate -->
    <attribute>
      <name>iterations</name>
      <required>false</required> 
	   <rtexpvalue>false</rtexpvalue>
    </attribute>

</tag>

Then you must alter the handler class by extending TagBodySupport and implementing the body methods if you wanted different behavior from that provided in the base class implementation. The handler class would now look like

public class Hello extends BodyTagSupport {
	private String name=null;
    private int iterations=1;

	/**
     * Getter/Setter for the attribute name as defined in the tld file 
     * for this tag
     */
	public void setName(String value){
		name = value;
	}

	public String getName(){
		return(name);
	}
	/**
     * Getter/Setter for the attribute iterations as defined in the tld file 
     * for this tag
     */

	public void setIterations(String value){
     try {
       iterations = Integer.parseInt(value);
     } catch(NumberFormatException nfe) {
       iterations = 1;
     }	
   }

	public String getIterations(){
		return(Integer.toString(iterations));
	}

    public int doStartTag() throws JspTagException{
	  try {
        JspWriter out = pageContext.getOut();
        out.println("<table border=\"1\">");
	     if (name != null)
	      out.println("<tr><td> Hello " + name + " </td></tr>");
        else
	      out.println("<tr><td> Hello World <td></tr>");
	  } catch (Exception ex) {
	    throw new JspTagException("All is not well in the world." + ex );
	  }
	  // Evaluate the body if there is one
	  return EVAL_BODY_TAG;
    }

	public int doEndTag()throws JspTagException {
	   try {
        	JspWriter out = pageContext.getOut();
	       out.println("</table>");
	   } catch (Exception ex){
	    	throw new JspTagException("All is not well in the world." + ex);
	   }
	}

	public int doAfterBody() throws JspTagException {
    if (iterations-- >= 1) {
      BodyContent body = getBodyContent();
      try {
		// Make sure we put anything in the output stream in the 
		// body to the output stream of the JSP
        JspWriter out = body.getEnclosingWriter();
        out.println(body.getString());
        body.clearBody(); // Clear for next evaluation
      } catch(IOException ioe) {
        throw new JspTagException("Error in Hello tag doAfterBody " + ioe);
      }
      return(EVAL_BODY_TAG);
    } else {
      return(SKIP_BODY); 
	}
}

Now let's make the simple changes in the JSP file. Our sample Hello.jsp looks like

<%@ taglib uri="/oreillySample.tld" prefix="sample" %>
<%!
    // allow a username to be passed in the request
    String userName = request.getParameter("NAME");
%>

<html>
        <head>
                <title>Your Standard Hello World Demo</title>
        </head>
        <body bgcolor="#ffffff">
                <hr />
                <sample:hello name="<%= userName %>" iterations="2">
			<tr><td><b>Have a nice day</b></td></tr>
			</sample:hello>
                <hr />
        </body>
</html>

If our JSP page was called like hello.jsp?NAME=Sue our output would look like

<html>
        <head>
                <title>Your Standard Hello World Demo</title>
        </head>
        <body bgcolor="#ffffff">
                <hr />
		      <table border="1">
		        <tr><td> Hello Sue </td></tr>
			  <tr><td><b>Have a nice day</b></td></tr>
			  <tr><td><b>Have a nice day</b></td></tr>
                </table>
                <hr />
        </body>
</html>

This simple example is but a small glimpse at the power of custom tag libraries. We examined how to create and use a simple tag library and then easily extend its functionality. The next article will examine some of the advanced features of tags, including defining scripting variables and cooperating tags. It will also go through working examples of each.

Sue Spielman is an associate editor for ONJava.com, covering JSP and Servlets technologies. She is also President and Senior Consulting Engineer for Switchback Software LLC.


Return to ONJava.com.