楼主: keaide

基于AJAX和JSF打造丰富的因特网组件

[复制链接]
论坛徽章:
456
ITPUB年度最佳版主
日期:2011-12-28 15:24:18马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14ITPUB年度最佳版主
日期:2014-02-19 10:05:27优秀写手
日期:2013-12-18 09:29:09ITPUB社区千里马徽章
日期:2013-06-09 10:15:34ITPUB年度最佳版主
日期:2013-01-30 17:30:25版主9段
日期:2012-07-03 02:21:03
21#
 楼主| 发表于 2006-8-1 21:33 | 只看该作者
图1展示了一个使用HTTP GET方法的AJAX序列图。W3C推荐你使用HTTP GET方法来取数据;这时不会产生用户请求所带来的其它影响(例如,Google Suggest)。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

使用道具 举报

回复
论坛徽章:
456
ITPUB年度最佳版主
日期:2011-12-28 15:24:18马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14ITPUB年度最佳版主
日期:2014-02-19 10:05:27优秀写手
日期:2013-12-18 09:29:09ITPUB社区千里马徽章
日期:2013-06-09 10:15:34ITPUB年度最佳版主
日期:2013-01-30 17:30:25版主9段
日期:2012-07-03 02:21:03
22#
 楼主| 发表于 2006-8-1 21:33 | 只看该作者
二、不同的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()方法,这有可能导致不期望的超出控制的“副作用”,例如由应用程序开发者把一个<h:commandButton>设置为immediate="true"。这将导致在“Apply Request Values”阶段完成之前调用应用程序逻辑。

另外,这种方法通常需要使用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加入到该请求上,那么你可能遇到一些问题,除非它们也为此定制的生命周期进行了注册。

使用道具 举报

回复
论坛徽章:
456
ITPUB年度最佳版主
日期:2011-12-28 15:24:18马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14ITPUB年度最佳版主
日期:2014-02-19 10:05:27优秀写手
日期:2013-12-18 09:29:09ITPUB社区千里马徽章
日期:2013-06-09 10:15:34ITPUB年度最佳版主
日期:2013-01-30 17:30:25版主9段
日期:2012-07-03 02:21:03
23#
 楼主| 发表于 2006-8-1 21:34 | 只看该作者
六、选择一种JSF AJAX方法

这里,我们使用生命周期方法—既然它不会带来应用程序逻辑副作用和其它开销。在此,开源工程Mabon能够帮助你集中于你的支持AJAX技术的组件的设计。

让我们解释一下什么是Mabon以及它为对AJAX数据回取感兴趣的组件开发者提供怎样的支持(图2)。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

使用道具 举报

回复
论坛徽章:
456
ITPUB年度最佳版主
日期:2011-12-28 15:24:18马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14ITPUB年度最佳版主
日期:2014-02-19 10:05:27优秀写手
日期:2013-12-18 09:29:09ITPUB社区千里马徽章
日期:2013-06-09 10:15:34ITPUB年度最佳版主
日期:2013-01-30 17:30:25版主9段
日期:2012-07-03 02:21:03
24#
 楼主| 发表于 2006-8-1 21:34 | 只看该作者
七、什么是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。

使用道具 举报

回复
论坛徽章:
456
ITPUB年度最佳版主
日期:2011-12-28 15:24:18马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14ITPUB年度最佳版主
日期:2014-02-19 10:05:27优秀写手
日期:2013-12-18 09:29:09ITPUB社区千里马徽章
日期:2013-06-09 10:15:34ITPUB年度最佳版主
日期:2013-01-30 17:30:25版主9段
日期:2012-07-03 02:21:03
25#
 楼主| 发表于 2006-8-1 21:34 | 只看该作者
十、LifecyclePhase类

Mabon LifecyclePhase是所有生命周期阶段的基类。

•ApplyRequestValuesPhase,InvokeApplicationPhase和RenderResponsePhase类—既然你仅想取回数据而不想以任何方式修改组件层次或底层模型,那么你不需要包括Restore View,Process Validations和Update Model阶段。Mabon阶段执行类似于缺省的生命周期的操作,例如解码一个输入的请求,调用应用程序逻辑,并且生成响应。

•FacesLifecycleServlet类—这是一个可重用的servlet,它将初始化FacesContextFactory并且在它的第一次请求期间查找MabonLifecycle。它将创建FacesContext,然后调用作为MabonLifecycle的一部分的三个生命周期阶段。由Web应用程序所定义的Servlet映射将把Mabon请求直接转发到这个FacesLifecycleServlet。

•LifecycleFactoryImpl类—这个类的唯一目的是添加第二个生命周期—MabonLifecycle。

•MabonViewHandler类—在初始生成期间,一个定制的屏幕生成器必须提供一个到支持bean的路径—该bean可能被FacesLifecycleServlet拦截和使用,在InvokeApplicationPhase调用这个参考支持bean期间。通过使用Mabon协议,组件创作者可以从能够被生成到客户端的MabonViewHandler中得到一个唯一的路径。如果组件创作者使用ViewHandler.getResourceURL()方法的路径参数传递字符串(显示于代码示例1中),那么MabonViewHandler将返回显示于代码示例2中的可以被写向客户端的字符串。

