Understanding Struts Custom Tags

Saikat Goswami's picture
articles: 

If you write Java Server Pages, this article tries to bring together the pieces you need to know to write 'presentation logic'. This article is about custom tags, how to develop them and how to make maximum use of them. This article is also about tag libraries that come with Struts. What is covered is: what is a tag; what is a 'custom' tag; how you can build one; how they make life easier; and how Struts comes with tag libraries for developers to indulge.

Tag 101: What is a Tag anyway?

Anyone who has seen a HTML document has seen a tag. Simply put, a tag is some text enclosed between the characters "<" and ">". Tags have names, attributes and values. Tags may have a body or may be bodyless. An example of bodyless tag is:

<tagName1 attrtibute1="value1" attribute2="value2" />

Tags with a body have a start tag, a matching end tag and some content within them. An example of a tag with body is:

<tagName2 attribute1="value1" >
		<tagName3 attribute2="value2"/>
</tagName2>

End tags always start with the character "/".

What is a 'Custom Tag' then?

HTML Tags are pre-defined. You cannot write HTML tags with names you like. A 'custom' tag is something you write so that the compiler/interpreter understands what it is supposed to do. For example, if you write <TABLE ...>, the browser understands that a table has to be displayed. However, if you want to arrange your documents according to chapters, you cannot write something like <CHAPTER...>. The browser will not understand the tag, because it is not a pre-defined HTML tag.

A custom tag, is thus, a tag, you write in your Java Server Page. When the jsp compiler encounters that tag, it knows what to do with it. It generates the proper HTML after doing whatever it is supposed to do.

Dissecting a Custom Tag

From a custom tag developer's perspective, a custom tag (or 'tag extension') has three parts:

  • Write a Java class implementing one of the two interfaces, namely, javax.servlet.jsp.tagext.Tag or javax.servlet.jsp.tagext.BodyTag. Methods to implement include doStartTag(), doEndTag() for the Tag interface. Tag interface is implemented only for bodyless tags. For tags with body content, the BodyTag interface is implemented and the developer not only has to implement the doStartTag() and doEndTag() methods, but also doInitBody() and doAfterBody().

  • Write a tag library descriptor, (TLD, for short), which is a XML document containing information about all the custom tags. This file has .tld extension. The TLD file conforms to a DTD. A sample entry in the TLD looks like this:

    <tag>
       <name>TagName</name>
       <tagclass>package.name.TagClass</tagclass>
       <bodycontent>JSP</bodycontent>
       <attribute>
          <name>Attr1</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
       </attribute>
    </tag>

    Although not mandatory, the TLD file is usually placed under WEB-INF/tlds/.

  • Declare the TLD in the web.xml file. web.xml is the standard descriptor file for any web application. The TLD is declared like:

    <webapp>
       ....
       <taglib>
          <taglib-uri>/TLDNameAsDeclaredInTLD</taglib-uri>
          <taglib-location>/WEB-INF/tlds/my.tld</taglib-location>
       </taglib>
    </webapp>

Using a Custom Tag in your page

Now that the custom tag is built and deployed, it can be used in a JSP by:

  • Declaring the TLD as a directive:
    <@ taglib uri="TLDNameAsDeclaredInTLD" prefix="test" %>

  • Using a tag "Tag1", which is a part of the TLD, in the JSP page:

    <test:tag1 attr1="value1" attr2="value2" />

As soon as the runtime encounters the "test" tag, it knows a tag in that library is going to be used. In the above example, "tag1" in the library is used. When the runtime parses "<test:tag1", the doStartTag() method of "tag1" is triggered.

What is a software framework?

A software framework refers to a collection of classes and interfaces working in a cooperative fashion to facilitate application development. Just the way struts of a building holds the entire structure, a framework acts as a skeleton to an application.

Welcome to Struts

Struts framework is used for web applications where presentation data will change dynamically, and the choice of technology is Java. Struts is an open source project, and is a part of Apache Software Foundation. The latest version is 1.1.

Struts can be acquired from http://jakarta.apache.org/struts/acquiring.html.
You can download either a binary distribution or a source distribution. If you download binary distribution, the pre-requisite software applications are (a) Java Development Kit (Java version 1.2 or later), (b) a Servlet Container compatible with Servlet API specification 2.2 or later and JSP specification 1.1 or later and (c) an XML parser that is compatible with Java API for XML parsing specification 1.1 or later. If you have downloaded J2SE 1.4, then you do not have to worry about getting a parser, because J2SE 1.4 or later comes bundled with a parser.

If you choose to download the source distribution, then you have to download a plethora of software applications. http://jakarta.apache.org/struts/userGuide/installation.html gives you the entire list.

Bird's eye-view of Struts architecture

Struts uses the MVC design pattern, which stands for Model, View and Controller respectively. Controller is the component responsible for transferring data back and forth from the front-end (View) to the back-end (Model). Struts provides the controller (which is a servlet). View refers to the JSP's and Model refers to your business objects. They can be anything from Enterprise Java Beans, regular Java classes or Java Beans.

Overview of the common libraries

The Struts distribution contains four main tag libraries: html, bean, logic and nested for us to use in our JSP's. We will discuss only the three commonly used.

Brief description of the taglibs:
html: Contains tags to output standard HTML, including forms, textfields, checkboxes, radio buttons.
bean: Contains tags for accessing JavaBeans and their properties. Developers can also define new beans and set properties.
logic: Contains tags for generating conditional output, iteration capabilities and flow management.

