
Beginning Apache Struts - From Novice To Professional (2006)
.pdf448 |
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 |
In addition to these, there are other user and role attributes. These depend on the underlying servlet technology’s facility to authenticate a user, and specify one or more roles for that user. How this is done is outside the scope of this book, so if you’re interested in learning more, you should consult a recent reference on servlets. The user attribute specifies the name of the remote user for the current request. The role attribute is a comma-delimited string of roles. present evaluates its body if any one of these roles is a valid role of the current user.
Examples
The simplest usage checks for the presence of an object on the request:
<logic:present name="myobject"> My object is present!
</logic:present>
Similarly, the use of the property attribute ensures that the given property is not null:
<logic:present name="contact" property="designation"> The contact's designation is:
<bean:write name="contact" property="designation"/> </logic:present>
You can also check the current authenticated username:
<logic:present user="donquixote"> Hi Don!
</logic:present>
or that the current authenticated user has any of the specified roles:
<logic:notPresent role="admin,staff">
Sorry, you are not allowed to view this page! </logic:notPresent>
Equivalents
You can easily create equivalents for these tags using JSTL’s <c:if> or <c:choose>...<c:when>. For example using <c:if>, the previous examples would be
<c:if test="${myobject != null}"> My object is present!
</c:if>
<c:if test="${contact != null && contact.designation != null}"> The contact's designation is:
<c:out value="${contact.designation}"/> </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 |
449 |
<c:if test="${pageContext.request.remoteUser == 'donquixote'}"> Hi Don!
</c:if >
The last example—checking roles—unfortunately has no JSTL equivalent. However, there is a JSF extension for security that handles this case neatly. Check out http://jsf-security.sourceforge.net if you’re interested.
redirect
This tag performs a page redirect. The tag has no body. See also <logic:forward>.
Usage Restrictions
You must specify either forward, href, action, or page to specify the base URL to redirect to.
Attributes
There are two main sets of attributes. The first set specifies the base URL of the page to redirect to. You have four ways to do this:
•forward: The name of the global forward to redirect to (e.g., forward="login").
•href: The raw URL to redirect to (e.g., href="http://www.kenyir.org").
•action: The name of the form handler (that is, action mapping) to redirect to. This must begin with a slash because it’s relative to the default module (e.g., action="/Logoff"). (See Chapter 17 for more on modules.)
•page: The path to the web page on the current webapp to redirect to. This path is relative to the webapp’s base folder. The path must begin with a slash (e.g., page="/index.jsp").
redirect also allows you to specify parameters on the redirected URL:
•anchor: Lets you specify the name of an anchor. Anchors are standard HTML. They are used to label sections of a long web page for easy navigation.
•name/property/scope: These attributes are used to locate a Map instance on the request or session. The key of the map is the parameter’s name, and the value is the corresponding parameter’s value. In the case that the value is an array, multiple parameters are written to the URL, each with the same name but different values. You use a combination of these three variables if you want to create more than one URL parameter.
450 |
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 |
•paramName,paramProperty,paramScope and paramId: The first set of three attributes is used to locate a single object on the current request or session. If this object is not an array, its toString() is called and this is the single parameter value. If the object is an array, then you’re creating multiple parameters with the same name but different values. The name of the parameter is given by paramId.
The remaining attributes are useLocalEncoding and transaction. useLocalEncoding, if set to true, tells Struts to use whatever the character encoding is for the current HttpServletResponse. The transaction attribute requires some elaboration.
Transaction Tokens
Struts has a mechanism to prevent a form from being submitted more than once. This might happen if the user clicks the form’s submit button twice in quick succession. Ordinarily, Struts would treat this as two separate submissions. This, of course, is an error. A standard solution to this problem is to use a transaction token.
You have to use two Action subclasses. The first Action subclass is activated when the form is requested. It places a unique string on both the request and the session. This unique string is the transaction token. Action has the function
saveToken(HttpServletRequest request)
to do this for you. This function automatically generates the transaction token and places it on the request and session under appropriate keys. A simple example of the execute() function of this Action subclass is as follows:
public ActionForward execute(...){ //create the transaction token saveToken(request);
//give the user the form to fill return mapping.findForward("success");
}
The second Action subclass is the one that processes the form data once it is submitted by the user. This is what its execute() would look like:
public ActionForward execute(...){ if(isTokenValid(request,true)){
return mapping.findForward("duplicate-submission");
}
//process form data as usual.
...
}
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 |
451 |
The function isTokenValid(request,true) checks to ensure that the transaction token on the request matches that on the session. Once the check is done, it destroys the copy on the session. This means that if the user clicked the submit button a second time, there would be no copy on the session, causing isTokenValid() to return false.
However, you should be aware that the simple solution outlined in the preceding section has one big failing: the error page (duplicate-submission) sent back to the user might make him think that the form data wasn’t been processed at all! Careful wording of the error message might help, but you still can’t get the true success page to the user. More sophisticated solutions would solve such user interaction issues as well.
Coming back to the transaction attribute, if it’s set to true then the value of the transaction token on the request is sent as a URL parameter.
Examples
Here is a simple redirect using the name of a global forward:
<logic:redirect forward="login" />
Next is an example of adding a single URL parameter. The name of the parameter (paramId) is email-address. The value of the parameter is determined by calling contact.getEmail():
<logic:redirect action="/MyFormHandler" paramId="email-address" paramName="contact" paramProperty="email" />
Here’s how you would add multiple URL parameters, based on a Map. The Map is located by calling contact.getAttributes(), which is located on the session scope:
<logic:redirect action="/mypage.jsp" name="contact" property="attributes" scope="session" />
Equivalents
None. No single tag in JSTL or JSF perform all the functions of <logic:redirect>.
The Nested Tag Library
The nested tag library allows you to apply tags relative to an object. You can emulate exactly the same functionality using nested properties (see Chapter 10 for a detailed exposition).
Unfortunately, to a programmer, the Nested taglib might feel like a kludge. For instance, suppose you wanted to write the contents of
MyBean.getMyPropertyA().getMyPropertyB()

