Custom JSP Actions
Once we have written our class, we can write a TLD that describes it to the JSP engine. Many people might prefer to work in the opposite direction, using the TLD as a specification JSP authors and tag handlers can use while working in parallel. I prefer to write the custom actions first, modifying the TLD as I go along, even though this is admittedly not the safest nor the most elegant means of working.
The TLD, as you can see from Listing 2, can be a relatively short XML file. The TLD maps action names to the classes that implement those actions. A TLD can map a single action to a single class, or it might map hundreds of actions to hundreds of different classes. And because each class exists separately, it is even possible (though hardly a good idea) for a class to be used in multiple TLDs simultaneously.
The TLD is loaded into our servlet container when it is first referenced. Unfortunately, this means that changing the TLD after the custom action has already been invoked requires restarting Tomcat (and Apache, if you are using Apache's mod_jk along with the Tomcat server). It tells the JSP engine which versions and specifications your tag library supports, making it possible for a JSP engine to know when a particular library needs to be upgraded in order to be compatible with current standards.
The TLD consists of a top-level <taglib> tag, which contains a minimum of four sections: <tlibversion> indicates the version of the tag library specification this library supports; <jspversion> indicates the version of the JSP specification for which the tag library was written; <shortname> gives this tag library a name, which some JSP engines use; and <tag> appears once for every tag handler class we want to include in our library. Each tag gets its own name, the name of the action that is invoked. Thus, if we import a tag library with a prefix of “abc”, the tag named “hello” will be invoked as “abc:hello”. The <tagclass> section maps the tag's name to the tag handler class that actually performs the actions; this class must obviously be in your server's CLASSPATH. The <info> section allows us to provide some basic information and in-line documentation about this particular tag.
Finally, we name each of the attributes this custom action takes. Each attribute has its own <name> tag, as well as an indication of whether the attribute is required.
Now that we have a TLD and a tag handler class, we can use them together in any of our JSPs. We import the tag library using the special JSP taglib directive:
<%@ taglib uri="/WEB-INF/hello.tld" prefix="hello" %>
Notice how the taglib directive takes two parameters, “uri” and “prefix”. The uri portion contains the filename of the TLD that we just created. If you want to put TLDs directly inside your WEB-INF directory, then the above syntax is perfectly valid. The prefix parameter is a sort of namespace declaration, telling the JSP engine what prefix we will attach to each of the actions the tag library imports. Giving the JSP the option of naming the prefix, rather than building it into the tag library itself, allows us to import multiple tag libraries without having to worry about namespace clashes.
Since our TLD defines a single “hello” tag, and since we imported the tag library using the “hello” prefix, we can invoke our HelloTag methods using the following syntax: <hello:hello/>. Listing 3 contains a complete JSP (test-tag.jsp) that demonstrates how we can use this tag.
Remember to include the trailing slash when invoking custom actions. If you forget to include it, Tomcat's JSP engine (known as Jasper) will produce an error message similar to the following:
Unterminated user-defined tag: ending tag </hello:hello> not found or incorrectly nested
Our TLD indicates the firstname attribute is optional. If we don't pass a firstname parameter, then we get the following output in our web browser:
This is a test of our custom action. Hi there!We can also pass an optional firstname parameter:
<hello:hello firstname="Reuven"/>If we put the above in our JSP, the following output is sent to the browser:
This is a test of our custom action. Hello, Reuven
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems
Join editor Bill Childers and Bit9's Paul Riegle on April 27 at 12pm Central to learn how to keep your Linux systems secure.
Free to Linux Journal readers.Register Now!
|diff -u: What's New in Kernel Development||Aug 20, 2014|
|Security Hardening with Ansible||Aug 18, 2014|
|Monitoring Android Traffic with Wireshark||Aug 14, 2014|
|IndieBox: for Gamers Who Miss Boxes!||Aug 13, 2014|
|Non-Linux FOSS: a Virtualized Cisco Infrastructure?||Aug 11, 2014|
|Linux Security Threats on the Rise||Aug 08, 2014|
- Security Hardening with Ansible
- diff -u: What's New in Kernel Development
- NSA: Linux Journal is an "extremist forum" and its readers get flagged for extra surveillance
- Monitoring Android Traffic with Wireshark
- Tech Tip: Really Simple HTTP Server with Python
- Readers' Choice Awards 2013
- [<Megashare>] Watch Mrs Brown's Boys Movie Online Full Movie HD 2014
- RSS Feeds
- IndieBox: for Gamers Who Miss Boxes!
- Returning Values from Bash Functions