18.8 Custom Tag Libraries

Java Servlet Programming, 2nd Edition > 18. JavaServer Pages > 18.8 Custom Tag Libraries

 
< BACKCONTINUE >

18.8 Custom Tag Libraries

To conclude, let's look at the most interesting aspect of JavaServer Pages: the support for custom tag libraries. Custom tags (aka custom actions) let a JSP page contain XML tags that, although they look like HTML, actually cause specific Java code to be executed when a tag is encountered. The possible uses for custom tag libraries are quite exciting. For example, Live Software (creators of JRun) used JSP custom tags to implement a 100% portable version of the Allaire Cold Fusion tags called CF_Anywhere. (Shortly thereafter, Live Software was purchased by Allaire.)

The details on how to write a custom tag library are fairly involved and extend beyond the scope of this chapter. Fortunately, several open source tag libraries are under development and already useful. The two most prominent are Apache Taglibs and Apache Struts, both from the Apache Jakarta project at http://jakarta.apache.org. Apache Taglibs holds general-purpose tag libraries; Apache Struts holds a tag libary intended to support a Model 2-style architecture, but many of the tags are generally useful. For a list of JSP tag libraries see http://jsptags.com. There's also an effort to create a standard tag library as a formal Java specification request process as JSR-052. For more information on JSR-052 see http://java.sun.com/aboutJava/communityprocess/jsr/jsr_052_jsptaglib.html.

18.8.1 Using Custom Tag Libraries

Custom actions allow the embedding of application logic into JSP pages using HTML-like tags. With the right set of tags, logic that previously had to be written using scriptlets can instead be written using tags. For example, the Apache Struts project has an <iterate> tag we can use to replace a for loop. The <iterate> tag repeats the body of the tag once for each element of a collection (List, Set, Vector, Map, array, etc.). During each iteration it puts the element into page scope for use within the body.[6] Struts also has a <property> tag that operates like <jsp:getProperty> with the extra enhancement that it filters the content for HTML display by converting all HTML special characters into their appropriate character entities. For example, < becomes %lt;.

[6] The <iterate> tag requires JDK 1.2 or later. There's an <enumerate> tag for JDK 1.1.

Using <iterate> and <property> together we can write the following page snippet to display all the cookies sent in the request with all special characters properly filtered:

<%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %> <struts:iterate  collection="<%= request.getCookies() %>">   <struts:property name="cookie" property="name" /> =   <struts:property name="cookie" property="value" /> <BR> </struts:iterate>

To install and use a tag library like Struts you must do several things:

  1. Download and unpack the tag library distribution. For example, Struts is available at http://jakarta.apache.org.

  2. Place the tag library Java classes so they will be found by the server. For example, place the struts.jar file in WEB-INF/lib or place the compiled classes in WEB-INF/classes.

  3. Place the Tag Library Descriptor (TLD) file into a location under the WEB-INF directory. It's common to use either WEB-INF/tlds or WEB-INF directly, the exact location isn't important. For example, place struts.tld into WEB-INF. The TLD file is an XML datafile providing the server with information about each tag in the library its name, class, how to use its attributes, how to use its body, and so on. There's an extra bonus to having TLDs: based on the TLD a web page documenting the tag library can be generated (perhaps using an XSL stylesheet).

  4. Add a <taglib> entry to the web.xml file. Then within the entry place a <taglib-uri> entry giving the lookup name for the taglib, and also a <taglib-location> entry giving the location of the TLD. This step would not be required if the <taglib-uri> entry would exactly match the <taglib-location> entry. To demonstrate:

        <taglib> <!-- since the uri matches the location this is optional -->         <taglib-uri>/WEB-INF/struts.tld</taglib-uri>         <taglib-location>/WEB-INF/struts.tld</taglib-location>     </taglib>

    The <taglib-uri> entry must be a URI path, so legal values include struts, http://jakarta.apache.org/struts, and /WEB-INF/struts.tld. A URI path traditionally refers to an actual resource location, but here it's used only as a unique identifier for the tag library.

  5. In every JSP page using the custom tag library, add the following taglib directive. This tells the server to load the tag library with the given "lookup URI" and to put those tags in the XML namespace prefix struts:

    <%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %>
  6. Use the tags within the JSP page, making sure the XML namespace prefix matches that declared in the taglib directive:

    <struts:property name="beanname" property="propname" />

    It is possible for the tag library creator to bundle the TLD within the tag library's JAR file. In this event, instead of pointing at the .tld, you then point at the .jar itself.

18.8.2 A Tool Application Using Custom Tag Libraries

