<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
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:
Use the setPageContext() method of the Tag to set the current PageContext for it to use.
Use the setParent() method to set any parent of the encountered Tag (or null if none).
Set any attributes defined to be given to the Tag.
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.
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.
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
In the '/WEB-INF/classes/com/acme/tag/' directory, create a new class called 'HelloWorldTag.java' with the following content:
package com.acme.tag;
Having done that, let us add some import statements:
import javax.servlet.jsp.*;import javax.servlet.jsp.tagext.*;
Now, we need to implement the javax.servlet.jsp.tagext.Tag interface:
public class HelloWorldTag implements Tag{
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;
Now lets implement a constructor for your Tag:
public HelloWorldTag() { super(); }
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; }
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.
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; }
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.
But we are not done yet. We need to include the following method:
public void release() {}
The method above is where you normally do your cleaning up. Due to the nature of this simple tag, we will not do anything.
We also need the following method:
public void setPageContext(final javax.servlet.jsp.PageContext pageContext) { this.pageContext=pageContext; }
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.
The JSP container also calls the following method:
public void setParent(final javax.servlet.jsp.tagext.Tag parent) { this.parent=parent; }
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.
Finally, this method has to be implemented:
public javax.servlet.jsp.tagext.Tag getParent() { return parent; }}
By now, your HelloWorldTag.java should look like this.
Compile your Tag.
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'.
Create a text file called taglib.tld in your '/WEB-INF/' directory
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">
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>
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.
Describe your Tag:
<tag> <name>helloWorld</name> <tagclass>com.acme.tag.HelloWorldTag</tagclass> <bodycontent>empty</bodycontent> <info>A Hello World tag</info> </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.
End your Tag library descriptor:
</taglib>
By now, your taglib.tld should look like this.
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" %>
Referencing the JAR file containing a Tag library from a JSP page
<%@ taglib uri="/WEB-INF/mytags.jar" prefix="mt" %>
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" %>
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.
Open the 'web.xml' file found in the '/WEB-INF/' directory of your web-application.
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>
Notice that as we are not about to package our Tag library, we point out the taglib.tld file instead of any JAR file.
Make sure that you save the 'web.xml' file.
By now, your web.xml should look like this.
6 Using your Tag
In order to use your new Tag, we make a simple JSP that uses it.
Create a file called 'helloWorld.jsp' in your '/taglib-tutorial-web/' directory.
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>
The first line above tells our JSP container where it will find the descriptor for our Taglib.
Your helloWorld.jsp page will now look like this.
7 Testing your Tag
Ok, Let us take your Tag for a test spin.
Make sure that Orion is running.
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