`

【转】深入理解Tapestry的Rewind

阅读更多

【转】深入理解Tapestry的Rewind

Tapestry的rewind一直是学习和使用Tapestry的难点,rewind是用来处理表单提交的,表单默认使用的是 DirectService来提交。在详细介绍之前,先说明下此文中需要用到的一些概念,首先是表单组件,我这里指的是指继承自 AbstractFormComponent类的组件,例如:TextField、TextArea、Checkbox等,而不是具体的Form组件,表单组件使用时必须在Form组件中,这些组件在rewind时调用继承自AbstractFormComponent的 rewindFormComponent来读取数据,并将数据赋值给容器或者页面。

    我们来看一下最简单的TextField组件,组件定义如下

<input jwcid= "price@TextField" type= "text" value= "ognl:picture.price" translator= "translator:number,pattern=##.##" validators= "validators:min=0" displayName= "价格" class = "input_text" />

    再看一下TextField中的rewindFormComponent组件方法

protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle) ...{
//从请求中得到参数值
String value = cycle.getParameter(getName());

try ...{
//用translator来转换值
Object object = getTranslatedFieldSupport().parse(this, value);
//用validators来验证值
getValidatableFieldSupport().validate(this, writer, cycle, object);
//赋值给容器或者页面
setValue(object);
} catch (ValidatorException e) ...{
getForm().getDelegate().record(e);
}
}

    可以看到在rewindFormComponent中,主要是从请求中取得用户输入的值,然后进行处理,最后赋值给容器或者页面,上面的例子中会调用页面类的getPicture().setPrice(“用户输入的值”)来进行赋值。这样整个表单的提交就可以理解为所有的表单组件读取用户输入的值并赋值给页面的过程。

    整个表单提交的详细处理过程如下:

* initialize():页面初始化
* pageBeginRender() ("rewind"):getRequestCycle().isRewinding()为true
* rewind of the form / setting of properties:所有表单组件调用rewindFormComponent来取值赋值
* Deferred listeners (for Submit components):调用Submit组件的listener
* Form's listener:调用Form组件的listener
* pageEndRender() ("rewind"): getRequestCycle().isRewinding()为true
* pageBeginRender() (normal): getRequestCycle().isRewinding()为false
* pageEndRender() (normal): getRequestCycle().isRewinding()为false

    我们可以看到pageBeginRender和pageEndRender被调用了两次,两次中的区别为RequestCycle(). isRewinding,因为我们在使用时经常利用pageBeginRender的初始化值,所以这里有很多使用上的误区,如果在 pageBeginRender中从数据库读取数据来初始化跟表单提交无关的变量的话,就可能被调用两次,这个是应该避免的。什么叫跟表单提交无关的变量呢,就是表单组件中跟赋值无关的,例如上边提到的value="ognl:picture.price",这时picture就是与表单提交相关的变量,如果你没有初始化,那么在赋值时调用getPicture().setPrice()就会出现空指针异常,因为这是的picture为null。我们举个例子来看一下表单无关的变量,假如这个picture页面会显示一个创建picture的表单和所有picture的列表,那这个picture的列表就是与表单提交无关的变量,如果你在pageBeginRender中初始化的话,就需要区分是否rewind,否则表单提交时就会被初始化两次,让我们看一下代码:

public abstract void setPictures(List<Picture> pictures);
public abstract void setPictureInList();//用于For中的value
public abstract void setPicture(Picture picture);//用于表单创建
public abstract Picture getPicture();
public void pageBeginRender(PageEvent event) ...{
if(getPicture()==null)...{
setPicture(new Picture());
}
setPictures(getPictureService().findAll());
}

    判断picture是否为null并赋值在页面显示和rewind中都是需要的,因为页面显示时,需要调用getPicture().getPrice (),页面rewind时,需要调用getPicture().setPrice(),这两个阶段中的picture都不能为null。但 setPictures会在表单提交时被调用两次,在rewind阶段初始化它是没有用处的,所以这时就要对是否rewind进行判断。修改后的代码如下:

public void pageBeginRender(PageEvent event) ...{
if(getPicture()==null)...{
setPicture(new Picture());
}
if (!event.getRequestCycle().isRewinding()) ...{
setPictures(getPictureService().findAll());
}
}

    这样就可以避免在rewind时对pictures进行不必要的赋值。这里还要提到的一点是页面显示和提交后的页面很可能不是同一个页面类的实例,大家都知道页面类的实例是从实例池取到的,用户打开页面显示表单完后的页面类实例和用户提交表单时的用来rewind的页面类实例不一定是同一个,即使是一个实例,也是被重新初始化过的,不要想当然的认为显示表单后再提交那个实例应该保存原来显示的东西,这个应该理清楚。

分享到:
评论

相关推荐

    深入浅出Tapestry

    资源名称:深入浅出Tapestry内容简介:本书以循序渐进的方式,从Tapestry框架技术的基本概念入手,讲解Tapestry框架在J2EE Web应用程序中的整体架构实现。使读者在学习如何使用Tapestry框架技术的同时,还能够获得在...

    tapestry 源码 深入研究tapestry最好资料

    tapestry 源码 深入研究tapestry最好资料

    深入浅出Tapestry4一书源代码(1)

    "深入浅出Tapestry4一书"的源代码是作者为了帮助读者更直观地理解Tapestry4的工作原理和实践应用而提供的。 在源代码中,"IceRoom"可能是一个示例项目,它展示了如何使用Tapestry4创建动态Web页面。IceRoom项目可能...

    深入浅出Tapestry高清

    深入浅出Tapestry高清版电子书,国内Tapestry权威人士撰写,中文唯一的Tapestry书籍材料。

    深入浅出tapestry

    本书以循序渐进的方式,从Tapestry框架技术的基本概念入手,讲解Tapestry框架在J2EE Web应用程序中的整体架构实现。使读者在学习如何使用Tapestry框架技术的同时,还能够获得在J2EE Web应用程序中应用Tapestry框架的...

    深入浅出Tapestry4一书源代码(2)

    《深入浅出Tapestry4》是一本专为开发者深入理解Tapestry4框架而编写的书籍。Tapestry4是Apache软件基金会开发的一个开源Web应用程序框架,它以组件化和事件驱动的方式,极大地简化了Java Web应用的开发。本章节我们...

    tapestry-project-4.1.5

    《深入理解 Tapestry 4.1.5:项目实例与核心库解析》 Tapestry 是一个基于 Java 的开源Web 应用程序框架,它强调组件化开发,提供了一种强大的方式来构建动态、高性能的Web 应用。在"tapestry-project-4.1.5"这个...

    tapestry官方中文文档

    它们将帮助初学者理解Tapestry的基本概念、组件使用、事件处理等方面的知识。 总的来说,Tapestry 4是一个强大且灵活的Web开发框架,通过其组件化、声明式编程和事件驱动的特性,能有效提高开发效率,同时保持代码...

    Tapestry简单入门.rar_java Tapestry_tapestry

    首先,让我们深入理解Tapestry的核心理念。Tapestry的目标是通过提高开发效率、简化代码结构和增强可维护性来改善Java Web应用的开发体验。它强调了类型安全和编译时检查,避免了传统JSP中常见的运行时错误。...

    Tapestry4开发指南.rar

    《Tapestry4开发指南》是一份针对Tapestry 4框架的详尽教程,旨在帮助开发者深入理解和熟练运用这一强大的Web应用开发工具。Tapestry是一个开源的Java框架,由Apache软件基金会维护,它提供了组件化、MVC模式以及...

    tapestry源码 api等

    通过研究这些源码和API,开发者不仅可以掌握Tapestry的基本用法,还能深入了解其设计哲学和内部工作流程,从而更好地优化和扩展自己的应用程序。同时,对于那些希望贡献到Tapestry开源项目的人来说,这是一份宝贵的...

    Tapestry 5 電子書

    这本书旨在帮助开发者深入理解和掌握Tapestry 5的各个方面,从而利用其强大功能构建高效、可维护的Web应用程序。 Tapestry 5是一个开源的Java框架,它提供了组件化和模版驱动的开发方式,使得Web应用的构建更为简洁...

    Tapestry用户登录Demo(源代码+操作视频)

    Tapestry是一个强大的Java web应用程序框架,由Apache软件基金会维护。这个“Tapestry用户登录Demo”是一个示例项目,旨在展示...通过研究源代码和观看操作视频,你可以深入理解Tapestry的工作原理,提升自己的技能。

    tapestry4开发指南

    《Tapestry 4开发指南》是一本专为初学者设计的书籍,旨在帮助读者深入理解和熟练运用Tapestry 4这一强大的Java Web框架。Tapestry 4是一款开源的、基于组件的Web应用程序框架,它允许开发者用更加面向对象的方式来...

    Enjoying Web Development with tapestry源码

    《享受Web开发:深入探索Tapestry框架》一书提供了丰富的源码示例,帮助开发者深入理解Tapestry这一强大的Java Web开发框架。Tapestry是Apache软件基金会的一个开源项目,它提供了一种组件化、事件驱动的方式来进行...

    tapestry4和5学习资料

    本压缩包包含了一系列的学习资源,帮助开发者深入理解和掌握Tapestry 4和5的关键概念和技术。 1. **Tapestry5最新中文教程.doc**: 这份文档可能是针对Tapestry 5的最新中文教程,旨在为初学者提供一个易懂的入门...

    Tapestry通用WEB框架

    在深入探讨Tapestry的知识点之前,让我们先了解一下这个框架的核心概念。 1. **组件模型**:Tapestry的核心是组件模型,它允许开发者将UI分成独立、可重用的部件。每个组件都是一个Java类,负责渲染HTML和处理用户...

    Tapestry 5.1 实例教程(全部)

    2. **请求处理**:深入理解Tapestry的请求处理流程,包括页面选择、事件处理和响应生成。 3. **部署与性能监控**:了解如何在生产环境中部署Tapestry应用,并使用Tapestry提供的监控工具进行性能分析。 **四、实战...

    Tapestry例子

    读者可以参考该博客文章以深入理解Tapestry模块化的具体实践。 附带的文件"sql.txt"可能包含与Tapestry应用相关的数据库查询语句或数据模型,而"TapestryHarold.zip"可能是一个示例模块,用于演示或测试Tapestry...

    Tapestry4开发指南

    《Tapestry4开发指南》是由干煸四季豆编写的,旨在帮助开发者深入理解并熟练运用Tapestry4这一框架进行应用开发。Tapestry4是一个基于Java的Web应用程序框架,它强调组件化、模版驱动和声明式编程,极大地提高了开发...

Global site tag (gtag.js) - Google Analytics