⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 infoq 用jsf-dwr-dojo创建动态web应用.htm

📁 几个运用了DWR框架编写的AJAX代码,
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<P>DWR Java类(DWR 
Java类就是普通Java类。这些类不用实现任何DWR特定接口或类。)每当收到一个AJAX请求时被实例化。这意味着如果应用程序必须在AjaxBean类中维护状态,那么当新请求来临时它就被抹掉了。AjaxBean中的方法本质上被预期是无状态的,会话状态必须维护在其他地方。</P>
<P>AJAX请求不是一个PortletRequest,这意味着DWR 
Java类不用访问PortletSession对象。AJAX请求是简单的HTTP请求,因此,DWR 
Java类可以访问HttpSession对象。按照Portal规范,要求HttpSession和PortletSession对象应该同步,也就是说,如果一个属性被增加进PortletSession对象那么它也应被增加进HttpSession对象(不必用相同的名字)。</P>
<P>以JBoss 
AS为例,当一个管理bean被命名为someManagedBean增加进PortalSession,那么可以通过HttpSession用属性名<STRONG>javax.portlet.p.&lt;portletInstanceName&gt;?someManagedBean</STRONG>获得相同对象。</P>
<P>在本例子应用中,会话状态被维护在someManagedBean中。DWR 
Java类从HttpSession对象中获得someManagedBean实例并设置其属性以反映用户当前会话状态。</P>
<P>为了访问业务服务(比如说在Spring层),AjaxBean可以使用Service Locator模式与业务服务交互。</P>
<P><STRONG>注意</STRONG>: JSF管理bean只有在接收到一个face 
request后才被实例化。因此确认你要用来存储会话状态的JSF管理bean已经收到了一个face 
request。该管理bean的作用范围应该是‘session’。</P>
<H3>HTML模板</H3>
<P>使用AJAX工作面临的一个问题是,基于用户动作创建复杂的HTML片段。这通常导致应用的维护成本高昂,经过一段时间,当应用需求精确了,修改用户界面有时甚至也是很困难的。HTML没有tile的概念,但是在本文例子应用了可以做一些类似tile的事情。</P><PRE>&lt;table style="height: 80%; width: 100%; padding-bottom: 100px; visibility: {0};"&gt;<BR>     &lt;tr valign="top"&gt;<BR>         &lt;td&gt;<BR>             &lt;table align="left" valign="top"&gt;<BR>                   &lt;tr&gt;<BR> 	       &lt;td class="formLabel"&gt;Product Category:&lt;/td&gt;<BR> 	       &lt;td class="formField"&gt;{1}&lt;/td&gt;<BR> 	  &lt;/tr&gt;<BR> 	  &lt;tr&gt;<BR> 	        &lt;td class="formLabel"&gt;&lt;span class="required"&gt;*&lt;/span&gt;Description:&lt;/td&gt;<BR> 	        &lt;td class="formField"&gt;&lt;textarea rows="2" id="desc_field" cols="80" <BR>                                  name="desc_field"&gt;&lt;/textarea&gt;&lt;/td&gt;<BR> 	   &lt;/tr&gt;<BR> 	&lt;table&gt;<BR> 	  &lt;tr&gt;<BR> 	        &lt;td&gt;{dataTable}&lt;/td&gt;<BR> 	   &lt;/tr&gt;<BR> 	   &lt;tr&gt;<BR> 	        &lt;td&gt;{dataScroller}&lt;/td&gt;<BR> 	   &lt;/tr&gt;<BR> 	&lt;/table&gt;<BR> 	   &lt;tr valign="bottom"&gt;<BR> 	       &lt;td align="right" style="padding-right: 50px;"&gt;<BR> 	          &lt;table&gt;<BR> 	 	&lt;tr&gt;<BR>     &lt;td&gt;&lt;input type="button" class="inputButton" onclick="saveDetails('{2}');" value="Save"/&gt;&lt;/td&gt;<BR> 		&lt;/tr&gt;<BR> 	           &lt;/table&gt;<BR> 	      &lt;/td&gt;<BR> 	&lt;/tr&gt;<BR> ...<BR> ...</PRE>
<P>上面HTML模板文件显示了两类占位符:</P>
<OL>
  <LI>数据占位符(Data placeholders) 
  <LI>HTML占位符 </LI></OL>