454 |
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 |
writeNesting
This tag is used to write the current nesting level either to the response stream (i.e., the rendered HTML page), or to make it available as a page scoped variable.
Usage Restrictions
None.
Attributes
This tag has three attributes:
•property: The value of this attribute is blindly appended to the end of the nesting level, prefixed with a dot.
•id: When id is specified, the nesting level is not written to the final HTML page, but rather is exposed as a page-scoped String variable with the value of id serving as the name.
•filter: This attribute takes the value true or false. If true, then the nesting level is encoded. For example, the ampersand (&) appears as &. Despite what the Apache online documents say, URL encoding is not performed—for instance, spaces are not encoded as %20%, etc.
These attributes are best illustrated with JSP examples.
Examples
Using writeNesting only makes sense when it’s used in conjunction with the <nested:nest> tag as in the following snippet:
<html:form ...>
<nested:nest property="contact"> <nested:nest property="company">
Nesting level is: <nested:writeNesting />
</nested:nest>
</nested:nest>
</html:form>
In this example, the displayed HTML will contain the text
Nesting level is: contact.company
456 |
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 |
root
This tag is used to specify a base object.
You use root either to specify a different base object from the current one (as is the case within an <html:form> tag) or to define a base object if none exists (as is the case anywhere outside an <html:form>).
Usage Restrictions
None, but you obviously need to specify the name attribute in order to accomplish anything.
Attributes
There is just one attribute, name, which is the name of the JavaBean on the current request. This bean is used as the new base object for all Nested tags enclosed by <nested:root>.
Examples
Suppose you wanted to access a nested property using, say, <bean:write>, in an <html:form>, but with the base object called MyBean instead of the base object implied by <html:form>. Here’s how you would do it:
<html:form action=...
<bean:write name="MyBean" property="contact.name"/> <bean:write name="MyBean" property="contact.email"/> <bean:write name="MyBean" property="contact.company"/>
</html:form>
To accomplish the same thing with the Nested tags, you’d have to use <nested:root>:
<html:form action=...
<nested:root name="MyBean"> <nested:nest property="contact">
<nested:write property="name"/> <nested:write property="email"/> <nested:write property="company"/>
</nested:nest>
</nested:root>
</html:form>
As you know (see the corresponding reference), <html:form> defines an implicit base object, which is the form bean associated with that form. <nested:root> allows you to temporarily redefine the base object. This would also work outside an <html:form>. For example, the snippet

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 |
457 |
<bean:write name="MyBean" property="contact.name"/> <bean:write name="MyBean" property="contact.email"/> <bean:write name="MyBean" property="contact.company"/>
may be replaced with
<nested:root name="MyBean"> <nested:nest property="contact">
<nested:write property="name"/> <nested:write property="email"/> <nested:write property="company"/>
</nested:nest>
</nested:root>
Equivalents
None.
The Tiles Tag Library
The Tiles tag library supports the Tiles plug-in, which is used to create layouts and reusable GUI components. Chapter 14 explains Tiles in detail, and you should consult it to understand how to use Tiles.
Table C-13 gives a synopsis of all tags in the Tiles tag library. Table C-13 is based on the Apache documentation. Please refer to www.apache.org/licenses/LICENSE-2.0 for a copy of the Apache License.
Table C-13. Synopsis of the Tiles Tag Library
Tag |
Usage/Comments |
insert |
Inserts a layout or Tile. |
definition |
Declares a layout or customized layout for later use. |
put |
Adds a Tiles attribute to the current context. |
putList and add |
putList defines a list attribute in the current context. add is used |
|
to add items to the list. |
get |
Writes a specified JSP or Tiles definition to the response stream. |
getAsString |
Writes a specified Tiles attribute as a literal string to the |
|
response stream. |
useAttribute |
Exposes a Tiles attribute to scriptlets or other custom tags. |
importAttribute |
Allows scriptlets or other custom tags to read Tiles attributes. |
initComponentDefinitions |
Legacy tag that allows the use of Tiles outside of Struts. |
|
|