
Beginning Apache Struts - From Novice To Professional (2006)
.pdf438 |
A P P E N D I X C ■ S T R U T S T A G R E F E R E N C E |
Attributes
Only the base-attrs attribute set is applicable.
Examples
The following example shows the use of the <logic:empty> tag to conditionally process the nested <bean:write> tag if MyCollection is empty:
<logic:empty name="MyCollection">
<bean:write name="MyCollection" property = "myproperty[13]" /> </logic:empty>
The next example illustrates the use of the property tag:
<logic:empty name="contact" property="email"> <bean:write name="contact" property="email"/>
</logic:empty>
The <bean:write> is executed only if the getEmail() function returns null, or a zerolength String. You can also use the scope variable to specify a scope under which to look for a bean:
<logic:notEmpty name="MyBean" scope="request"> <bean:write name="MyBean" property = "myproperty" />
</logic:empty>
In the previous example, the <bean:write> is called on the base object if MyBean can be found on the request scope.
Equivalents
You can easily create equivalents for empty and notEmpty using JSTL’s <c:if> or <c:choose>...<c:when>. For example using <c:if>, the previous examples would be
<c:if test="${empty MyCollection}">
<bean:write name="MyCollection" property = "myproperty[13]" /> </c:if>
and
<c:if test="${empty contact.email}">
<bean:write name="contact" property="email"/> </c:if>
A P P E N D I X C ■ S T R U T S T A G R E F E R E N C E |
439 |
You’d have to use JSTL’s implicit objects (requestScope, sessionScope, etc.) to specify a scope:
<c:if test="${ not empty requestScope.MyBean}"> <bean:write name="MyBean" property = "myproperty" />
</c:if>
equal/notEqual
equal checks that the given property (or extended property) is equal to a given value. If so, the body of the equal tag is executed. notEqual is the converse of equal.
Usage Restrictions
The value attribute is required. You must specify one selector attribute (see the start of this section for a definition) as well.
Attributes
Both base-attrs and exprop-attrs are accepted. There is also an additional value attribute, which is a constant value that the property or extended property will be compared to.
Examples
The following example shows the use of the <logic:equal> tag to conditionally process the nested <bean:write> tag if the variable client is equal to the String “Joe”:
<logic:equal name="client" value="Joe"> <bean:write name="client" />
</logic:equal>
The next example illustrates the use of the parameter attribute:
<logic:equal parameter="username" value="Susan"> Hello Susan!
</logic:equal>
The body is executed only if there is a parameter named username on the request URL with the value Susan. If there were more than one such parameter, the first one that occurs on the URL is used.
You can also use the scope variable to specify a scope under which to look for a bean:
<logic:notEqual name="MyBean" property="email" scope="session" value="joey@joey.com">
<bean:write name="MyBean" property = "email" /> </logic:notEqual>

A P P E N D I X C ■ S T R U T S T A G R E F E R E N C E |
443 |
Attributes
The iterate tag uses base-attrs to specify the base object that represents the Collection/ Map/Enumeration/array/Iterator to iterate over. Besides these, several other attributes can be used:
•collection: The name/property combination only allows you to loop over iteratable objects that may be read as JavaBean properties. This can be quite restrictive.
For example:
<logic:iterate name="MyBean" property="myCollection" ...
implicitly calls the function
MyBean.getMyCollection()
•in order to determine the iteratable object. Many Java classes however, do not use the JavaBeans getXXX() convention, so a different approach is needed for them. The solution is to use the collection attribute in combination with a scriptlet:
<logic:iterate collection="<%=MyObject.iterator()%>" ...
•id: This is the name given to a single element read from the iteratable object.
•indexId: The current index; starts from zero.
•length: The maximum number of elements to read from the iteratable object. If not present, all elements are read.
•offset: The index of the first element to return from the iteratable object. For example, if the iteratable object is an array [a, b, c], using offset="1" makes the loop read b and c only. Note that the offset is zero based, as it is in Java.
•type: The fully qualified classname of the elements read from the iteratable object. If an element doesn’t match this classname, a ClassCastException is thrown.
Examples
Here’s the basic usage:
<logic:iterate name="MyBean" property="myCollection" id="anElement"> <!-- anElement.toString() called -->
<bean:write name="anElement" /> </logic:iterate>
A P P E N D I X C ■ S T R U T S T A G R E F E R E N C E |
445 |
Attributes
Both base-attrs and exprop-attrs are accepted, and have their usual meaning. Besides these, there are two additional attributes:
•value: A constant substring that the property or extended property will be matched for. For example, if the property or extended property results in the string “Visit Zimbabwe”, then value="im" would cause a match, while value="Zic" would not.
•location: The value is either start or end, and specifies where the matching should take place within the source string. If omitted, a match anywhere will succeed.
Examples
Here’s a simple example that looks for an email address with an .sg suffix:
<logic:match name="MyBean" property="email" value=".sg" location="end">
I see you're from Singapore! </logic:match>
Or you could interrogate the HTTP request header:
<logic:notMatch header="user-agent" value="Windows"> Try knoppix now: http://www.knoppix.net
</logic:notMatch>
Equivalents
You can easily create equivalents for these tags using JSTL’s <c:if> (or <c:choose>...<c:when>) in conjunction with JSTL functions. (This is a standard JSTL library of functions. You must declare the JSTL function taglib in order to use it.) For example, using <c:if> the previous examples would be
<c:if test="${fn:endsWith(MyBean.email,'.sg')}"> I see you're from Singapore!
</c:if>
and
<c:if test="${fn:contains(header.user-agent,'Windows')}"> Try knoppix now: http://www.knoppix.net
</c:if>
446 |
A P P E N D I X C ■ S T R U T S T A G R E F E R E N C E |
messagesPresent/messagesNotPresent
messagesPresent is a conditional tag that executes its body if the given message or error message exists on the current request. messagesNotPresent is the converse of messagesPresent.
Note the following terminology:
•“Error messages” are ActionMessage instances stored in an ActionMessages/ ActionErrors instance, which in turn is stored under the key Globals.ERROR_KEY in the request.
•“Messages” are ActionMessage instances stored in an ActionMessages/ActionErrors instance, which in turn is stored under the key Globals.MESSAGE_KEY in the request.
For example, your ActionForm’s validate() might return an ActionErrors instance that contains one or more ActionMessage instances. These ActionMessage instances are stored by key, as you’ve seen in Chapters 6 and 7. The key is called the “name” of the corresponding error message/message.
Both error messages and messages may be displayed with <html:errors>, or iterated with <html:messages>.
Usage Restrictions
None.
Attributes
There are three attributes: name, property, and message.
Note that the name and property attributes don’t have their usual meaning. Instead, the following checks are made depending on the settings of these attributes:
•If no attributes are specified, messagesPresent simply checks if there any error messages in the current request. It executes its body if there are error messages. Setting message="true" causes messagesPresent to check for any messages instead.
•If the property attribute is specified, messagesPresent checks if there are any error messages with that name. Again, setting message="true" causes a check for the appropriate message instead.
•The name attribute allows you to look for error messages/messages on the request, under a key other than Globals.ERROR_KEY or Globals.MESSAGE_KEY. Note that if you specify the message attribute, the name attribute is ignored.
•If the name attribute is specified, then even a String or String array in the request will result in a match.