Using the <iterate> and <property> tags from Struts we can simplify our toolview.jsp page. We'll also take this opportunity to demonstrate the servlet-driven Model 2 architecture in which a servlet receives the request, adds attributes to the request object, then dispatches the request to a JSP that acts like a template. Example 18-12 shows the controller servlet.

Example 18-12. A Model 2 Servlet Controller
import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class ToolServlet extends HttpServlet {   Tool[] tools = null;   public void init() throws ServletException {     // Load the tool data in our init for simplicity     String toolsFile =       getServletContext().getInitParameter("toolsFile"); // from web.xml     if (toolsFile == null) {       throw new ServletException("A tools data file must be specified as " +                                  "the toolsFile context init parameter");     }     log("Loading tools from " + toolsFile);     try {       tools = Tool.loadTools(toolsFile);       if (tools.length == 0) {         log("No tools found in " + toolsFile);       }       else {         log(tools.length + " tools found in " + toolsFile);       }     }     catch (Exception e) {       throw new ServletException(e);     }   }   public void doGet(HttpServletRequest req, HttpServletResponse res)                                throws ServletException, IOException {     Tool[] tools = null;     // Place an appropriate "tools" attribute in the request     String state = req.getParameter("state");     if (state == null) {       req.setAttribute("tools", getTools());     }     else {       req.setAttribute("tools", getTools(state));     }     // Send the request to the JSP for processing     RequestDispatcher disp = req.getRequestDispatcher("/toolview-tag.jsp");     disp.forward(req, res);   }   public Tool[] getTools() {     return tools;   }   public Tool[] getTools(String state) {     List list = new LinkedList();     for (int i = 0; i < tools.length; i++) {       if (tools[i].getStateFlag().equalsIgnoreCase(state)) {         list.add(tools[i]);       }     }     return (Tool[]) list.toArray(new Tool[0]);   } }

This servlet behaves similarly to the ToolApp in Tea and ToolServlet in WebMacro. It loads the tool information in its init( ) method, and on each request places an appropriate subset of tools into the request object. The servlet forwards each request to a JSP for actual rendering, and the JSP can gain access to the tools in the request object using the <jsp:useBean> tag. Example 18-13 demonstrates the JSP named toolview-tag.jsp .

Example 18-13. The Tool Application Rewritten Using Tag Libraries
<%-- toolview-tag.jsp --%> <%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %> <%   String title = "Tool Listing";   String deck = "A list of content creation tools";   String desc = "Without tools, people are nothing more than animals.  And " +                 "pretty weak ones at that.  Here's a list of servlet-based " +                 "content creation tools you can use so you won't be a " +                 "servlet weakling."; %> <%@ include file="/header.jsp" %> <%@ page session="false" %> <%@ page errorPage="/errorTaker.jsp" %> <%-- Fetch the tools array as a request attribute --%> <jsp:useBean   scope="request"/> <struts:iterate  collection="<%= tools %>">   <HR SIZE=2 ALIGN=LEFT>   <H3>   <%-- Automatically HTML-escapes values --%>   <struts:property name="tool" property="name" />   <% if (((Tool)tool).isNewWithin(45)) { %>     <FONT COLOR=#FF0000><B> (New!) </B></FONT>   <% } else if (((Tool)tool).isUpdatedWithin(45)) { %>     <FONT COLOR=#FF0000><B> (Updated!) </B></FONT>   <% } %>   </H3>   <A HREF="<struts:property name="tool" property="homeURL"/>">            <struts:property name="tool" property="homeURL"/></A><BR>   <%-- Assume don't want HTML in comments --%>   <struts:property name="tool" property="comments" /> </struts:iterate> <%@ include file="/footer.jsp" %>

This page first uses the taglib directive to load the Struts custom tag library. Don't forget this step! If you do forget, you won't get a direct error message but things won't work. The reason is that without the taglib directive the <struts:iterate> and <struts:property> tags look to the server like any other HTML tags and they're treated like page content to be output instead of page logic to be executed!

The body of the page uses the <struts:iterate> tag to loop over the array of tools and the <struts:property> tag to display each tool's name, URL, and comments. If the comments are allowed to contain HTML markup then the proper tag to use would be <jsp:getProperty> so the HTML markup isn't filtered away.

Using the common tags from Apache Struts removes some more code from the HMTL page, but a few scriptlets remain. To remove all the scriptlets would require creating a custom tag to perform the timestamp comparison. Unfortunately, because of the many details involved in writing custom tags, we can't include a tutorial here. If you're interested in learning more on creating custom tags, see Hans Bergsten's book JavaServer Pages (O'Reilly).


Last updated on 3/20/2003
Java Servlet Programming, 2nd Edition, © 2001 O'Reilly

< BACKCONTINUE >


Java servlet programming
Java Servlet Programming (Java Series)
ISBN: 0596000405
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net