Common features of Struts Tags

  • Automatic Scoping: Struts tags check all contexts (namely page, request, session, application) and use the first instance found. Developers do not have to explicitly "retrieve" objects from a particular scope. They may, however, specify a context.

  • Almost all Struts tags have attributes: id, scope, name, and property. id is the name of the variable to be used in the page, name is the name of the bean, property is the property of the bean to be set or accessed, scope is the context in which the bean is to be created or retrieved from.

  • Nested references to properties can be made like:
    property = "abc.def.ghi"
    which is equivalent to:
    getAbc().getDef().getGhi();

  • Indexed references, like:
    property="abc[3]"
    which is equivalent to:
    getAbc(3);
    or as a setter:
    setAbc(3, value);
    This is a new feature, added in Struts 1.1

HTML Taglib

The most important tag in this library is the FormTag, since it can be used in any page that requires user input, to be captured in a form. The beauty is that any tag used inside the form tag, will automatically detect the bean associated with the form, and populate it, when the user submits the form. Another useful feature of HTML tags is that they have full support for JavaScript mechanism. You have to configure JavaScriptValidatorTag in order to use it.
There are tags for rendering HTML image, link, and button. Interestingly, there is no tag for rendering a HTML table. A tag to look for is the ErrorsTag, which is required to display error messages on the page. After configuring the resource bundle, struts-config.xml, validation.xml and validator-rules.xml for error-handling, all one has to do is write "<html:errors/>" on the page where the error message needs to be displayed. Struts takes care of the rest.

All Struts HTML tags have some common properties, of which, name and styleClass stand out. name refers to the name of the ActionForm or JavaBean where the data is going to be gathered from. style and styleClass are used to specify the CSS files to be used to display these elements.

Bean Taglib

Tags in this library are responsible for rendering a bean, or bean property and creating a new JavaBean in any desired scope. Tags to look for, in this library, are cookie, define, header, message and struts. HeaderTag is used to retrieve any HTTP request header value. CookieTag is used to retrieve any value from a cookie or add any cookie in the response object. MessageTag is used for localization. Generally, <bean:message key="someKey">, renders value associated with "someKey" in the resource bundle. A common way of using this tag is to render page titles, labels. The titles, labels can be configured in the resource bundle like:

	title.mainPage=Welcome to my HomePage
	title.catalogue=Catalogue Page
	label.submit=Submit
	label.subscribe=Subscribe
And in the jsp page, you write:
	<bean:message key="label.subscribe">

This renders the text: "Subscribe".
The Struts tag exposes any Struts configuration object (ApplicationResourcesConfig, ActionConfig or any class in the org.apache.struts.config package).

Logic Taglib

Useful tags in this library, prevents writing Java code in JSP's. Tags used for conditional logic, are MessagesPresentTag, MessagesNotPresenttag, NoEqualTag, EqualTag. The IterateTag is useful for looping collections. RedirectTag and ForwardTag are used for rendering a HTTP redirect and forward respectively. The ForwardTag takes only one attribute, "name", which is the one specified in the global-forward element in struts-config.xml.

It is usually rare for a small project to write custom tags. What exists today, in the market is good enough for common tasks. Using custom tags mean cleaner JSP code, easier to maintain, reusable across applications. One point to note is that not all tags within the Struts libraries can be used outside Struts, but most can.

Struts is not the only destination if you are looking to add intelligence to your JSP's. Other places to look for tag libraries are:
http://jakarta.apache.org/taglibs
http://jsptags.com
http://java.sun.com/products/jsp/jstl/index.jsp

Prepared by Saikat Goswami, Boston, Massachussets, sai_nyc@hotmail.com

Comments

Very good. Information is sharp and very easy to read. I'd like more detail in the custom tags part of the article.

hi Tony,
i am having problem in iterating array of objects in the nested tag in struts.My code for that is

"MenuGroupForm" is my formbean and

"menuGroupLines" is the property which contains array of mybusinessobjects .

i want to set the values for my businessObject
setter methods.

Please give me a syntax with example for setting the values for mybusinessObject.

How about showing the entire process of creation of a taglib through a simple flowchart or Diagram ?
And 1 qk qs why is the Title 'Understanding Struts Custom Tags' , custom tags is generic for any J2EE application .Though the first part of the article deals with creation of a taglib in general ..."Any specific reason for using the name STRUTS ?
The effort is commendable ...but I think that there is scope for improvement in the article.

Hi Tony,

Once you write your own tags, put them in a tld file; then place the tld files under /WEB-INF. Bingo! You are all set to call the tags in your jsp.

Please let me know if you need assistance, and I will be glad to help.

-Sai

Hi ,
This article is good adn gives an idea about the practical points. However, I would like you to tell me about this. How does a struts custom tag acess the form bean? eg , . I have a a form bean which has an object of type MetaData and this object in turn has a field String id. I understand, somewhere getMetaData().getId() is done by the tag.But my point is how the tag knows about the form bean which contains meta data? I have indicated nothing in the property about the form bean? Does the tag choose the form bean associated with the current request through the action mapping? Please lemme know.

Basic and very effective for start or to learn struts as well as JSFaces

Understanding Struts Custom Tags !!! I was expecting to see some usage of custom tags in Struts ??!!!!

I would like to know how to use our own custom tags in struts !!!

Good article for a beginner,
but would also like to have included an example on how to create a fully functional custom tag.