程序人生(程序篇- DynaActionForm类&支持Map的ActionForm(Map-backed ActionForm))

DynaActionForm类

随着页面的增多,ActionForm的数量也会急剧膨胀。对ActionForm类的维护会成为一件耗时、费力的工作。而且每个ActionForm都只是简单、重复地收集、验证属性,然后再把它们传递给业务逻辑Bean。引入DynaActionForm类就是要试图解决这个问题。DynaActionForm使你不必创建一个个具体的ActionForm类,为每个bean的属性编写get/set方法。你只需在Struts的配置文件中列出DynaActionForm的属性、类型、缺省值,这样可以大大地减少工作量。

下面的struts-config.xml的XML片断会配置出一个带有givenName、familyName两个字段的UserForm bean

<form-bean
    name="UserForm"
    type="org.apache.struts.action.DynaActionForm">
    <form-property
        name="givenName"
        type="java.lang.String"
        initial="John"/>
    <form-property
        name="familyName"
        type="java.lang.String"
        initial="Smith"/>
</form-bean>

DynaActionForm支持以下数据类型:
java.lang.BigDecimal
java.lang.BigInteger
boolean and java.lang.Boolean
byte and java.lang.Byte
char and java.lang.Character
java.lang.Class
double and java.lang.Double
float and java.lang.Float
int and java.lang.Integer
long and java.lang.Long
short and java.lang.Short
java.lang.String
java.sql.Date
java.sql.Time
java.sql.Timestamp

DynaActionForm还支持由这些数据类型构成的数组(比如String)、Map接口的实现类(比如java.util.HashMap)、 List接口的实现类(如 java.util.ArrayList)。如果你没有给属性设定初值,数字类属性会自动设定为0,对象类属性设定为null。如果使用基本的Struts标志库访问DynaActionForm对象的属性,访问的方法和访问普通ActionForm对象的方法相同。你还可以用bean:define来显示DynaActionForm的属性(当然用bean:define不会创建DynaActionForm实例,因为创建DynaActionForm需要有恰当的动态属性(dyna-properties))。

如果你使用的是Struts JSTL EL标签库,JSTL访问ActionForm和DynaActionForm的语法是不同的。JSTL表达式语法只能直接访问普通的ActionForm对象的属性。要访问DynaActionForm的属性必须稍加修改。Struts JSTL EL用类似以下的语法来访问ActionForm属性:
${formbean.prop}
访问DynaActionForm属性的语法则需要修改为:
${dynabean.map.prop}
map是DynaActionForm的一个Hashmap属性,而且这个map包含了DynaActionForm的属性(DynaActionForm将属性保存在一个HashMap类对象中)。如果你的ActionForm使用的是简单的属性和标准的验证,而且只需把这些属性传递到另一个JavaBean(用BeanUtils.copyProperties(myBusinessBean,form))。完成这样的任务DynaActionForm会是一个很好的解决方案。

DynaActionForm并不只是ActionForm的"丢进来" 替代品(drop-in replacement)。如果你要在Action中访问ActionForm的属性,你就会用到map-style的访问器,类似myForm.get(“name”)。如果你要在Action中频繁地使用ActionForm对象,我建议你还是选择普通的ActionForm对象。 DynaActionForm必须要由一个带参数的构造函数来初始化。为了模仿其他的属性,在他们的构造中包含了很多方法。对你而言,要生成一个DynaActionForm,则必须由Struts通过ActionMapping来实现。

通过扩展DynaActionForm你可以实现自己的validate和reset方法。并在struts-config.xml指定你的DynaActionForm子类。然而,我们不能混淆普通属性和动态属性(DynaProperties)。Java类的反射机制无法在DynaActionForm中找到普通的getter和setter方法。如果要使用Struts的验证器,你需要把form-bean类指定为org.apache.struts.validator.ValidatorActionForm或是它的子类。



支持Map的ActionForm(Map-backed ActionForm)


DynaActionForm类可以根据我们在Struts配置文件中的列举出来的属性在初始化的时候创建ActionForm。但在某些情况下HTML窗体需要动态生成的。这些ActionForm窗体的属性事先我们并不知道,那么我们要如何动态地创建ActionForm属性呢?要解决这个问题我们必须要依靠一种新的解决方法。

Struts允许将属性保存在一个Map类对象中。你可以把窗体中动态字段的数据存储到Map中。下面是一个支持Map的ActionForm的例子:

public FooForm extends ActionForm {
    private final Map values = new HashMap();
    public void setValue(String key, Object value) {
        values.put(key, value);
    }
    public Object getValue(String key) {
        return values.get(key);
    }
}

在JSP页面中,你可以用mapname(keyname)这样的符号来访问存储在map中的值。用这样的语法访问属性意味着:

mapname属性多半支持map接口,而且是根据String建立索引的。
Struts根据通过get(String key)/set(String key ,Object value)方法找到正确的子属性(sub-property)值。Struts会从括弧中取出keyname的值,并在调用get/set方法的时候使用。

这是一个简单的例子: <html:text property="value(foo)"/> 这个标志会以”foo”为参数调用FooForm的getValue方法,最后这个方法会返回"foo"的属性值。如果你想要根据动态的属性名生成一个窗体,你可以参考下面的代码:

<%
  for (int i = 0; i < 10; i++) {
       String name = "value(foo-" + i + ")";
%>
  <html:text property="<%= name %>"/>
  <br/>
<%
  }
%>

你可能已经注意到了我们并没有指定name的值。map-backed属性名任由你定义,同一个bean中你甚至可以定义多个map-backed属性。


除了map-backed属性,你还可以生成list-backed(支持list接口)的属性。和map-backed属性一样,你也要在bean中创建如下的get/set方法。

public FooForm extends ActionForm {
    private final List values = new ArrayList();
    public void setValue(int key, Object value) {
        values.set(key, value);
    }

    public Object getValue(int key) {
        return values.get(key);
    }
}

在显示页面中你还可以通过使用特定的符号访问list-backed属性。方括弧中的属性名包含了以下的意思:

listname属性(多半支持list接口)是根据String建立索引的。
Struts应该根据带int类型key参数的get/set方法找到正确的子属性(sub-property)值。

虽然map-backed ActionForm向我们提供了更多的灵活性。但是一些常规ActionForm和 DynaActionForm能用的语法在map-backed ActionForm却得不到支持。
 
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页