Understanding How Struts Tags Work: The bean:page Tag


Understanding How Struts Tags Work: The <bean:page> Tag

It's important to know about JSP custom tag development in general, but what you really need to know is how Struts tags in particular work. The Struts tag libraries were developed using a series of common techniques. Understanding these can help you both develop code and debug problems faster.

The sample tag that we'll use is the <bean:page> tag. It was chosen because it's not particularly long or complex, and it illustrates some of the basic ideas behind how all Struts tags work.

Only a single tag is presented here. This is done specifically so that if you want more information you'll look into the source code directly on your own. I recommend that you begin by looking at the source code for tags you're actually using. All the source code for Struts can be downloaded from the Struts Web site (http://jakarta.apache.org/struts).

The <bean:page> Tag Java Code

The first stop in our tag deconstruction project is the actual tag Java file. All Struts tags are located in subpackages of org.apache.struts.taglib . For example, the bean tags are located in org.apache.struts.taglib.bean . Listing 11.1 is the Java file for this tag.

Listing 11.1 org.apache.struts.taglib.bean.PageTag.java
[View full width]
 /*  * $Header: /home/cvspublic/jakarta-struts/src/share/org/apache/struts/taglib/bean/ graphics/ccc.gif PageTag.java,v 1.6 2001/04/23 22:52:20 craigmcc Exp $  * $Revision: 1.6 $  * $Date: 2001/04/23 22:52:20 $  *  * ====================================================================  *  * The Apache Software License, Version 1.1  *  * Copyright (c) 1999-2001 The Apache Software Foundation. All rights  * reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution, if  *    any, must include the following acknowlegement:  *       "This product includes software developed by the  *        Apache Software Foundation (http://www.apache.org/)."  *    Alternately, this acknowlegement may appear in the software itself,  *    if and wherever such third-party acknowlegements normally appear.  *  * 4. The names "The Jakarta Project", "Struts", and "Apache Software  *    Foundation" must not be used to endorse or promote products derived  *    from this software without prior written permission. For written  *    permission, please contact apache@apache.org.  *  * 5. Products derived from this software may not be called "Apache"  *    nor may "Apache" appear in their names without prior written  *    permission of the Apache Group.  *  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  * ====================================================================  *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Apache Software Foundation. For more  * information on the Apache Software Foundation, please see  * <http://www.apache.org/>.  *  */ package org.apache.struts.taglib.bean; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.TagSupport; import org.apache.struts.util.MessageResources; import org.apache.struts.util.RequestUtils; /**  * Define a scripting variable that exposes the requested page context  * item as a scripting variable and a page scope bean.  *  * @author Craig R. McClanahan  * @version $Revision: 1.6 $ $Date: 2001/04/23 22:52:20 $  */ public class PageTag extends TagSupport {     // ----------------------------------------------------------- Properties     /**      * The name of the scripting variable that will be exposed as a page      * scope attribute.      */     protected String id = null;     public String getId() {         return (this.id);     }     public void setId(String id) {         this.id = id;     }    /**     * The message resources for this package.     */     protected static MessageResources messages =         MessageResources.getMessageResources         ("org.apache.struts.taglib.bean.LocalStrings");     /**      * The name of the page context property to be retrieved.      */     protected String property = null;     public String getProperty() {         return (this.property);     }     public void setProperty(String property){         this.property = property;     }     // ------------------------------------------------------- Public Methods     /**      * Retrieve the required configuration object and expose it as a      * scripting variable.      *      * @exception JspException if a JSP exception has occurred      */     public int doStartTag() throws JspException {         // Retrieve the requested object to be exposed         Object object = null;         if ("application".equalsIgnoreCase(property))             object = pageContext.getServletContext();         else if ("config".equalsIgnoreCase(property))             object = pageContext.getServletConfig();         else if ("request".equalsIgnoreCase(property))             object = pageContext.getRequest();         else if ("response".equalsIgnoreCase(property))             object = pageContext.getResponse();         else if ("session".equalsIgnoreCase(property))             object = pageContext.getSession();         else {             JspException e = new JspException                 (messages.getMessage("page.selector", property));             RequestUtils.saveException(pageContext, e);             throw e;         }         // Expose this value as a scripting variable         pageContext.setAttribute(id, object);         return (SKIP_BODY);     }     /**      * Release all allocated resources.      */     public void release() {         super.release();         id = null;         property = null;     } } 

Here are the important things to understand from this listing:

  • The license at the top of the file ” This is the standard Apache Software License. Item 1 in the license indicates that the code can't be redistributed with without including the license ”so, here it is!

  • The properties section ” Nearly all Struts tags use properties as a way to store information. This is how the different tag handler methods ( doStartTag() , doEndTag() , and so on) that are present share data with each other.

  • The MessageResources file for this particular taglib package ” All tags in the org.apache.struts.taglib.bean package share the same MessageResources file. This is generally used for defining error messages employed by the tag. Changing or localizing error text is done by modifying these properties files or by creating your own.

  • Expose the results as pageAttributes Notice these lines:

     // Expose this value as a scripting variable         pageContext.setAttribute(id, object); 

    This is how virtually all Struts tags work. They manipulate data and then pass results into the main JSP page by attaching objects (usually String s or beans) to the PageContext . This makes them visible only while this page is being built.

  • The org.apache.struts.utilities classes ” For example, this tag uses the RequestUtils utility class. Getting to know these classes will help you understand a great deal more about how all the Struts tag libraries work.

After you've examined a few of these tags, they'll all begin to look the same and you can figure them out quickly. When you get to that point, you'll find debugging Struts JSP files will go much quicker.

Now might be a good time to go to your computer and look through the source code of one or two more tags. Start by looking at tags you're familiar with.

The Struts Bean Taglib Descriptor File ( struts-bean.tld )

The next stop on this whirlwind tour of the <bean:page> tag is the taglib descriptor files. The TLD files are located directly in the WEB-INF directory of your Web application. The structure and syntax of these files are defined by the Java Servlet specification.

The struts-bean.tld file is a bit long, but the section that defines <bean:page> is pretty short. It is as follows :

 <tag> <name>page</name> <tagclass>org.apache.struts.taglib.bean.PageTag</tagclass> <teiclass>org.apache.struts.taglib.bean.PageTei</teiclass> <bodycontent>empty</bodycontent> <attribute> <name>id</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>property</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> 

The important information here is the following:

  • The name of the Java file used for this tag is org.apache.struts.taglib.bean.PageTag.java

  • The line <bodycontent>empty</bodycontent> means that no content can be specified in the body of the tag. That is, you should always specify it as <bean:page ... /> and never as <bean:page ... >I'm the body!</bean:page> .

  • Only two attributes can be specified with this tag: id and property . Both are required.

That's it for the TLD file. There's not much there, but it can be useful if you're unsure which attributes are required.

One thing to watch out for is to make sure that your TLD files are from the same version as your Struts classes. Because the Struts classes are usually stored in the struts.jar file and the TLD files are stored with your Web application, it's possible for them to get out of synch. Each time you upgrade the struts.jar file you're working with, you should watch out for changes that might have occurred in the TLD files. The most common mistake is specifying a tag attribute that is in the current release of Struts and then finding that you have an old TLD file from before that attribute came into existence. If this happens, an error will be thrown to tell you that the attribute isn't valid. Be especially careful when copying TLD files from old projects ”the TLD files might be out of date.

Using the <bean:page> Tag: Tying It All Together

Now that you've looked over the Java file and the TLD file entry for <bean:page> , it's time to review how the tag is used.

According to the Struts user guide, the purpose of the <bean:page> tag is to "Expose a specified item from the page context as a bean." The documentation goes on to say that this tag is used to "Retrieve the value of the specified item from the page context for this page, and define it as a scripting variable, and a page scope attribute accessible to the remainder of the current page."

This is pretty easy to see from the source file. Remember the following lines:

 public int doStartTag() throws JspException {         // Retrieve the requested object to be exposed         Object object = null;         if ("application".equalsIgnoreCase(property))             object = pageContext.getServletContext();         else if ("config".equalsIgnoreCase(property))             object = pageContext.getServletConfig();         else if ("request".equalsIgnoreCase(property))             object = pageContext.getRequest();         else if ("response".equalsIgnoreCase(property))             object = pageContext.getResponse();         else if ("session".equalsIgnoreCase(property))             object = pageContext.getSession();         else {             JspException e = new JspException                 (messages.getMessage("page.selector", property));             RequestUtils.saveException(pageContext, e);             throw e;         }         // Expose this value as a scripting variable         pageContext.setAttribute(id, object);         return (SKIP_BODY); 

As you can see, the tag accepts the property attribute that's passed into it, stores the appropriate page context item in the object , and then sets the result on to the page context as a scripting variable with the id attribute.

So, it's clear that both the property and id attributes are required and that the tag syntax must be

 <bean:page id="nameToStoreItUnder" property="session" /> 

After you understand how the tags work, it's easy to quickly put them to use and debug your code if you make a mistake.



Struts Kick Start
Struts Kick Start
ISBN: 0672324725
EAN: 2147483647
Year: 2002
Pages: 177

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