The value is: ${value} 修改 Another 类: public class Another { private String value; @Component(parameters = { "page=start" }) private PageLink goToStart; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } 修改 Start 类: public class Start { @Property 第二章 基础 28 private String theValue = "Init Value"; @InjectPage private Another anotherPage; public String getGreeting() { return "Hello Tapestry!"; } @OnEvent(value = "action", component = "actionLink1") Object toAnotherPage() { return anotherPage; } Object onSuccessFromForm1() { anotherPage.setValue(theValue); return anotherPage; } } 然而,当我们提交表单,Another 页面并没有显示 Start 页面传过来的数据,如图 2-10。 (图 2-10) 这是为什么呢? 要知道造成这个问题的原因,需要了解 Tapestry 的页面池。 页面池 当 Tapestry 收到一个页面请求时,Tapestry 需要一个页面实例来生成 Html 代码。页面 实例可看成是页面类和页面模板的混合体,用于生成最终的 Html 代码。 假设在一段时间内有许多用户请求 A 页面。如果对每个请求,都为其新建一个 A 页面 实例并在使用后销毁,那么新建和销毁页面实例将是不小的开销。为了提高性能,Tapestry 使用页面池。当一个用户请求 A 页面,Tapestry 将从页面池中取出一个 A 页面实例并在使用 后放回页面池供以后的请求使用,这样就减少了新建和销毁页面实例的开销。 当用户往页面中输入了某些数据,这些数据将保存在页面实例中,如果不加处理就把此 页面实例放回页面池,那么这些数据将会被暴露给下一个使用此页面实例的用户。为了避免 第二章 基础 29 出现这种情况,在一个页面实例被放回页面池之前 Tapestry 会对其进行清理,把其中的变量 重置为初始值。 回过头来看前面的问题,当我们在 Start 页面中输入数据并提交表单,会依次发生如下 事情: 第一步,客户端向 Tapestry 发出一个组件事件请求,触发 Start 页面实例的 onSuccessFr omForm1()方法。 第二步,Tapestry 从页面池取出一个 Another 页面实例并设置其 value 属性。 第三布,Tapestry 通知客户端重定向到此 Another 页面。 第四步,客户端请求 Another 页面。 第五步,Tapestry 从页面池取出一个 Another 页面实例用来生成 Html 代码发送给客户端。 很显然,在整个过程中,客户端向 Tapestry 发送了两次请求。对每次请求,Tapestry 都 是从页面池中新取出一个 Another 页面实例来处理,请求处理完成后,Another 页面实例又 会被放回页面池,保存在其中的数据也就被清除了。因此即使第五步中所用 Another 页面实 例就是第二步中所用的那一个(也有可能不是同一个),其中的数据也已经被清除过了。 试想如果在第二步设置完 Another 页面实例的 value 属性后,就直接用此页面实例生成 Html 代码发送给客户端,而不需要经过重定向,那么前面数据丢失的问题就不存在了。 我们可以配置 Tapestry 以禁止重定向。 禁止重定向 修改 AppModule 类: public class AppModule { public static void contributeApplicationDefaults( MappedConfiguration
${defaultTitle}
Customer Service

