📄 infoq 用jsf-dwr-dojo创建动态web应用.htm
字号:
<P><A id=tl-64 onclick="Ads.clickTextLink(this, 64);"
href="http://dev2dev.bea.com.cn/bbs/ext/techdays2008/getpv.jsp?p=Infoq"
target=_blank>Dev2Dev
TechDays</A><BR>最新热点技术培训<BR>与指导,5月特邀<BR>专家与您一起探讨<BR>Java2SOA技术变革<BR><A id=tl-64
onclick="Ads.clickTextLink(this, 64);"
href="http://dev2dev.bea.com.cn/bbs/ext/techdays2008/getpv.jsp?p=Infoq"
target=_blank>即刻开始报名!</A></P>
<P><A id=tl-63 onclick="Ads.clickTextLink(this, 63);"
href="http://www.operamasks.org/" target=_blank>Apusic
OperaMasks</A><BR>拥有独创技术的<BR>Web开发框架直<BR>接提高开发效率<BR>3倍以上,所有源<BR>码全部通过<BR><A
id=tl-63 onclick="Ads.clickTextLink(this, 63);"
href="http://www.operamasks.org/"
target=_blank>OperaMasks.org</A><BR>开放。<BR>……马上体验!</P>
<P><A id=tl-66 onclick="Ads.clickTextLink(this, 66);"
href="http://www.infoq.com/cn/vendorcontent/show.action?vcr=281"
target=_blank>SOA中国技术论坛</A><BR>4月23日·上海<BR>与你一起破解SOA<BR>迷局,共享SOA实<BR>施案例。InfoQ中<BR>文站读者免费获取<BR>价值280元电子票</P>
<P><A id=tl-67 onclick="Ads.clickTextLink(this, 67);"
href="http://msdn2.microsoft.com/zh-cn/bb980628.aspx"
target=_blank>立即加入七彩都市</A><BR>让每个开发人员能<BR>拥有一个自己的程<BR>序单元格……现在<BR>加入即可获得微软<BR>图书7.5折优惠券</P>
<P><A id=tl-55 onclick="Ads.clickTextLink(this, 55);"
href="http://www.primeton.com/job/?referer=infoq&utm_campaign=hroninfoq&utm_source=infoq&utm_medium=infoqleftfont"
target=_blank>普元软件高薪诚聘<BR>[100名]Java人才</A><BR>资深J2EE架构师<BR>高级Java工程师<BR>Java开发工程师<BR>……现在提交简历</P></DIV></DIV>
<DIV class=box-simple-bottom></DIV></DIV>
<DIV class=box-simple>
<DIV class=box-simple-top></DIV>
<DIV class=box-simple-content>
<P class=banner id=bannerparagraph><A class=towerAdLeft id=sk-50
onclick="Ads.clickSkyscraper(this, 50 );"
href="http://dev2dev.bea.com.cn/bbs/ext/techdays2008/getpv.jsp?p=Infoq"
target=_blank><IMG
src="InfoQ%20用JSF-DWR-DOJO创建动态Web应用_files/bea_soa_120-600.gif"></A> </P></DIV>
<DIV class=box-simple-bottom></DIV></DIV>
<DIV class=box-simple>
<DIV class=box-simple-top></DIV>
<DIV class=box-simple-content>
<P class=banner><IMG alt="" src="InfoQ%20用JSF-DWR-DOJO创建动态Web应用_files/logos.jpg"
useMap=#sponsorsmap> <MAP name=sponsorsmap><AREA title=Oracle shape=RECT
target=_blank alt=Oracle coords=0,60,120,120
href="http://www.oracle.com/technology/global/cn/ada/welcome.htm"><AREA
title=Microsoft shape=RECT target=_blank alt=Microsoft coords=0,120,120,190
href="http://msdn2.microsoft.com/zh-cn/default.aspx"></MAP></P></DIV>
<DIV class=box-simple-bottom></DIV></DIV>
<DIV class=sidebar-bottom></DIV></DIV></DIV>
<DIV id=clearer></DIV>
<DIV id=content>
<DIV id=content-wrapper>
<DIV class=box>
<DIV class="contribute contribute-print">
<UL>
<LI class=c-news></LI>
<LI class=c-print><A href="javascript:print()">打印</A> </LI></UL></DIV>
<H2>文章</H2>
<DIV class=top-corners>
<DIV></DIV></DIV>
<DIV class=box-content>
<DIV class=box-content-2>
<DIV class=box-content-5>
<P class=h1-r><IMG alt=""
src="InfoQ%20用JSF-DWR-DOJO创建动态Web应用_files/logo.jpg"></P>
<H1>用JSF/DWR/DOJO创建动态Web应用</H1>
<P class=info>作者 <STRONG>Ashish Sarin</STRONG>译者 <STRONG>宋玮</STRONG> 发布于
2007年11月5日 下午3时48分 </P>
<DL class=tags2>
<DT class=community>社区
<DD><A id=739
onclick="try {CategoryPopup.showPopup(this);} catch(e) {}; return false;"
href="http://www.infoq.com/cn/java" name=java>Java</A>
<DT class=topics>主题
<DD><A id=744
onclick="try {CategoryPopup.showPopup(this);} catch(e) {}; return false;"
href="http://www.infoq.com/cn/webframework" name=webframework>Web框架</A>
<DT class=topics>标签
<DD><A id=1,015
onclick="try {CategoryPopup.showPopup(this);} catch(e) {}; return false;"
href="http://www.infoq.com/cn/dwr" name=dwr>DWR</A>,
<DD><A id=1,120
onclick="try {CategoryPopup.showPopup(this);} catch(e) {}; return false;"
href="http://www.infoq.com/cn/dojo" name=dojo>Dojo</A>,
<DD><A id=1,166
onclick="try {CategoryPopup.showPopup(this);} catch(e) {}; return false;"
href="http://www.infoq.com/cn/JSF" name=JSF>JSF</A> </DD></DL>
<H2>摘要</H2>
<P>本文给出如何将JSF、DWR、DOJO集成在一起来创建丰富Web应用(该应用使用Portlet和Facelet)的方法。假定读者对这些框架和它们所提供的特性已有基本的了解。</P>
<DIV class=vendor-content-box-float>
<H3>相关<SPAN class=vendor>厂商</SPAN>内容</H3>
<P class=entrypdf><A
href="http://www.infoq.com/cn/vendorcontent/show.action?vcr=273">BEA虚拟化技术让你无需再为计算容量而担心
</A></P>
<P class=entrypdf><A
href="http://www.infoq.com/cn/vendorcontent/show.action?vcr=240"
target=_blank>《IDC:SOA中国路线图》技术分析报告下载 </A></P>
<P class=entrydownload><A
href="http://www.infoq.com/cn/vendorcontent/show.action?vcr=271"
target=_blank>Dev2Dev技术日:如何在SOA参考架构中使用Eclipse、Java、Flex和SOA? </A></P></DIV>
<H2>例子应用</H2>
<P>本文中所讨论的例子应用是一个产品管理应用。该应用为期用户提供了如下特性:</P>
<OL>
<LI>用户可以基于名字搜索一个产品类型
<LI>当用户选择了一个产品,将显示一个带有分隔面板(split pane)的新窗口。该分隔面板左侧以树的形式(就像你在Windows
Explorer所看到的那样)显示所有属于该产品类型的产品子类型。可能每个产品子类型还有它自己的子类型。分隔面板右侧显示还有如下标签的标签面板(tabbed
pane):
<UL>
<LI><STRONG>Products(产品)</STRONG> —— 这个标签页显示属于所选子类型的产品列表
<LI><STRONG>Add Product Subtype(增加产品子类型)</STRONG> ——
这个标签页显示一个表单,用来接受给所选产品子类型增加新产品子类输入值
<LI>在分隔面板的底部,有一个back按钮以便回到搜索产品类型页。 </LI></UL>
<LI>当某个子类型关联的产品列表显示在分隔面板右侧时,每一页应该只显示10个产品。这意味着应该能够对屏幕上的结果进行分页和排序。
<LI>显示在分隔面板左侧的树应该可以展开/折叠(expandable/collapsable)而且不应导致页面刷新,这样会增强用户体验。
<LI>鼠标右键点击树上任何一个节点(代表一个产品子类型)应该给用户显示弹出菜单,带有给所选子类增加新产品子类子节点、删除所选产品子类型、用数据库的最新数据刷新所选产品子类的孩子产品子类列表等选项。
<LI>当一个新的产品子类被增加到所选产品子类上后,无需刷新页面,新产品子类应该立刻显示在树上。 </LI></OL>
<P>图1显示了当用户选择一个产品类型/子类型时,屏幕上的期望效果。</P><IMG alt=""
src="InfoQ%20用JSF-DWR-DOJO创建动态Web应用_files/image1.jpg">
<P><SMALL>图 1. 产品子类详细信息窗口 </SMALL></P>
<H2>DOJO</H2>
<P>创建跨浏览器兼容的树结构、标签面板、分隔面板、弹出菜单等等是耗时的工作,同时这些工作最好是由有经验的Javascript/DHTML程序员来完成。有许多工具包支持这些UI部件并且是跨浏览器兼容的,但是支持丰富事件处理模型的工具包却不多。以下罗列了一些例子应用需要响应以满足用户需求的用户动作:</P>
<TABLE cellSpacing=0 cellPadding=4 width="100%" border=1>
<TBODY>
<TR vAlign=center align=left>
<TD><SMALL><STRONG>用户动作</STRONG></SMALL></TD>
<TD><SMALL><STRONG>应用程序响应</STRONG></SMALL></TD></TR>
<TR vAlign=center align=left>
<TD><SMALL>选择树节点</SMALL></TD>
<TD><SMALL>显示属于该节点的产品子类列表</SMALL></TD></TR>
<TR vAlign=center align=left>
<TD><SMALL>右键点击树节点</SMALL></TD>
<TD><SMALL>显示带有增加孩子产品子类、删除所选产品子类等功能的弹出菜单</SMALL></TD></TR>
<TR vAlign=center align=left>
<TD><SMALL>选择标签面板上的‘<STRONG>增加产品子类型</STRONG>’标签</SMALL></TD>
<TD><SMALL>显示输入新产品子类型信息的表单</SMALL></TD></TR>
<TR vAlign=center align=left>
<TD><SMALL>当用户点击[+]号展开树并察看子节点时</SMALL></TD>
<TD><SMALL>从数据库中装载孩子节点信息并显示在树上</SMALL></TD></TR></TBODY></TABLE>
<P>DOJO工具包是一个Javascript/DHTML工具包,它提供了一套丰富UI部件(包括但不止限于树、标签面板、弹出菜单),该套UI部件带有一个非常适合用于本例子应用的丰富事件处理模型。</P>
<H2>DWR</H2>
<P>DWR ( Direct Web Remoting )
是一个简化构建用Java编写的AJAX应用的AJAX框架。DWR提供了许多特性,包括(但不只限于此):</P>
<UL>
<LI>由Java类(开发者创建用来处理AJAX请求)创建Javascript
<LI>允许JSF管理bean作为处理AJAX请求的Java类
<LI>用转换器(converter)对Javascript关联数组(associative array)和Java bean进行双向转换
<LI>用转换器对Javascript数组和Java集合进行双向转换 </LI></UL>
<P>转换器在DWR中扮演一个十分重要的角色,并提供了一个更整洁的编程模型。例如,如果用户输入新产品子类信息,并需要应用程序保存它,那么在Web层有两种方法获得其信息:</P>
<UL>
<LI>用 HttpServletRequest 的 getParameter 方法获得所有关于新产品子类的信息。
<LI>创建一个DTO(数据传输对象)
ProductSubtype,其所有产品子类属性都有getter和setter。在dwr.xml文件中配置一个转换器将ProductSubtype指定为一个<STRONG>bean</STRONG>转换器。在Javascript中,简单地创建一个关联数组(associative
array)并把它传递给Java类(由它来处理AJAX请求)中以ProductSubtype作为参数的方法。在本例中DWR将做由Javascript关联数组到ProductSubtype的转换,因为ProductSubtype在DWR中被声明用于<STRONG>bean</STRONG>
转换器。 </LI></UL>
<P>后一种选择提供了一个更整洁的编程模型,你不必处理获取请求参数及创建一个在Java程序中被使用的DTO。</P>
<P>当AJAX请求被处理时,大多数时候需要在Javascript回调方法中接收状态编码、消息或一些的数据,以决定给用户显示什么、不显示什么。Bean转换器在这种情景下非常方便。</P>
<P>DOJO的丰富事件模型结合DWR处理Java应用AJAX请求的整洁方法,提供了创建高交互性Web应用(类似于例子应用)的一种途径,应用中由DOJO组件产生的事件被传递给DWR去处理。</P>
<H2>问题描述</H2>
<OL>
<LI>在一个Portal环境中,开发者不负责为用户界面产生HTML,界面通过解析符合Facelet的XHTML文件来产生。即使JSF管理bean的属性包含HTML字符串作为其值,它并不是由Portal解析的,而是照原样在用户界面上显示给用户。如何产生可以被Web浏览器执行以创建UI部件的DOJO特定HTML呢?
<LI>DOJO提供了丰富事件模型,而且可以在Javascript中截获这些事件。DWR框架可以用来在服务器端接收这些事件,但是服务器端会话状态需要维护在什么地方?
<LI>当树上的节点超过几百个时,在IE或Mozilla中Javascript创建DOJO树节点需要花些时间。因此是否这意味着如果节点超过几百个,应用不能在浏览器使用DOJO的树部件?
<LI>在Web应用中使用AJAX后,当窗口上发生用户事件时如何产生HTML或HTML片断?应该在Java代码中编码产生还是从一个外部文件获取?应用程序能否在AJAX请求的响应中显示复杂用户界面?
<LI>当使用AJAX时,代码可能因使用HttpServletRequest的getParameter("fieldName")方法而变得混乱,难以维护。
</LI></OL>
<H2>解决方案 </H2>
<H3>自定义JSF组件</H3>
<P>自定义JSF组件用来为DOJO的树和分隔容器组件产生所需的HTML。JSF组件所产生的HTML总是由浏览器解析,而不是由Portal作为文本输出。下面是XHTML的部分内容,展示了如何自定义JSF组件用来产生DOJO的树和标签面板窗口部件。</P><PRE><div xmlns="http://www.w3.org/1999/xhtml"<BR> ...<BR> ...<BR> xmlns:dojo="http://dojotoolkit.org/"<BR> xmlns:mytree="http://mytree.com/tree"<BR> xmlns:mytab="http://mypane.com/tabPane"><BR> <ui:composition><BR> <ui:define name="body"><BR> <f:view><BR> <h:form styleClass="form" id="formId"><BR> <div dojoType="SplitContainer" orientation="horizontal" sizerWidth="5" activeSizing="false" style="overflow:<BR> auto; whitespace: nowrap; height: 550px; background: transparent; padding: 5px;" ><BR> <div dojoType="ContentPane" sizeShare="20"<BR> style="overflow: auto; whitespace: nowrap;"><BR> <mytree:treeComponent backingBeanName="treeBackingBean"></mytree:treeComponent><BR> </div><BR> <div dojoType="ContentPane" sizeShare="80" style="overflow: auto; white-space nowrap;"><BR> <mytab:tabPaneComponent/><BR> </div><BR> </div><BR> ...<BR> ...</PRE>
<P>如果树上的节点数很大(超过200),自定义JSF组件不应为多于200的节点产生代码。如果节点数超过了200,在装载页面时IE将花费大量时间去创建这些窗口部件。本文例子应用的自定义JSF组件只创建100个树节点(在根一级上)并在最后显示‘Show
more...’选项。当用户选择了‘Show
More..’选项,则由DWR负责将剩余的节点信息从数据库中取来。该信息接着被传递给Javascript回调方法以便用程序创建TreeNode窗口部件。</P>
<P>MyFaces也提供了能产生DOJO树的组件,但是MyFaces组件一次性创建所有节点,这不是好方法,因为当树上的节点数达到上千时Web应用中的组件将变得无法使用。</P>
<H3>DWR 和 JSF </H3>
<P>DWR要求你创建Java类并将其配置到dwr.xml配置文件中。DWR创建一个Javascritp文件(文件扩展名为.js),该文件的名字是在dwr.xml中配置的</P>
<P>如下dwr.xml配置信息展示了Java类是如何被配置的:</P><PRE><create creator="jsf" javascript="AjaxBean" scope="request"><BR> <param name="managedBeanName" value="ajaxBean" /><BR> <param name="class"<BR> value="com.somebean.AjaxBean" /><BR> </create></PRE><BR><PRE>creator="jsf"</PRE>
<P>这一句说明Java类被配置为JSF管理bean。该Java类包含所有将由Javascritp调用的AJAX方法。</P><PRE><param name="managedBeanName" value="ajaxBean" /></PRE>
<P>这一句说明在faces-config.xml配置文件中管理bean的名字为ajaxBean。</P><PRE><param name="class"<BR> value="com. somebean.AjaxBean" /> </PRE>
<P>这一句说明所引用的实际Java类。</P><PRE>javascript="AjaxBean"</PRE>
<P>这一句说明在Javascript代码中以此名称使用Java类。</P>
<P>为了在Javascript中使用AjaxBean,需要用 <script> 标签引入该Javascript。</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -