Article
Use Custom Tags to Aggregate RSS Feeds into JSP-Based Web Apps
Compiling the Tag Handler Class
To compile the tag handler class, make sure you have the Servlet and JSP classes in your classpath. If you’re using Tomcat 4, these can be found in the $TOMCAT_HOME/common/lib/servlet.jar file. The resulting class file should be placed under the WEB-INF/classes directory of your Web application, in the appropriate directory/package structure.
Describing the Tag
The next step is to describe the custom tag using an XML file called a tag library descriptor, or TLD file. This step is necessary because it allows us to define how the custom tag will be used on the page, the name of its attributes, and so on. Starting at the top, we have all the usual XML header information:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
Next, we have the start of the tag library definition. Although custom tags are reusable, they must be defined within the context of a tag library -- a collection of one or more tags that are typically related in some way. This block of XML allows us to define the version of our tag library, the required version of JSP, a short name, and a description of the tag library.
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>rss</short-name>
<description>
Tags used to present RSS information.
</description>
Following this is the definition of the tags in the tag library. Here we have only one, which defines the name of the tag as it will be used on a JSP page, the name of the tag handler class, the body content type and, again, a short description.
<tag>
<name>rssFeed</name>
<tag-class>tagext.RssFeedTag</tag-class>
<body-content>JSP</body-content>
<description>
A tag to present a headlines/titles of items from an RSS feed.
</description>
Of these, the body content probably needs some more explanation. The JSP specification provides several body content types that can be defined for custom tags, with the two most useful being empty and JSP. A body content type of empty indicates that the custom tag will be used without body content on the page, which is handy when you simply want the tag to perform some sort of action. On the other hand, a body content type of JSP indicates that there will be regular JSP constructs used between the start and end tags. This is what we’re using in this example, because we’d like the body content to be evaluated for each item in the RSS feed.
The next part of the XML file describes the scripting variable that will be introduced into the page within the body content of the tag. In the tag handler code, we get the next RSS item from the collection, then place the reference to that object in the page context under the name rssItem. One of the things custom tags can do is make these attributes available as scripting variables on the JSP page, so they can be accessed with the request-time expression syntax of <%= … %>. Here, we specify the name and type of the variable, along with a scope of NESTED to indicate that the variable should only be accessible between the starting and ending tags.
<variable>
<name-given>rssItem</name-given>
<variable-class>rss.RssItem</variable-class>
<scope>NESTED</scope>
</variable>
The final aspect of the tag to describe is its attributes. In this example there is only a single attribute, called url, which is used to indicate the source of the RSS feed. To ensure that the tag works as expected, we've stated that this attribute must be supplied when the tag is used. The rtexprvalue element of the attribute tag says that the value of the attribute must be statically defined in the JSP page. In other words, the value of the attribute isn't the result of a request-time expression.
<attribute>
<name>url</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
Using the Tag
For the purposes of this example, let's assume that the TLD file has been saved as rss.tld under the WEB-INF directory of your Web application. To use a custom tag, you first need to tell the JSP page where to find the description of that tag. This is achieved through the taglib directive, with the uri attribute pointing to the TLD file that represents the tag library, and the prefix attribute stating how the tags in that tag library will be identified and used on the page. Then, using the same syntax as before, we can use the tag to read the RSS feed provided by any Website, and generate a set of hyperlinks to the current news stories on that site.
<%@ taglib uri="/WEB-INF/rss.tld" prefix="rss" %>
<rss:rssItems url="http://www.sitepoint.com/rss.php">
<a href="<%= rssItem.getLink() %>"><%= rssItem.getTitle() %></a>
<br />
</rss:rssItems>
Future Enhancements
The tag presented here is fairly simple in its implementation, and there are many enhancements that could be made. For example, every time the JSP page is requested, the tag opens up an HTTP connection to retrieve the contents of the RSS feed. While this is okay for a low traffic site, a better solution would be to cache the feed on a regular basis. This would avoid the performance penalty associated with opening a network connection for every page request.
Also, the tag doesn't take into account what happens if a network error occurs. For example, the Website might be down or may not be functioning correctly. In any case, you would probably want to add some error handling, perhaps to display a message to alert users that the feed isn't currently available.
Summary
In this article we've looked at what RSS is, how to read RSS feeds, and how to integrate this functionality into a JSP-based Web application. Although we could have built this functionality directly into the JSP page using Java code scriptlets, developing a JSP custom tag has allowed us to build a more maintainable component with the added advantage that it’s reusable, too.
Building the tag handler class and writing the TLD file does involve slightly more work than would embedding Java code into the page. However, I believe that the benefits in maintainability and reusability easily justify the additional effort involved.