Combining Mapped properties with Indexed properties in Struts

前端 未结 1 1159
面向向阳花
面向向阳花 2020-12-22 02:04

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

1条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-22 02:24

    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.

    0 讨论(0)
提交回复
热议问题