代码示例1:Mabon协议:

mabon:/managedBean.getValidDates  

代码示例2:Mabon评估Mabon协议后返回的字符串:

/<context-root>/<mabon-servlet-mapping>/managedBean.getValidDates

在一个AJAX请求期间,这个URL根据请求发送并且被FacesLifecycleServlet所拦截。

使用道具 举报

回复
论坛徽章:
456
ITPUB年度最佳版主
日期:2011-12-28 15:24:18马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14ITPUB年度最佳版主
日期:2014-02-19 10:05:27优秀写手
日期:2013-12-18 09:29:09ITPUB社区千里马徽章
日期:2013-06-09 10:15:34ITPUB年度最佳版主
日期:2013-01-30 17:30:25版主9段
日期:2012-07-03 02:21:03
26#
 楼主| 发表于 2006-8-1 21:35 | 只看该作者
十一、Mabon:初始化请求

Mabon实现是特别为AJAX请求设计的并且使用JSON语法实现一种通讯通道。这种方案让使用托管bean的AJAX组件取数据并且与服务器进行通讯而不必经历一个完整的JSF生命周期。那么,它是如何工作的呢?在应用程序启动时,Mabon将把MabonLifecycle作为JSF LifecycleFactory上下文的一部分添加。

在起始请求时,Mabon仅被代理到基本的JSF实现,并且,如果需要的话,仅在生成器响应阶段是活动的。

在图3的序列图中,一个包含一个定制的AJAX组件的页面被执行。为了能够工作,这个AJAX组件必须从一个底层支持bean中获取数据。在encodeBegin()期间,该组件的AJAX生成器将使用Mabon协议(mabon:/)输出(写)引用该支持bean的一个目标URL。为了得到这个URL,生成器将调用ViewHandler上的getResourceURL()方法。它将传递一个匹配该方法(它负责为支持bean(例如,mabon:/managedBean.getSuggestions)绑定表达式)的字符串。在MabonViewHandler中的这个getResourceURL()方法将返回一个完整的路径:

/<context-root>/<mabon-servlet-mapping>/managedBean.getSuggestions—它可以被写到文档中。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

使用道具 举报

回复
论坛徽章:
456
ITPUB年度最佳版主
日期:2011-12-28 15:24:18马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14ITPUB年度最佳版主
日期:2014-02-19 10:05:27优秀写手
日期:2013-12-18 09:29:09ITPUB社区千里马徽章
日期:2013-06-09 10:15:34ITPUB年度最佳版主
日期:2013-01-30 17:30:25版主9段
日期:2012-07-03 02:21:03
27#
 楼主| 发表于 2006-8-1 21:35 | 只看该作者
十二、Mabon:数据取请求

在页面被生成到客户端后,它包含一个目标URL—指向AJAX组件取回数据所需要的支持bean(例如,/<context-root>/<mabon mapping>/managedBean.getValidDates)。在后面的AJAX请求中,这个字符串将被Mabon实现所拦截并且用于调用支持bean并且把结果返回到客户端(图4)。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

使用道具 举报

回复
论坛徽章:
456
ITPUB年度最佳版主
日期:2011-12-28 15:24:18马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14ITPUB年度最佳版主
日期:2014-02-19 10:05:27优秀写手
日期:2013-12-18 09:29:09ITPUB社区千里马徽章
日期:2013-06-09 10:15:34ITPUB年度最佳版主
日期:2013-01-30 17:30:25版主9段
日期:2012-07-03 02:21:03
28#
 楼主| 发表于 2006-8-1 21:36 | 只看该作者
一旦提交一个支持AJAX的组件,即创建一个新的XMLHttpRequest对象,它能够与服务器异步通讯以从托管bean中取回数据。这个请求被FacesLifecycleServlet所拦截,这将通过Mabon生命周期而不是默认的JSF生命周期实现路由请求。

当FacesLifecycleServlet拦截该请求时,通过顺序地调用每个Mabon生命周期阶段,开始执行请求处理。首先,你执行ApplyRequestValuesPhase,这将解码该请求并且得到托管bean参考和该请求的托管bean需要的方法参数。其次,你执行InvokeApplicationPhase—它将基于托管bean参考创建一个MethodBinding,并调用这个MethodBinding以传递任何参数,并且返回结果。第三,Render-ResponsePhase使用这个结果并把它写回到客户端。

十三、Mabon API

接下来的部分,我们将讨论一些可用的API以及如何在一个应用程序中进行Mabon注册。

使用道具 举报

