
Beginning Apache Struts - From Novice To Professional (2006)
.pdf408 |
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 |
Examples
Consider the <html:multibox> on a form:
<html-el:form ...>
<logic:iterate name="contacts" id="contact">
<html-el:multibox property="ids" value="${contact.getId()}" /> </logic:iterate>
</html-el:form>
and the associated ActionForm subclass:
public SelectedContactIds extends ActionForm{ protected String[] _ids;
public void setIds(String[] ids){ _ids = ids; }
public String[] getIds(){return _ids;}
public void reset(ActionMapping mapping, HttpServletRequest request){
//We use a new String array instead
//of just null to allow easy migration to
//the Validator framework, which requires
//a non-null value for arrays.
_ids = new String[0];
}
}
The length of the _ids variable isn’t fixed—it depends on how many of the rendered check boxes were checked.
Equivalents
None.
radio
This tag renders a radio button input field.
Usage Restrictions
This tag must be inside an <html:form> tag. The property and value attributes are required.
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 |
409 |
Attributes
All common attribute sets (evt-attrs, acc-attrs, ren-attrs, struts-attrs , init-attr, and the new err-attrs) are accepted, and have their usual meanings.
In addition to these, there is the idName attribute, which points to a JavaBean. When idName is specified, the value attribute is used as a property name for this JavaBean. The combination is used to specify a return value for the radio button.
Examples
Here’s an example of a few radio buttons on a form. Notice how all radio buttons refer to the same property (color), thereby allowing the user to select one color from a list:
<html:radio property = "color" value="Red"/>Red<br> <html:radio property = "color" value="Yellow"/>Yellow<br> <html:radio property = "color" value="Blue"/>Blue<br>
Here’s the same example but using the idName attribute:
<logic:iterate name="colors" id="c"> <html:radio idName="c" value="color"/> <bean:write name="c" property="color"/><br>
</logic:iterate>
In this second example, colors is an iteratable object (see the entry for <logic:iterate>) and holds JavaBeans (exposed in the snippet by the variable c), which have a getColor() function.
Equivalents
JSF’s <h:selectOneRadio> is an equivalent.
reset
This tag displays a button that if clicked, causes the enclosing form’s fields to be cleared.
Usage Restrictions
This tag should be inside an <html:form> tag.
Attributes
The first four attribute sets (evt-attrs, acc-attrs, ren-attrs, and struts-attrs) are accepted. If value isn’t specified and if there is no text rendered in the body of the <html:reset> tag, then the button text defaults to “Reset”.
410 |
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 |
Examples
This example shows three submit buttons, all of which have the text “Reset Me”. The last reset button uses an <html:bean> tag to localize its text:
<html:reset value="Reset Me" /> <html:reset >Reset Me</html:reset > <html:reset >
<html:bean message="msg.reset-me"/> </html:reset >
In all cases, if the user clicks the button, the form gets submitted, the associated ActionForm’s reset() function is invoked, and the page is then redisplayed. Your ActionForm subclasses might override this function to provide custom resetting of the form’s fields.
Equivalents
The JSF’s <h:commandButton id="reset" type="RESET"> allows you to emulate the functionality of the <html:reset> button. Of course, for you to use this with Struts, you need to embed it within the Strut-Faces <s:form> tag. Refer to Chapter 20 for details on <h:commandButton> and <s:form>.
rewrite
This tag resolves and renders a URL. The rules used are similar to those for <html:link>. Unlike <html:link>, though, the URL isn’t embedded within an HTML <a> tag; the URL is rendered by itself. You might find this useful for debugging or for use in scripts.
Usage Restrictions
You must specify either action/module, href, page, or forward.
Attributes
•action/module, href, page, or forward: Used to specify a URL. The action, module pair specifies a form handler. The action, of course, must begin with a slash, and if you want to specify a module, use the module attribute. href is either a relative or absolute URL. page is a module-relative URL (and therefore, must begin with a slash). forward is the name of a global forward.
•anchor: An optional HTML anchor for the link.
•transaction: If true, appends the current transaction token to the URL as a request parameter. Refer to the entry for <logic:present> for details on transaction tokens.
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 |
411 |
•paramName,paramProperty,paramScope and paramId: You use these to create a single request parameter. The request parameter is appended to the final URL. The first set of three attributes is used to locate a single object on the current request or session. This object’s toString() is the single parameter value. The name of the parameter is given by paramId.
•name/property/scope: You use these to create multiple request parameters. The request parameters are appended to the final URL. These attributes are used to locate an object of type java.util.Map. The Map’s keys are the parameter names, and the corresponding values are the parameter values. If you specify property, you must also specify name.
•useLocalEncoding: If set to true, tells Struts to use whatever the character encoding is for the current HttpServletResponse.
Examples
Here’s a simple example using a global forward:
<html:rewrite forward="success" />
The rendered string will be the true URL for the success global forward. For more examples, refer to the entry for <html:link>.
Equivalents
None.
select, with option, options, and optionsCollection
select displays an HTML selection.
The other option tags are nested within it in order to render options for the enclosing select element:
•option: Renders a single option. There are attributes you can use to help with localizing the displayed text.
•options: Displays a list of options, populated from a JavaBean.
•optionsCollection: A more streamlined version of options. Also displays a list of options populated from a JavaBean.
414 |
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 |
getLabel() that are ready to use with optionsCollection. Listing C-1 shows how you might use this class (perhaps in an Action subclass).
Listing C-1. Using the LabelValueBean Class
//create collection to hold value-label pairs List labelValuePairs = new ArrayList();
//populate collection
labelValuePairs.add( new LabelValueBean("labelOne", "valueOne")); labelValuePairs.add( new LabelValueBean("labelTwo", "valueTwo"));
//save to request under suitable label request.setAttribute("myOptions", labelValuePairs);
Simple Performance Optimizations
For performance reasons, you should save and reuse a single collection instance, and not re-create it in each populating Action.
Sometimes, though, your selection may require a mix of dynamic and static options. One simple solution in this situation is to use more than one <html:optionsCollection>— one for the static options that come from a cache, and another that refers to dynamically created value-label pairs.
Even in the case of dynamically created pairs, some optimization is possible. The most time-consuming task is creating the new LabelValueBean objects. If the possible valuelabel combinations are finite, you might want to cache them in a WeakHashMap, which acts as a temporary cache. Of course, the benefits of caching the JavaBeans this way might be outweighed by the performance hit in calculating the keys to retrieve the bean from the WeakHashMap. So, this technique works best when you already have a usable key at hand.
Internationalization
The use of JavaBeans instead of Struts’ message resource mechanism means that the option labels can’t be readily localized. One simple solution is to use a custom class (see Listing C-2) for the collection (we’ll use an Iterator), and to use LabelValueBeans to store message resource keys pointing to the localized label instead of the actual label.
The translation from message key to actual label while at the same time not creating unnecessary objects requires some trickery, as you can see from Listing C-2.
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 |
415 |
Listing C-2. The LocalizableIterator Class
/*************************************************
*Copyright 2005 Arnold Doray
*This code is released under the Lesser GNU
*General Public License. Please refer to:
*http://www.gnu.org/copyleft/lesser.html
*for details on this license.
*************************************************/
import java.util.Iterator; import java.util.Locale;
import org.apache.struts.util.MessageResources; import org.apache.struts.util.LabelValueBean;
public class LocalizableIterator implements Iterator{
protected LocalizedLabelValueBean _bean = null; protected Iterator _labelValuePairs = null;
public LocalizableIterator(){
_bean = new LocalizedLabelValueBean();
}
public void set(Iterator labelValuePairs, Locale locale, MessageResources resources){
_labelValuePairs = labelValuePairs; _bean.setLocale(locale); _bean.setResources(resources);
}
public boolean hasNext(){
return _labelValuePairs.hasNext();
}
public Object next(){
return _bean.setLabelValueBean( (LabelValueBean)_labelValuePairs.next());
}
416 |
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 |
public void remove() throws UnsupportedOperationException{ throw new UnsupportedOperationException();
}
public class LocalizedLabelValueBean{ private MessageResources _resources; private Locale _locale;
private LabelValueBean _delegate; private String _label = null;
private void setLocale(Locale locale){ _locale = locale;
}
private void setResources(MessageResources resources){ _resources = resources;
}
private LocalizedLabelValueBean setLabelValueBean(LabelValueBean delegate){
_delegate = delegate; _label = null;
return this;
}
public String getValue(){ return _delegate.getValue();
}
public String getLabel(){ if(null == _label){
_label = _resources.getMessage(_locale, _delegate.getLabel());
}
return _label;
}
}
}
As Listing C-2 shows, the LocalizableIterator produces the same object when next() is called, each time configured with a different LabelValueBean. Here’s how you might use this class in your Action subclasses. Remember that, unlike Listing C-1, the underlying