怎么样在Struts使用JavaBean和List?
怎么样在Struts使用JavaBean和List?
在Strust中,我们可能经常要在ActionForm中使用其他JavaBean作为属性类型,这里就存在着如何使用好这些属性与HTML Form之间的数据交换,下面我们就这些问题做一讲解。
如在用户注册界面中,我们通常会将用户的联系方式形成一个单独的新的Class,如Contact,包含以下属性:电话(tel),手机(cell),Email(email),QQ(qq),通信地址(adress)等等,这样条理也比较清晰,以下是这个ActionForm的部分代码:
public class RegisterForm extends ActionForm
{
private Integer id;
private String logonName;
private String realName;
private Contact contact=new Contact();
………..
}
在这里我们需要将Contact实例化(在reset函数中需要重新实例化),这主要因为Struts的机制:如我们将HTML的Form元素(如email)值传给ActionForm,Struts需要执行的操作是getContact().setEmail(String email),如果这时返回的contact对象为空的话,那么赋值如何进行,而且Struts也不会知道如何去实例化Contact,有时这些JavaBean的类型有可能是接口,实例化更是未知,所以关于JavaBean类型在ActionForm中的实例化,你需要自行完成,而且必须完成。至于在实际操作中判断JavaBean是否被进行过相关操作(不再是初始状态),你需要自行判断,其实也很简单,如可在Contact类中编写一个函数检验一下即可。
ActionForm创建完毕后,我们需要在Jsp Form中引用这些JavaBean类型的属性值,那就很简单啦,只需采用“Form的属性名称”+“.”+“JavaBean中的属性名称”结构构成的名称付给相关元素即可。如:
<html:text property="contact.email"/>
通过这种方式我们就可以处理好ActionForm中的JavaBean类型的属性值了。
实际的情况可能更复杂些,我们有时可能要提交多行数据到后退,而且行内的数据是相关的,如我们需要提交多个用户的联系方式,这些行内的数据,如email,电话,手机,这些数据都是和用户编码相关的,现在我们修改一下Contact类,添加一个用户编码(userId)属性,这时我们构建的ActionForm中可能需要一个列表数据(List)类型来处理这种情况。以下是这个ActionForm的部分代码:
public class ModifyBatchContactForm extends ActionForm
{
private List contact =new AutoArrayList (Contact.class);
…..
}
在以上代码中,我们同样处理了List类型数据的初始化。Struts在给List中的对象赋值时,当然需要先获取List数据,然后在获取List中某一个对象(通过Index),最后给对象赋值。在这里想我们可以更详细点分析浏览器端传过来数据,字段值形式如下:contact[0].email=linux_china@hotmail.com,Struts获取ActionForm中的List数据后,通过Index(此时为0)来获取List中封装的JavaBean对象,然而此时List是空的(尽管初始化了,但是没有数据),是无法取得封装的对象的,因此我们要在Struts获取List中封装的对象的时候给它创建一个,这样就保证对象的获取和赋值的成功进行,所有我们新建一个AutoArrayList类,继承ArrayList,只要重写get(int index)方法即可,其实很简单,代码如下:
public class AutoArrayList extends ArrayList {
private Class itemClass;
public AutoArrayList(Class itemClass) {
this.itemClass = itemClass;
}
public Object get(int index) {
try {
while (index >= size()) {
add( itemClass.newInstance());
}
} catch (Exception e) {
e.printStackTrace();
}
return super.get(index);
}
}
这样我们就完成可以多行数据提交的ActionForm设计,这里还有点提醒,如果从浏览器端传过来的行索引是跳跃是的,如缺少中间行,而你不想要这些数据的话,且首尾行index相差很大的话,这种方式可能不太适合。这种多行提交形式比较适合对固定行的数据处理。如果行数不固定的话,你可以参考使用MapForm方式实现。
下面我们就看看如何在Jsp中使用这个ActionForm,其实只需要执行一个循环即可:
<logic:iterate id="contact" name=" FormName " property="contact" indexId="index">
<html:text name=" contact " property="userId" indexed="true" />
<html:text name=" contact " property="email" indexed="true"/>
</logic:iterate>
这里我们再讲解一下,代码中出现的“contact”(红色)都是ActionForm中的List数据类型变量名称,请确保一致,请不要更改名称,这也是方便提交到后台的数据接收。“FormName”为在struts-config中声明的ActionForm名称。indexed="true"可以确保生成的html元素的名称唯一,不要缺少这个声明。以上的Jsp代码,你也可以使用JSTL来完成,就看你习惯如何了。
通过以上步骤,我们完成了多行数据的提交所有环节,这样Struts就会完成其他所有的事情,我们的代码逻辑和实现也简单多了。
总结:通过以上两个例子,相以信对ActionForm中使用JavaBean和List类型数据不会再陌生,同时使用Map类型,这样可创建更好的ActionForm设计,关于MapForm,请参考http://www.jetmaven.net/documents/j_mapformInStruts.php。不过引入这种方式后,在Validator方面你可能要花点脑筋啦(如通过XDoclet生成Validator文件可能功能不全),可能你需要手写一些代码来完成相关工作。