摘要
本文将讨论两中类型的表单scoping,并提出将Array或Complex DataType作为FormBeans成员处理的问题。
在该示例中,我们采用了一组复选项来演示两个表单scoping如何与表单bean一起工作。
本文还包含一些适用于Workshop 8.1和Workshop 9.2的示例。
Form Bean Scoping
有两种不同的scoping可用于Form Bean:(1) request-scoping和 (2) page flow-scoping。
Request-Scoped Form Bean
默认情况下,传递给action方法的Form Bean实例是request-scoped实例。
/**
* @jpf:action
* @jpf:forward name="success" path="displayData.jsp"
*/
protected Forward submit( MyFormBean requestScopedBean )
{
return new Forward( "success" );
}
“Request-scoped”意味着Form Bean实例与HTTP请求具有相同的生命周期。Form Bean实例的创建时间与该请求的创建时间相同,并在销毁该请求时被销毁(连同其中的所有数据)。Request-scoped Form Bean实例在从单个JSP页面向单个action方法提交数据时很有用。
Page Flow-Scoped Form Bean
Page Flow-scoped Form Bean实例与Controller文件实例具有相同的生命周期。随着Controller文件实例的创建和销毁,它们也被创建和销毁。这使得Page Flow-scoped Form Bean可用来存储在许多不同JSP页面之间累积的数据。
要创建Page Flow-scoped Form Bean实例,可在Controller文件中构造Form Bean的一个公共成员变量。
public class myController extends PageFlowController
{
public MyFormBean pageFlowScopedBean = new MyFormBean();
.
.
.
}
一旦创建了Form Bean的Page Flow-scoped实例,就可以通过使用@action form="form_bean"注释将该实例传递给action方法。
public class myController extends PageFlowController
{
public MyFormBean pageFlowScopedBean = new MyFormBean();
/**
* @jpf:action form="pageFlowScopedBean"
* @jpf:forward name="success" path="displayData.jsp"
*/
protected Forward submit( MyFormBean form )
{
return new Forward( "success" );
}
}
每次调用submit() 方法时,都会向它传递相同的Form Bean实例,即pageFlowScopedBean,该实例是在创建Controller文件实例时创建的。
Request Scoped Form Bean中的数组或复杂数据类型
formBean的默认作用域是Request;因此,每个http请求都会触发容器来实例化一个新的formBean实例。也就是说,在后续表单提交时不会使用包含大型数组的formBean实例。
容器通常调用setXXX方法将值设置到表单bean中。但在使用数组或复杂对象类型的情况下,容器会在将某个值设置到每个数组元素之前对数组类型对象或复杂类型对象调用getXXX方法。因此,您需要修改getter方法并确保数组被初始化为正确大小。默认情况下,workshop将它初始化为1并将生成一个如下所示的setter:
public String[] getName() {
// For data binding to be able to post data back, complex types and
// arrays must be initialized to be non-null.
if(this.name == null || this.name.length == 0) {
this.name = new String[1];
}
return this.name;
}
可以修改此代码,将String数组设置为任意大小。
什么时候可以不在Request Scoped form bean中使用数组:
上述解决方案中的问题是,我们需要知道数组的大小,以及表单bean是否具有一个可能包含数组的复杂对象,然后还需要知道该对象的大小以及硬编码值的种类。
并非在所有的情况下都有这种可能,page flow scoped form bean在克服这些问题上很有帮助。
PageFlow Scoped Form Bean中的数组或复杂数据类型
此设计方法允许用户解决以下问题。
·formBean包含non-static array sized数组类型。
·formBean包含作为属性的XMLBean Document,并且此XMLBean Document中的一个或更多元素具有数组类型。
·getXXX方法返回非null数组类型作为默认值,并且数组大小通常被设置为1。可以使用setXXX设置具有更大数组大小的对象,但在提交表单时,只提交一个元素。
什么时候可以不在Page Flow Scoped form bean中使用数组:
在使用数组时,有些情况类似于单个portlet,您无法使用Pageflow scoped formbean,在这种情况下需要使用Request Scoped Form Bean。
代码示例:
在此示例中,演示了如何让复杂java bean数组与request scoped form bean和page flow scoped form bean一起工作。
我们定义了一个java bean“FormListBean”,它有一个字符串和一个int成员变量,并且Form Bean有一个类型为“FormListBean”的数组。
设置:
- 在应用程序中创建一个Web Project。
- 右击文件夹示例并将它导入web项目。
- 构建并运行Controller。
- 该Controller将生成一个页面,该页面包含一个带有默认值的字符串和复选框组成的表。
- 您可以编辑并提交数据,显示页面将显示所有修改的数据。
若想再次进行测试,可以通过单击页面上的Reset按钮重置这些值,这会将您带入索引页面。
结束语
本文谈论了两种类型的表单bean scoping,并介绍了在将数组或复杂对象类型作为表单bean的成员变量时如何使用它们,还介绍了如何在数组中修改数据并提交它们。本文还讨论了无法将某一特定表单bean用于具有数组数据类型的表单bean时的场景。文中还附带了一些在8.1和9.2上都可以使用的示例,这些示例既适用于Request Scoped Form Bean,也适用于Page Flow Scoped Form Bean。
参考资料
电子文档参考资料 - BEA的电子文档页面
RequestScoped_Workshop8.1.zip - workshop 8.1中包含数组的request scoped form bean的示例
PageFlowScoped_Workshop8.1.zip - workshop 8.1中包含数组的page flow scoped form bean的示例
RequestScoped_Workshop9.2.zip - workshop 9.2中包含数组的request scoped form bean的示例
PageFlowScoped_Workshop9.2.zip - workshop 9.2中包含数组的page flow scoped form bean的示例
原文出处:http://dev2dev.bea.com/blog/rvimala/archive/2006/11/working_with_ar.html