<P>占位符 {0}、{1} 和 {2} 代表数据占位符,很容易由如下静态方法填充:</P><PRE><STRONG>public static</STRONG> String getStringWithValues(String template, Object[] values) <STRONG>throws</STRONG> IncorrectNumberOfValues {<BR>  	<STRONG>for</STRONG>(<STRONG>int</STRONG> i = 0; i &lt; values.length; i++) {<BR> 	     <EM>int</EM> index = template.indexOf("{" + i + "}");<BR> 	     <EM>if</EM>(index == -1) {<BR> <STRONG>throw new</STRONG> IncorrectNumberOfValues("The number of values passed is : " + values.length + "<BR> which doens't match the number of placeholders in : " + template);<BR> 	      } <STRONG>else</STRONG> {<BR> 	            <STRONG>if</STRONG>(values[i] != <STRONG>null</STRONG>) {<BR> 	                 template = StringUtils.replace(template, "{" + i + "}", values[i].toString());<BR> 	             } <STRONG>else</STRONG> {<BR> 	                 template = StringUtils.replace(template, "{" + i + "}", "");<BR> 	             }<BR>                        }<BR> 	   }<BR>           <STRONG>return</STRONG> template;<BR> }</PRE>
<P>这里, 
<STRONG>模板</STRONG>是需要被解析并用值数组中的值替换占位符的html模板。因此,数据占位符{0}被值数组中的第一个元素替换,数据占位符{1}被值数组中的第二个元素替换,以此类推。</P>
<P>占位符 {dataTable} 和 {dataScroller}代表HTML占位符,要求被一个HTML片段替换。{dataTable} 
占位符应该被数据表格所替换,该数据表格显示对应于所属某产品分类的每一个产品记录。对应于 {dataTable} 
的HTML是另一个HTML模板。有两种将HTML占位符替换为相应HTLM模板的方法:</P>
<OL>
  <LI>编程:在ajax bean内部,占位符可以被HTML替换。这种方法不需要创建任何类型的框架。 
  <LI>在properties文件或XML文档中创建占位符和HTML模板之间的映射。例如,一个properties文件可能被创建包含如下映射: 
  {dataTable} = /WEB-INF/classes/templates/dataTableTemplate.html {dataScroller} 
  = /WEB-INF/classes/templates/dataScroller.html </LI></OL>
