将Mapped属性与Struts中的Indexed属性相结合 [英] Combining Mapped properties with Indexed properties in Struts

查看:114
本文介绍了将Mapped属性与Struts中的Indexed属性相结合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用动态表单,并且根据属性类型,我想显示不同的输入样式(文本字段,单选按钮,下拉列表,清单......)。

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, ...).

为了获得动态表单,我使用Map设置了ActionForm。

In order to have the dynamic form, I've set up the ActionForm with a Map.

Map<String, Object> values;
public void setValue(String key, Object value);
public Object getValue(String key);

当我尝试设置清单或多功能箱时出现问题。 ActionForm只传递一个值,虽然我原本期望String []被映射到Object参数。

My problem comes when I try to set up a checklist or multibox. The ActionForm only passes one value, although I would have expected that the String[] would be mapped to the Object argument.

关于如何解决这个问题的任何想法?

Any idea about how can I solve this?

编辑:在JSP中:

<input type=checkbox name="value(foo)" />


推荐答案

我调查了这个问题,发现了发生的事情。问题不在于Struts,而在于使用 BeanUtils (Struts用它来填充带有请求参数的表单) )。

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<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);
  }
}

当你运行这个时,你只会打印一个值(正如你所说的那样):

When your run this you get printed one value only (just as you desrbibed):

foo=1

问题在于BeanUtils认为这是一个映射属性并将其视为这样,为密钥的标量值。由于你的值是一个数组,它只使用第一个元素:

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);
...

你可以做的是修改JSP和ActionForm来处理列表值分开。修改示例:

What you can do is modify your JSP and ActionForm to treat the list of values separately. Example modified:

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中的所有单个元素,而对于复选框(将其扩展为一般的多值元素) )你使用

for all the single elements in your JSP, while for your checkboxes (extending it to multivalue elements in general) you use

<input type="checkbox" name="plainValue" ... />

并在ActionForm中委托一次地图。

and you delegate to the map once in your ActionForm.

这篇关于将Mapped属性与Struts中的Indexed属性相结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