Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Apache Struts - From Novice To Professional (2006)

.pdf
Скачиваний:
60
Добавлен:
17.08.2013
Размер:
11.68 Mб
Скачать

408

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.

Each rendered <option> has a value and a label. The value is the value submitted if that option is selected. The label is the text presented to users in order for them to make the selection.

412

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

Usage Restrictions

The select tag must be inside an <html:form> tag, and the various option tags must be nested within an <html:select> tag. There are a couple other restrictions:

The property attribute is required for select.

The value attribute is required for option.

Attributes for select

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. Besides these, there are a couple of attributes specific to select:

multiple: Enables multiple selections if specified (the actual value is unimportant). The underlying property must be an array if the multiple attribute is specified. As with <html:multibox>, you must set the underlying property to a zero-length array in your ActionForm’s reset() if you want to detect an unselected item. See the entry for <html:multibox> for details.

size: The number of options to display at once.

Attributes for option

The option tag accepts the ren-attrs attribute set. Besides this, the following attributes are specific to option:

value: The submitted value. This attribute is required.

key: The message resource key that specifies the label for the option. If omitted, the label is the text nested within the option tag’s body.

locale/bundle: These attributes are used to specify a different Locale object or message resource file. locale specifies a key that can be used to look up the Locale object stored on the current session. The bundle attribute is explained in more detail in the entry for <bean:message>. You’d use these attributes to specify a locale different from the current user’s locale or a message resource file different from the default one.

Attributes for options

The option tag accepts the ren-attrs attribute set, except for the styleId attribute. (This attribute is left out because the options tag might render more than one HTML <option> element, and the HTML standard forbids you from having two elements with the same id.)

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

413

There are two ways to specify the values and labels to use for each rendered <option> element:

Specify the collection/property/labelProperty attributes: The collection attribute gives the name of a collection of JavaBeans, each holding the value and label for a single <option>. The property attribute is the name of the getXXX() function that is called on each bean to obtain the value for an <option>. Similarly, the labelProperty attribute is the name of the getXXX() function that is called on each bean to obtain the label for an <option>. If labelProperty is omitted, the <option>‘s value is used as a label.

Specify name/property and labelName/labelProperty attributes: The name and property pair specifies a collection in any scope from which to get the values for each rendered <option>. If you specify the property attribute only, then the ActionForm subclass is the implicit base object. Similarly, the labelName and labelProperty pair specifies a collection from which to get the labels for each rendered <option>. If only labelProperty is specified, then the ActionForm subclass is the implicit base object. If neither labelName nor labelProperty is specified, the labels are the same as the values.

The remaining attribute of <html:options> is filter, which if true filters the labels for HTML reserved characters (like <, >, or &). The default is true.

Attributes for optionsCollection

optionsCollection is a simplified, streamlined version of <html:options>. Like <html:options>, the optionsCollection tag accepts the ren-attrs attribute set, except for the styleId attribute. It also has the filter attribute, like <html:options>.

optionsCollection assumes that the values and labels for each rendered <option> are stored in a collection of JavaBeans. This collection is specified using the name and property attributes. If you specify the property attribute only, then the ActionForm subclass associated with the enclosing form is the implicit base object. Each JavaBean is assumed to have two getXXX() functions from which to obtain the value and label for a single <option> tag.

By default, the name of the function for obtaining values is getValue(). The function for labels is getLabel(). If you wish to specify different names for each, then use the value and label attributes. For example, setting value="color" would mean that the getColor() function is called to determine the value for each <option>.

The LabelValueBean Class

For options and optionsCollection, you need to have a JavaBean class with getXXX() functions for values and labels. Struts has a utility class called org.apache.struts. utility.LabelValueBean that does exactly this. It has the functions getValue() and

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

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

417

collection of LabelValueBean (given by the variable labelValuePairs in Listing C-2) now stores message resource keys instead of actual labels:

//somehow get collection of LabelValueBeans

//the labels on these are really message resource keys List labelValuePairs = ...

//create a new LocalizableIterator LocalizableIterator li = new LocalizableIterator();

//initialize it li.set(labelValuePairs.iterator(),

getLocale(request), getResources(request));

//save to request under suitable label request.setAttribute("myOptions", li);

Examples

You may mix one or more option/options/optionsCollection tags in your JSP code. Here’s an example:

<html:select property="selectedColor">

<html:option value="new-color" key="app.prompt.newcolor" /> <html:optionsCollection name="myOptions" />

</html:select>

Or, to enable multiple selections, use this:

<html:select property="selectedColor" multiple="true"> <html:optionsCollection name="myOptions" /> <html:options collection = "myOtherOptions"

property = "value" labelProperty="label" />

</html:select>

Remember, the value of the multiple attribute is unimportant—as long as the multiple attribute is specified, Struts assumes the underlying property is an array.

Equivalents

JSF’s <h:selectOneListbox> is an equivalent for a single-selection list. <h:selectManyListbox> is an equivalent for a multiple-selection list.