<P>运行时这些占位符被相应模板替换。该方法要求创建一个小框架,从properties文件读取信息并解析HTML模板以使相应的HTML文件替换HTML占位符。</P>
<H3>DWR <STRONG>bean</STRONG> 转换器</H3>
<P>Web应用通常使用DTO从Web层往服务层传递信息。本文例子应用使用另一级别的DTO,从Javascript往Web层传递信息。例如,当搜索产品时,用户可以输入如下信息:产品名称,产品编码、产品id已经相应的搜索类型(LIKE 
或 EQUALS)。利用DTO,这些参数被传递到例子应用的Web层。Javascript中的关联数组(associative array —— 
也称为命名数组)的概念被用来设置这些参数,接着DWR把这些关联数组转换到相应的DTO。关联数组中的名称必须与DTO中的属性名字匹配。</P>
<P>下面dwr.xml的配置信息展示了如何配置一个DTO:</P><PRE>&lt;convert match="com.search.product.SearchCriteria" converter="bean"/&gt;</PRE>
<P>使用这种方法使服务器端Java代码更整洁,因为你不必再显式地获取来自AJAX请求的每个请求参数值。</P>
<H3>JSF的<STRONG>rendered</STRONG>属性</H3>
<P>所有JSF 
HTML标签都有一个rendered属性,该布尔值决定了HTML窗口部件是否将显示给用户。当使用HTML模板时,可以达成同样的功能。这将要求创建一个表达式框架来处理在HTML中的表达式并显示/隐藏一个HTML片段。</P><PRE>&lt;exp:if value="someManagedBean.permissions.save"&gt;<BR>       &lt;td&gt;&lt;input type="button" class="inputButton" onclick="removeProduct('{0}');" value="Remove" /&gt;&lt;/td&gt;<BR> &lt;/exp:if&gt;</PRE>
<H3>用于导航的 FacesRequest 或 HttpServletRequest</H3>
<P>当用户点击产品详细信息页面上的back按钮时,产品搜索页面需要被显示。如果点击back按钮使用AJAX来处理,那么应用程序没有利用到定义在faces-config.xml文件中的导航规则。因此,在产品详细信息页面上使用JSF的HTML按钮组件,而不是使用发起HttpServletRequest(或AJAX请求)给服务器用以导航至另一个页面的HTML按钮,是一个不错的主意。</P>
<H2>值得考虑的备选方案</H2>
<H3>Ajax4jsf </H3>
<P>Ajax4jsf 
为JSF组件提供了使用AJAX的方法,但是对Portlet支持在1.1.1版中提供。在创建例子应用的时候ajax4jsf还不支持Portlet。</P>
<H3>基于HTML和CSS的树</H3>
<P>联合使用 &lt;li&gt; 
HTML元素和CSS创建一个树形结构是可行的。但是这种树结构缺乏任何类型的事件处理模型,因此不适合高交互性的树窗口部件的要求。</P>
<H3>RichFaces</H3>
<P>RichFaces提供了带有AJAX功能的、丰富的JSF组件。RichFaces利用Ajax4jsf完成其AJAX功能。</P>
<H2>关于作者</H2>
<P>Ashish Sarin在开发/设计基于Java的Web应用程序方面已经有8年的经验。</P>
<H2>参考文献</H2>
<P><STRONG>Dojo</STRONG><BR>Dojo是一个用Javascript写的开源DHTML工具包。更多信息请参考<A 
href="http://www.dojotoolkit.org/about">http://www.dojotoolkit.org/about</A>。</P>
<P><STRONG>DWR</STRONG><BR>DWR —— Direct Web Reporting 
使得在Java应用中使用Ajax更容易。更多信息请参考<A 
href="http://getahead.org/dwr/documentation">http://getahead.org/dwr/documentation</A>。</P>
<P><STRONG>RichFaces</STRONG><BR><A 
href="http://labs.jboss.com/jbossrichfaces/">http://labs.jboss.com/jbossrichfaces/</A>.</P>
<P><STRONG>Ajax4jsf</STRONG><BR><A 
href="http://labs.jboss.com/jbossajax4jsf/">http://labs.jboss.com/jbossajax4jsf/</A>.</P>
<P><STRONG>Facelets</STRONG><BR><A 
href="http://labs.jboss.com/jbossajax4jsf/">http://labs.jboss.com/jbossajax4jsf/</A>.</P>
<P><STRONG>查看英文原文:</STRONG><A 
href="http://www.infoq.com/articles/jsf-dojo-dwr">Creating dynamic web 
applications with JSF/DWR/DOJO</A> </P>
<DIV style="MARGIN-TOP: 15px; DISPLAY: block">
<DIV style="DISPLAY: inline; MARGIN-RIGHT: 0px" align=right>
<DL class=tags3>
  <DT>加入书签 
  <DD><A 
  onclick="this.href='http://www.xianguo.com/api/submitdigg/?link' + escape(window.location) + '&amp;feed=' + escape('http://www.infoq.com/cn/rss/rss.action?token=qtUIjhH7J3J93oYWNBn4ENaWb7M7gUQ6')" 
  href="http://www.infoq.com/cn/articles/" target=_blank rel=nofollow>鲜果+</A>, 
  <DD><A 
  onclick="this.href='http://digg.com/submit?phase=2&amp;url=' + escape(window.location)" 
  href="http://www.infoq.com/cn/articles/" target=_blank rel=nofollow>digg+</A>, 

  <DD><A 
  onclick="this.href='http://reddit.com/submit?url=' + escape(window.location) + '&amp;title=' + escape('用JSF/DWR/DOJO创建动态Web应用')" 
  href="http://www.infoq.com/cn/articles/" target=_blank 
  rel=nofollow>reddit+</A>, 
  <DD><A 
  onclick="this.href='http://del.icio.us/post?url=' + escape(window.location) + '&amp;title=' + escape('用JSF/DWR/DOJO创建动态Web应用')" 
  href="http://www.infoq.com/cn/articles/" target=_blank 
  rel=nofollow>del.icio.us+</A>, 
  <DD><A 
  onclick="this.href='http://www.dzone.com/links/add.html?url=' + escape(window.location) + '&amp;title=' + escape('用JSF/DWR/DOJO创建动态Web应用')" 
  href="http://www.infoq.com/cn/articles/" target=_blank rel=nofollow>dzone+</A> 
  </DD></DL></DIV></DIV>
<SCRIPT type=text/javascript>
var replyEnabled=true;
var forumID=1;
var threadID=3789;
var previewText='预览';
var pleaseWait='请稍候……';	
var reply='回复';
var postMessage='发送消息';	
var errorSubject='请输入主题。';	
var errorBody='您不允许发表无内容的消息。请输入您的消息并重试。';
var cancel='取消';
var goBackOrEdit='返回/编辑';
var re='Re:';
var lastMessage=0;
var stopWatchText='取消对此讨论的关注';
var startWatchText='关注此讨论';
var descending='false';
var ctxPath= '';
var postAddress= ctxPath + '/forum/post!post.action?language=' + 'zh';
var postAddWatches= ctxPath + '/forum/watches!add.action';
var postRemoveWatches= ctxPath + '/forum/watches!remove.action';
var loggedIn=false;	
</SCRIPT>

<SCRIPT src="InfoQ%20用JSF-DWR-DOJO创建动态Web应用_files/forum.js" 
type=text/javascript></SCRIPT>

