基于AJAX和JSF打造丰富的互联网组件之Mabon篇(1)
在上一篇文章中,我们讨论了JSF组件创作者如何利用新的Weblets(http://weblets.dev.java.net)开源工程来提供资源服务―这些资源包括直接来自于JAR中的JavaScript库,图标和CSS文件―而不影响应用程序开发者。
在本文中,我们将使用AJAX和JSF组件实现取回数据。使用AJAX取回数据最普通的情形是填充下拉列表框并且为文本域添加输入探测(type-ahead)功能。与使用AJAX回寄机制操作事件相反,取数据不应该影响页面中的周围的其它组件。并且如果取数据不影响DOM树的另外部分的话,那么你不必仅为取得该数据而遍历完整的JSF生命周期。
本文中将引入一种新的开源工程Mabon(http://mabon.dev.java.net)。Mabon,代表托管Bean对象标志,其目标是,通过使用一种JSON语法通讯通道,使得基于AJAX技术的JSF组件开发者能够从标准JSF生命周期之外来访问JSF托管bean。
实质上,通过使用JSF规范所提供的托管bean工具,Mabon向应用程序开发者提供了一种标准的容易的方式来为基于AJAX技术的JSF组件提供数据。
一、用AJAX技术取数据
常规的取数据方式与使用AJAX技术遵循相同的基本概念,而且不应该影响周围其它组件的状态。
图1展示了一个使用HTTP GET方法的AJAX序列图。W3C推荐你使用HTTP GET方法来取数据;这时不会产生用户请求所带来的其它影响(例如,Google Suggest)。
图1.一个使用HTTP GET方法的XMLHttpRequest的序列图
二、不同的JSF AJAX方法
如果你不想使用其它附加功能,那么不必改变JSF组件层次,因此也不需要经历整个JSF生命周期。但是,如果你想重用一个托管bean方法,那么最容易的方式就是使用JSF MethodBinding工具。为此,存在三种方案:把功能添加到Renderer,使用一个PhaseListener以及提供一种新的JSF生命周期。
三、Renderer方法
Renderer方法把功能添加到屏幕生成器以检测AJAX请求。JSF默认的生命周期首先在“Restore View”阶段恢复组件层次,而在“Apply Request Values”阶段Renderer获得控制。在处理完AJAX请求后,Renderer调用FacesContext的responseComplete()方法来终止处理生命周期的剩下阶段。从表面上来看,这似乎是一种更好的方法,但是它实际上存在一些严重的不足。
首先,这种方法要求有一个组件层次,这可能导致在每个请求中带来其它额外开销,特别是当使用客户端状态保存功能时。仅当这一阶段处理完之后,调用response-Complete()方法才起作用。这个“Apply Request Values”阶段调用视图中所有屏幕生成器上的decode()方法,这有可能导致不期望的超出控制的“副作用”,例如由应用程序开发者把一个
另外,这种方法通常需要使用HTTP POST来把状态字符串发送回服务器端。
四、PhaseListener方法
这个PhaseListener方法添加一个PhaseListener(PhaseId.RESTORE_VIEW)―它“短路”生命周期并且完成在PhaseListener本身中的所有处理工作。此后,它要调用FacesContext的responseComplete()方法。
为使这种方法能够工作,它必须生成一个包含在初始请求中有关使用托管bean信息的引用。PhaseListener在回寄期间使用这个信息以创建一个MethodBinding―然后,它被用于调用托管bean上的一个方法并且把数据返回到客户端。既然没有创建组件层次而且没有屏幕生成器,那么把immediate设置为true的命令组件就不会导致任何副作用。
但是,这种方法存在一个问题:无法防止应用程序开发者在同一阶段依附其它的PhaseListeners,这样可能导致不希望的副作用。而且,你也无法知道这些PhaseListeners将以怎样的顺序执行。
五、生命周期方法
这个生命周期方法添加一个被映射到一个AJAX请求的新的生命周期并且仅包含需要处理请求的生命周期阶段,调用由MethodBinding所定义的应用程序逻辑,并生成响应。这消除了创建和恢复组件树的麻烦,因此不需要屏幕生成器。如果把immediate设置为true,你也不会遇到任何问题。
使用一种定制的生命周期的另一项优点是,由应用程序开发者添加的任何PhaseListener对这种方案都将毫无影响;应用程序开发者甚至能把PhaseListeners添加到这个定制的生命周期。然而,如果使用一个定制PhaseListener把其它托管beans加入到该请求上,那么你可能遇到一些问题,除非它们也为此定制的生命周期进行了注册。
六、选择一种JSF AJAX方法
这里,我们使用生命周期方法―既然它不会带来应用程序逻辑副作用和其它开销。在此,开源工程Mabon能够帮助你集中于你的支持AJAX技术的组件的设计。
让我们解释一下什么是Mabon以及它为对AJAX数据回取感兴趣的组件开发者提供怎样的支持(图2)。
七、什么是Mabon?
Mabon提供了一种方便的方式来“钩住”(hook in)一种特别设计的生命周期―这特别适合于支持AJAX技术的组件―它必须从一个支持bean中直接取数据,而不需要浪费一个完整的JSF生命周期。它还提供了一种Mabon协议(mabon:/)―用于引用支持bean和一个用于发送目标URL和任何需要的参数的JavaScript工具函数,然后异步地从托管bean取回数据。
八、Mabon和JSON
正如你所知,XMLHttpRequest提供了两种响应类型―responseText和responseXML―它们可以用于取回数据。你可能会问:我何时该使用哪一个?对这个问题的回答要依赖于是否你想自己控制响应的语法。
responseXML类型返回一个完整的DOM对象(它为你提供很多种方式来遍历DOM树),这可以让你查找你所需要的信息并且把变化应用到当前文档中。当你的组件将响应周围的元素并且你不想控制响应时(例如,当你与一个Web服务进行通讯时),这是非常有用的。
九、MabonLifecycle类
MabonLifecycle由三部分组成:
ApplyRequestValuesPhase,InvokeApplicationPhase和RenderResponsePhase。MabonLifecycle负责执行这三个阶段,它还负责处理任何依附到该MabonLifecycle上的PhaseListeners。