回复
论坛徽章:
456
ITPUB年度最佳版主
日期:2011-12-28 15:24:18马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14ITPUB年度最佳版主
日期:2014-02-19 10:05:27优秀写手
日期:2013-12-18 09:29:09ITPUB社区千里马徽章
日期:2013-06-09 10:15:34ITPUB年度最佳版主
日期:2013-01-30 17:30:25版主9段
日期:2012-07-03 02:21:03
29#
 楼主| 发表于 2006-8-1 21:36 | 只看该作者
十四、Mabon Servlet配置

如果你计划把Mabon应用于你的支持AJAX技术的组件中,那么你应该知道使用你的JSF组件库的应用程序开发者还要再加上一步。应用程序开发者需要把显示在下面列表1中的入口添加到Web应用程序配置文件web.xml中。

列表1:Mabon Servlet配置

<servlet><servlet-name>Mabon Servlet</servlet-name><servlet-class>net.java.dev.mabon.webapp.FacesLifecycleServlet</servlet-class><init-param><param-name>javax.faces.LIFECYCLE_ID</param-name><param-value>net.java.dev.mabon</param-value></init-param></servlet>...<servlet-mapping><servlet-name>Mabon Servlet</servlet-name><url-pattern>/mabon/*</url-pattern></servlet-mapping>
列表2:mabon.js库 dojo.provide("net.java.dev.mabon";/*** @param kvparams (map)* {* url:目标URL* args:参数数组* callback:结果callback,签名为(result)* }*/net.java.dev.mabon.send = function (kvparams){var params = new Array();for (var i=0; i < kvparams.args.length; i++){var arg = kvparams.args;if (typeof(arg) == "string" params.push("'" + arg + "'";elseparams.push(arg);}var content = {args:'[' + params.join(',') + ']'};dojo.io.bind({url: kvparams.url ,method: 'get',content: content,mimetype: "text/javascript",load: function(type, data, evt) { kvparams.callback(eval(data)); },error: function(type, data, evt) { alert('Oops! The server returned an error, please try again.'); }});}

servlet类

net.java.dev.mabon.webapp.Faces-LifecycleServlet和初始化参数(例如,net.java.dev.mabon)是Mabon合同的一部分。应用程序开发者可以选择把该映射设置成默认定义一样的URL模式(例如/mabon/*)或重载缺省的URL映射,以防它与Web应用程序使用的资源发生冲突。Mabon自动地消费这个URL映射改变而不用要求任何代码修改。

使用道具 举报

回复
论坛徽章:
456
ITPUB年度最佳版主
日期:2011-12-28 15:24:18马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14ITPUB年度最佳版主
日期:2014-02-19 10:05:27优秀写手
日期:2013-12-18 09:29:09ITPUB社区千里马徽章
日期:2013-06-09 10:15:34ITPUB年度最佳版主
日期:2013-01-30 17:30:25版主9段
日期:2012-07-03 02:21:03
30#
 楼主| 发表于 2006-8-1 21:36 | 只看该作者
十五、Mabon JavaScript API

Mabon工程提供了一种方便的JavaScript库—你可以使用它来把你的请求发送到服务器端。Mabon send()函数利用Dojo toolkit的bind()函数以与服务器异步地通讯。有关于Dojo开发工具包的更多信息,请访问Dojo网站(http://dojotoolkit.org/)。

列表2展示了Mabon JavaScript库的源码。

Mabon send()函数只使用一个参数:一个Map。为了从你的AJAX实现中调用mabon.send()函数,你必须使用JavaScript Map语法来构造Map,详见下面的代码:

mabon.send({ url: targetURL,args: [item1, item2],callback: callback_function });

targetURL是资源URL—它被写向客户端(例如

/context-root/mabon-servlet-mapping/managedBean.methodName)。targetURL将被FacesLifecycleServlet所拦截并且将被Mabon “Apply Request Values”阶段所译解。

十六、Mabon协议

现在,既然你已经知道如何配置Mabon,那么我们开始分析你如何引用需要的托管bean来取数据。类似Mabon协议的语法很容易理解。该语法以mabon:/开始,后面跟着托管bean名字,最后是方法名,参考如下:

ViewHandler.getResourceURL(context, "mabon:/<managed bean name>.<method>";

这里的语法中使用了一个前缀来指示,这是一个Mabon托管的请求,托管bean的名字和需要的方法。这个由Mabon合同所定义的语法(mabon:/<managed bean><method>)用于返回一个引用该托管bean的目标URL。

十七、小结

本文讨论了怎样使用AJAX来取数据并且利用JSF管理的bean工具作为一种数据源,还讨论了不同的XMLHttpRequest响应类型—responseText和responseXML—你可以使用它们来把结果返回到服务器端。我们还向你展示了如何有效地使用eval()函数来分析JSON语法响应。

此外,在本文中,我们还讨论了一种新的开源工程Mabon—它扩展JSF来提供一个定制的生命周期—它远程地调用一个托管的bean方法,然后使用JSON请求把结果传送到客户端。

在本系列的下一篇文章中,我们将分析如何综合前面三篇中的知识来创建一个利用AJAX,Mabon和Weblets技术的组件<jdj:inputSuggest>。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表