I\'m trying to have a dynamic form and, depending on an attribute type, I would like to display a different input style (textfield, radio buttons, dropdown, checklist, ...).
I looked into this issue and found out what was happening. The problem is not with Struts but with BeanUtils (which Struts uses for populating the form with the request parameters).
I managed to duplicate this by extracting a (test only) snippet of code from the framework:
public class MyForm {
// assume this is your Struts ActionForm
public void setValue(String key, Object val) {
System.out.println(key + "=" + val);
}
}
public class Test {
public static void main(String[] args)
throws IllegalAccessException, InvocationTargetException {
MyForm s = new MyForm();
Map properties = new HashMap();
// Your request should be like yourActionUrl?value(foo)=1&value(foo)=2&value(foo)=3
// and Struts calls bean utils with something like:
properties.put("value(foo)", new String[] {"1", "2", "3"});
BeanUtils.populate(s, properties);
}
}
When your run this you get printed one value only (just as you desrbibed):
foo=1
The thing is that BeanUtils considers this a mapped property and treats it as such, going for a scalar value for the key. Since your value is an array it just uses the first element:
...
} else if (value instanceof String[]) {
newValue = getConvertUtils().convert(((String[]) value)[0], type);
...
What you can do is modify your JSP and ActionForm to treat the list of values separately. Example modified:
public class MyForm {
private Map map = new HashMap();
public void setValue(String key, Object val) {
map.put(key, val);
}
public void setPlainValue(String[] values) {
// this is correctly called; now delegate to what you really wanted
setValue("foo", values);
}
}
public class Test {
public static void main(String[] args)
throws IllegalAccessException, InvocationTargetException {
MyForm s = new MyForm();
Map properties = new HashMap();
// Notice the change to your URL..
// yourActionUrl?plainValue=1&plainValue=2&plainValue=3
properties.put("plainValue", new String[] {"1", "2", "3"});
BeanUtils.populate(s, properties);
}
}
The above means that you use
for all the single elements in your JSP, while for your checkboxes (extending it to multivalue elements in general) you use
and you delegate to the map once in your ActionForm.