我正在尝试使用动态表单,并且根据属性类型,我想显示不同的输入样式(文本字段,单选按钮,下拉列表,清单等)。
为了获得动态表单,我为ActionForm设置了一个Map。
Map<String, Object> values;
public void setValue(String key, Object value);
public Object getValue(String key);
我尝试设置清单或多重框时遇到问题。尽管我希望将String []映射到Object参数,但ActionForm仅传递一个值。
关于如何解决这个问题的任何想法吗?
编辑:在JSP中:
<input type=checkbox name="value(foo)" />
最佳答案
我调查了这个问题,发现正在发生的事情。问题不在于Struts,而在于BeanUtils(Struts用于使用请求参数填充表单)。
我设法通过从框架中提取(仅测试)代码片段来复制此代码:
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<String, Object> properties = new HashMap<String, Object>();
// 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);
}
}
当您运行此程序时,您只会得到一个值(就像您指定的那样):
foo=1
事实是BeanUtils认为这是一个映射属性,并照此处理,为键指定了标量值。由于您的值是一个数组,因此只使用第一个元素:
...
} else if (value instanceof String[]) {
newValue = getConvertUtils().convert(((String[]) value)[0], type);
...
您可以做的是修改JSP和ActionForm以分别处理值列表。修改示例:
public class MyForm {
private Map<String, Object> map = new HashMap<String, Object>();
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<String, Object> properties = new HashMap<String, Object>();
// 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);
}
}
以上意味着您使用
<input type="..." name="value(foo)" ... />
对于JSP中的所有单个元素,而对于复选框(通常将其扩展为多值元素),则使用
<input type="checkbox" name="plainValue" ... />
然后您在ActionForm中将其委托给地图一次。