<DIV class=comments-header>
<H3><SPAN id=comments-number>1</SPAN> 条回复</H3>
<P><A class=comment-reply 
onclick="javascript:loggedIn?replyFromTooltip(12669,true):showLoginWindow(this,ALIGN_RIGHT,new Function('replyFromTooltip(12669,true)'));" 
href="javascript:void(0)">回复</A> </P></DIV><SPAN id=newMessage 
style="DISPLAY: none"></SPAN><SPAN id=replyTree_12669></SPAN><SPAN 
id=replyMessage_12669></SPAN>
<DIV class=forum-list-tree 
style="LEFT: 0px; MARGIN-RIGHT: 0px; POSITION: relative"><A 
class=forum-list><SPAN id=tooltip_13634 style="CURSOR: hand">老套的模式</SPAN> 
</A>发表人 fan fan 发表于 2007年11月12日 下午5时16分
<SCRIPT language=javascript type=text/javascript>
		    	Event.observe('tooltip_13634', 'mouseover', initializeTooltip);
		    	Event.observe('tooltip_13634', 'mouseout', deintializeTooltip);	    	
		  	</SCRIPT>
 </DIV><SPAN id=replyTree_13634></SPAN><SPAN id=replyMessage_13634></SPAN>
<DIV class=comments-sort><SPAN id=comments-sort style="DISPLAY: none"><A 
class=comment-sort-desc href="javascript:changeOrder(2);">按日期倒序排列</A> 
</SPAN></DIV>
<OL class=comments>
  <LI id=comment-13634><A name=view_13634></A>
  <DIV class=comment-header>
  <P class=comment-top><A 
  href="http://www.infoq.com/cn/articles/jsf-dojo-dwr;jsessionid=24078313C21B1223C70FE81772483E76#">返回顶部</A></P>
  <DIV id=header_13634>
  <H4><A onclick="javascript:hideTooltip();return true;" 
  href="http://www.infoq.com/cn/articles/jsf-dojo-dwr;jsessionid=24078313C21B1223C70FE81772483E76#view_13634" 
  name=13634>老套的模式</A></H4>
  <P class=comment-author>2007年11月12日 下午5时16分 发表人 <STRONG>fan fan 
  </STRONG></P></DIV></DIV>
  <DIV id=body_13634>
  <P><SPAN id=quote_13634>a+b+c=a+b+c </SPAN></P></DIV>
  <P class=comment-footer><A class=comment-reply 
  onclick="javascript:loggedIn?replyFromFlat(13634):showLoginWindow(this,ALIGN_RIGHT,new Function('replyFromFlat(13634);'));" 
  href="javascript:void(0)">回复</A></P><SPAN id=replyFlat_13634></SPAN><SPAN 
  id=replyFlatMessage_13634></SPAN><SPAN id=lastMessages></SPAN><SPAN 
  id=replyFlatMessage_12669></SPAN></LI></OL>
<DIV class=box-bottom></DIV></DIV></DIV>
<DIV class=bottom-corners>
<DIV></DIV></DIV></DIV></DIV></DIV></DIV><!-- right side start -->
<DIV id=rightbar>
<DIV id=right-wrapper><!-- box start -->
<DIV class=box>
<H2>独家内容</H2>
<UL class=menu id=tabsmenu>
  <LI class=m-ALL_EXCEPT_NEWS-on id=tab_ALL_EXCEPT_NEWS><A 
  onclick="ContentSummary.switchTab('ALL_EXCEPT_NEWS');return false;" 
  href="http://www.infoq.com/cn/articles/jsf-dojo-dwr;jsessionid=24078313C21B1223C70FE81772483E76#">全部</A> 
  </LI>
  <LI class=m-ARTICLE-off id=tab_ARTICLE><A 
  onclick="ContentSummary.switchTab('ARTICLE');return false;" 
  href="http://www.infoq.com/cn/articles/jsf-dojo-dwr;jsessionid=24078313C21B1223C70FE81772483E76#">文章</A> 
  </LI>
  <LI class=m-PRESENTATION-off id=tab_PRESENTATION><A 
  onclick="JSResource.presentationsTab();return false;" 
  href="http://www.infoq.com/cn/articles/jsf-dojo-dwr;jsessionid=24078313C21B1223C70FE81772483E76#">技术演讲</A> 
  </LI>
  <LI class=m-INTERVIEW-off id=tab_INTERVIEW><A 
  onclick="JSResource.interviewsTab();return false;" 
  href="http://www.infoq.com/cn/articles/jsf-dojo-dwr;jsessionid=24078313C21B1223C70FE81772483E76#">技术访谈</A> 
  </LI>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -