- 浏览: 409284 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
holleyangyanges:
name327 写道LZ说句打击你的话, 首先不说Https的 ...
使用httpclient4登录百度 -
holleyangyanges:
,没有登陆成功啊!
使用httpclient4登录百度 -
shenjichao2009:
...
Spring AOP原理解析 -
wuke0210:
[color=red][/color]
CKEditor3.0在asp.net环境下上传文件的配置,集成CKFinder -
wuke0210:
CKEditor3.0在asp.net环境下上传文件的配置,集成CKFinder
摘要
本文给出如何将JSF、DWR、DOJO集成在一起来创建丰富Web应用(该应用使用Portlet和Facelet)的方法。假定读者对这些框架和它们所提供的特性已有基本的了解。
例子应用
本文中所讨论的例子应用是一个产品管理应用。该应用为期用户提供了如下特性:
- 用户可以基于名字搜索一个产品类型
- 当用户选择了一个产品,将显示一个带有分隔面板(split pane)的新窗口。该分隔面板左侧以树的形式(就像你在Windows Explorer所看到的那样)显示所有属于该产品类型的产品子类型。可能每个产品子类型还有它自己的子类型。分隔面板右侧显示还有如下标签的标签面板(tabbed pane):
- Products(产品) —— 这个标签页显示属于所选子类型的产品列表
- Add Product Subtype(增加产品子类型) —— 这个标签页显示一个表单,用来接受给所选产品子类型增加新产品子类输入值
- 在分隔面板的底部,有一个back按钮以便回到搜索产品类型页。
- 当某个子类型关联的产品列表显示在分隔面板右侧时,每一页应该只显示10个产品。这意味着应该能够对屏幕上的结果进行分页和排序。
- 显示在分隔面板左侧的树应该可以展开/折叠(expandable/collapsable)而且不应导致页面刷新,这样会增强用户体验。
- 鼠标右键点击树上任何一个节点(代表一个产品子类型)应该给用户显示弹出菜单,带有给所选子类增加新产品子类子节点、删除所选产品子类型、用数据库的最新数据刷新所选产品子类的孩子产品子类列表等选项。
- 当一个新的产品子类被增加到所选产品子类上后,无需刷新页面,新产品子类应该立刻显示在树上。
图1显示了当用户选择一个产品类型/子类型时,屏幕上的期望效果。
图 1. 产品子类详细信息窗口
DOJO
创建跨浏览器兼容的树结构、标签面板、分隔面板、弹出菜单等等是耗时的工作,同时这些工作最好是由有经验的Javascript/DHTML程序员来完成。有许多工具包支持这些UI部件并且是跨浏览器兼容的,但是支持丰富事件处理模型的工具包却不多。以下罗列了一些例子应用需要响应以满足用户需求的用户动作:
用户动作 | 应用程序响应 |
选择树节点 | 显示属于该节点的产品子类列表 |
右键点击树节点 | 显示带有增加孩子产品子类、删除所选产品子类等功能的弹出菜单 |
选择标签面板上的‘增加产品子类型 ’标签 | 显示输入新产品子类型信息的表单 |
当用户点击[+]号展开树并察看子节点时 | 从数据库中装载孩子节点信息并显示在树上 |
DOJO工具包是一个Javascript/DHTML工具包,它提供了一套丰富UI部件(包括但不止限于树、标签面板、弹出菜单),该套UI部件带有一个非常适合用于本例子应用的丰富事件处理模型。
DWR
DWR ( Direct Web Remoting ) 是一个简化构建用Java编写的AJAX应用的AJAX框架。DWR提供了许多特性,包括(但不只限于此):
- 由Java类(开发者创建用来处理AJAX请求)创建Javascript
- 允许JSF管理bean作为处理AJAX请求的Java类
- 用转换器(converter)对Javascript关联数组(associative array)和Java bean进行双向转换
- 用转换器对Javascript数组和Java集合进行双向转换
转换器在DWR中扮演一个十分重要的角色,并提供了一个更整洁的编程模型。例如,如果用户输入新产品子类信息,并需要应用程序保存它,那么在Web层有两种方法获得其信息:
- 用 HttpServletRequest 的 getParameter 方法获得所有关于新产品子类的信息。
- 创建一个DTO(数据传输对象) ProductSubtype,其所有产品子类属性都有getter和setter。在dwr.xml文件中配置一个转换器将ProductSubtype指定为一个bean 转换器。在Javascript中,简单地创建一个关联数组(associative array)并把它传递给Java类(由它来处理AJAX请求)中以ProductSubtype作为参数的方法。在本例中DWR将做由Javascript关联数组到ProductSubtype的转换,因为ProductSubtype在DWR中被声明用于bean 转换器。
后一种选择提供了一个更整洁的编程模型,你不必处理获取请求参数及创建一个在Java程序中被使用的DTO。
当AJAX请求被处理时,大多数时候需要在Javascript回调方法中接收状态编码、消息或一些的数据,以决定给用户显示什么、不显示什么。Bean转换器在这种情景下非常方便。
DOJO的丰富事件模型结合DWR处理Java应用AJAX请求的整洁方法,提供了创建高交互性Web应用(类似于例子应用)的一种途径,应用中由DOJO组件产生的事件被传递给DWR去处理。
问题描述
- 在一个Portal环境中,开发者不负责为用户界面产生HTML,界面通过解析符合Facelet的XHTML文件来产生。即使JSF管理bean的属性包含HTML字符串作为其值,它并不是由Portal解析的,而是照原样在用户界面上显示给用户。如何产生可以被Web浏览器执行以创建UI部件的DOJO特定HTML呢?
- DOJO提供了丰富事件模型,而且可以在Javascript中截获这些事件。DWR框架可以用来在服务器端接收这些事件,但是服务器端会话状态需要维护在什么地方?
- 当树上的节点超过几百个时,在IE或Mozilla中Javascript创建DOJO树节点需要花些时间。因此是否这意味着如果节点超过几百个,应用不能在浏览器使用DOJO的树部件?
- 在Web应用中使用AJAX后,当窗口上发生用户事件时如何产生HTML或HTML片断?应该在Java代码中编码产生还是从一个外部文件获取?应用程序能否在AJAX请求的响应中显示复杂用户界面?
- 当使用AJAX时,代码可能因使用HttpServletRequest的getParameter("fieldName")方法而变得混乱,难以维护。
解决方案
自定义JSF组件
自定义JSF组件用来为DOJO的树和分隔容器组件产生所需的HTML。JSF组件所产生的HTML总是由浏览器解析,而不是由Portal作为文本输出。下面是XHTML的部分内容,展示了如何自定义JSF组件用来产生DOJO的树和标签面板窗口部件。
<div xmlns="http://www.w3.org/1999/xhtml" ... ... xmlns:dojo="http://dojotoolkit.org/" xmlns:mytree="http://mytree.com/tree" xmlns:mytab="http://mypane.com/tabPane"> <ui:composition> <ui:define name="body"> <f:view> <h:form styleClass="form" id="formId"> <div dojoType="SplitContainer" orientation="horizontal" sizerWidth="5" activeSizing="false" style="overflow: auto; whitespace: nowrap; height: 550px; background: transparent; padding: 5px;" > <div dojoType="ContentPane" sizeShare="20" style="overflow: auto; whitespace: nowrap;"> <mytree:treeComponent backingBeanName="treeBackingBean"></mytree:treeComponent> </div> <div dojoType="ContentPane" sizeShare="80" style="overflow: auto; white-space nowrap;"> <mytab:tabPaneComponent/> </div> </div> ... ...
如果树上的节点数很大(超过200),自定义JSF组件不应为多于200的节点产生代码。如果节点数超过了200,在装载页面时IE将花费大量时间去创建这些窗口部件。本文例子应用的自定义JSF组件只创建100个树节点(在根一级上)并在最后显示‘Show more...’选项。当用户选择了‘Show More..’选项,则由DWR负责将剩余的节点信息从数据库中取来。该信息接着被传递给Javascript回调方法以便用程序创建TreeNode窗口部件。
MyFaces也提供了能产生DOJO树的组件,但是MyFaces组件一次性创建所有节点,这不是好方法,因为当树上的节点数达到上千时Web应用中的组件将变得无法使用。
DWR 和 JSF
DWR要求你创建Java类并将其配置到dwr.xml配置文件中。DWR创建一个Javascritp文件(文件扩展名为.js),该文件的名字是在dwr.xml中配置的
如下dwr.xml配置信息展示了Java类是如何被配置的:
<create creator="jsf" javascript="AjaxBean" scope="request"> <param name="managedBeanName" value="ajaxBean" /> <param name="class" value="com.somebean.AjaxBean" /> </create>
creator="jsf"
这一句说明Java类被配置为JSF管理bean。该Java类包含所有将由Javascritp调用的AJAX方法。
<param name="managedBeanName" value="ajaxBean" />
这一句说明在faces-config.xml配置文件中管理bean的名字为ajaxBean。
<param name="class" value="com. somebean.AjaxBean" />
这一句说明所引用的实际Java类。
javascript="AjaxBean"
这一句说明在Javascript代码中以此名称使用Java类。
为了在Javascript中使用AjaxBean,需要用 <script> 标签引入该Javascript。
DWR Java类(DWR Java类就是普通Java类。这些类不用实现任何DWR特定接口或类。)每当收到一个AJAX请求时被实例化。这意味着如果应用程序必须在AjaxBean类中维护状态,那么当新请求来临时它就被抹掉了。AjaxBean中的方法本质上被预期是无状态的,会话状态必须维护在其他地方。
AJAX请求不是一个PortletRequest,这意味着DWR Java类不用访问PortletSession对象。AJAX请求是简单的HTTP请求,因此,DWR Java类可以访问HttpSession对象。按照Portal规范,要求HttpSession和PortletSession对象应该同步,也就是说,如果一个属性被增加进PortletSession对象那么它也应被增加进HttpSession对象(不必用相同的名字)。
以JBoss AS为例,当一个管理bean被命名为someManagedBean增加进PortalSession,那么可以通过HttpSession用属性名javax.portlet.p.<portletInstanceName>?someManagedBean 获得相同对象。
在本例子应用中,会话状态被维护在someManagedBean中。DWR Java类从HttpSession对象中获得someManagedBean实例并设置其属性以反映用户当前会话状态。
为了访问业务服务(比如说在Spring层),AjaxBean可以使用Service Locator模式与业务服务交互。
注意 : JSF管理bean只有在接收到一个face request后才被实例化。因此确认你要用来存储会话状态的JSF管理bean已经收到了一个face request。该管理bean的作用范围应该是‘session’。
HTML模板
使用AJAX工作面临的一个问题是,基于用户动作创建复杂的HTML片段。这通常导致应用的维护成本高昂,经过一段时间,当应用需求精确了,修改用户界面有时甚至也是很困难的。HTML没有tile的概念,但是在本文例子应用了可以做一些类似tile的事情。
<table style="height: 80%; width: 100%; padding-bottom: 100px; visibility: {0};"> <tr valign="top"> <td> <table align="left" valign="top"> <tr> <td class="formLabel">Product Category:</td> <td class="formField">{1}</td> </tr> <tr> <td class="formLabel"><span class="required">*</span>Description:</td> <td class="formField"><textarea rows="2" id="desc_field" cols="80" name="desc_field"></textarea></td> </tr> <table> <tr> <td>{dataTable}</td> </tr> <tr> <td>{dataScroller}</td> </tr> </table> <tr valign="bottom"> <td align="right" style="padding-right: 50px;"> <table> <tr> <td><input type="button" class="inputButton" onclick="saveDetails('{2}');" value="Save"/></td> </tr> </table> </td> </tr> ... ...
上面HTML模板文件显示了两类占位符:
- 数据占位符(Data placeholders)
- HTML占位符
占位符 {0}、{1} 和 {2} 代表数据占位符,很容易由如下静态方法填充:
public static String getStringWithValues(String template, Object[] values) throws IncorrectNumberOfValues { for (int i = 0; i < values.length; i++) { int index = template.indexOf("{" + i + "}"); if (index == -1) { throw new IncorrectNumberOfValues("The number of values passed is : " + values.length + " which doens't match the number of placeholders in : " + template); } else { if (values[i] != null ) { template = StringUtils.replace(template, "{" + i + "}", values[i].toString()); } else { template = StringUtils.replace(template, "{" + i + "}", ""); } } } return template; }
这里, 模板 是需要被解析并用值数组中的值替换占位符的html模板。因此,数据占位符{0}被值数组中的第一个元素替换,数据占位符{1}被值数组中的第二个元素替换,以此类推。
占位符 {dataTable} 和 {dataScroller}代表HTML占位符,要求被一个HTML片段替换。{dataTable} 占位符应该被数据表格所替换,该数据表格显示对应于所属某产品分类的每一个产品记录。对应于 {dataTable} 的HTML是另一个HTML模板。有两种将HTML占位符替换为相应HTLM模板的方法:
- 编程:在ajax bean内部,占位符可以被HTML替换。这种方法不需要创建任何类型的框架。
- 在properties文件或XML文档中创建占位符和HTML模板之间的映射。例如,一个properties文件可能被创建包含如下映射: {dataTable} = /WEB-INF/classes/templates/dataTableTemplate.html {dataScroller} = /WEB-INF/classes/templates/dataScroller.html
运行时这些占位符被相应模板替换。该方法要求创建一个小框架,从properties文件读取信息并解析HTML模板以使相应的HTML文件替换HTML占位符。
DWR bean 转换器
Web应用通常使用DTO从Web层往服务层传递信息。本文例子应用使用另一级别的DTO,从Javascript往Web层传递信息。例如,当搜索产品时,用户可以输入如下信息:产品名称,产品编码、产品id已经相应的搜索类型(LIKE 或 EQUALS)。利用DTO,这些参数被传递到例子应用的Web层。Javascript中的关联数组(associative array —— 也称为命名数组)的概念被用来设置这些参数,接着DWR把这些关联数组转换到相应的DTO。关联数组中的名称必须与DTO中的属性名字匹配。
下面dwr.xml的配置信息展示了如何配置一个DTO:
<convert match="com.search.product.SearchCriteria" converter="bean"/>
使用这种方法使服务器端Java代码更整洁,因为你不必再显式地获取来自AJAX请求的每个请求参数值。
JSF的rendered 属性
所有JSF HTML标签都有一个rendered属性,该布尔值决定了HTML窗口部件是否将显示给用户。当使用HTML模板时,可以达成同样的功能。这将要求创建一个表达式框架来处理在HTML中的表达式并显示/隐藏一个HTML片段。
<exp:if value="someManagedBean.permissions.save"> <td><input type="button" class="inputButton" onclick="removeProduct('{0}');" value="Remove" /></td> </exp:if>
用于导航的 FacesRequest 或 HttpServletRequest
当用户点击产品详细信息页面上的back按钮时,产品搜索页面需要被显示。如果点击back按钮使用AJAX来处理,那么应用程序没有利用到定义在faces-config.xml文件中的导航规则。因此,在产品详细信息页面上使用JSF的HTML按钮组件,而不是使用发起HttpServletRequest(或AJAX请求)给服务器用以导航至另一个页面的HTML按钮,是一个不错的主意。
值得考虑的备选方案
Ajax4jsf
Ajax4jsf 为JSF组件提供了使用AJAX的方法,但是对Portlet支持在1.1.1版中提供。在创建例子应用的时候ajax4jsf还不支持Portlet。
基于HTML和CSS的树
联合使用 <li> HTML元素和CSS创建一个树形结构是可行的。但是这种树结构缺乏任何类型的事件处理模型,因此不适合高交互性的树窗口部件的要求。
RichFaces
RichFaces提供了带有AJAX功能的、丰富的JSF组件。RichFaces利用Ajax4jsf完成其AJAX功能。
关于作者
Ashish Sarin在开发/设计基于Java的Web应用程序方面已经有8年的经验。
参考文献
Dojo
Dojo是一个用Javascript写的开源DHTML工具包。更多信息请参考http://www.dojotoolkit.org/about
。
DWR
DWR —— Direct Web Reporting 使得在Java应用中使用Ajax更容易。更多信息请参考http://getahead.org/dwr/documentation
。
RichFaces
http://labs.jboss.com/jbossrichfaces/
.
Ajax4jsf
http://labs.jboss.com/jbossajax4jsf/
.
Facelets
https://facelets.dev.java.net/
.
查看英文原文: Creating dynamic web applications with JSF/DWR/DOJO
From : http://www.infoq.com/cn/articles/jsf-dojo-dwr
发表评论
-
让Bootstrap轮播插件carousel支持左右滑动手势的三种方法
2016-03-02 20:43 1296因为最近开发的项目涉及到移动设备上的 HTML5 开发,其 ... -
JavaScript获取浏览器类型与版本
2016-02-16 11:02 822从网上找到一段使用JavaScript判断浏览器以及浏览器 ... -
PhotoShop 如何给文字描边
2011-11-17 16:44 1323选中图层,然后在菜单中点击 【图层】->【图层样式】-& ... -
在URL传递特殊符号
2011-06-09 12:43 1778有些符号在URL中是不能直接传递的,如果要在URL中传递这 ... -
jQuery获取Select选择的Text和 Value[转]
2011-04-13 18:08 1998jQuery获取Select选择的Text ... -
如何将form提交到iframe
2011-03-24 18:01 4013一、<iframe name='w1'></ ... -
转:用URL传参带特殊字符,特殊字符丢失
2011-03-04 17:00 21300以前还真没注意过这些特殊字符,只是知道传递的长度有限制,下面也 ... -
Window.ShowModalDialog使用手册
2011-02-27 14:38 1020基本介绍: showModalDialog() ... -
javascript trim方法
2011-02-21 17:56 1130在javascript中的string对象没有trim方法,所 ... -
IE网页打印页面设置符合含义
2011-02-14 15:52 2097在web页面中的打印一直是开发人员比较头疼的问题,如果不是要求 ... -
Jquery 倒计时处理
2010-04-29 17:42 2218朋友需要一个倒计时的处理自动提交, 刚好在学习Jquery, ... -
IIS&&PHP&&Mysql的配置
2009-11-09 09:24 9591:安装完成PHP&&My ... -
雅虎给出的34条网站加速方法
2009-11-09 09:13 920雅虎给出了优化网站加 ... -
开启 IE8 的兼容模式
2009-11-02 16:30 3552<meta http-equiv="X-U ... -
IE8 兼容 IE6
2009-10-28 16:11 1454之前项目使用IE6开发的测试的,最近客户要求使用IE8 因为 ... -
浏览器的生存之道 IE8开发特性面面观
2009-10-26 16:54 1194近些日子,互联 ... -
IE8相比IE7 有24个不同
2009-10-26 12:30 1615CNET科技资讯网5月18日北京报道:今天,微软(中国)有 ... -
JavaScript[对象.属性]集锦
2007-11-27 08:58 1014windows对象 每个HTML文档的顶层对象. 属性 ... -
javascript多==范
2007-11-27 09:02 1351事件源对象event.srcElement.tagNamee ... -
HTML颜色参考
2008-01-15 14:37 1283HTML颜色参考HTML里,颜色有两种表示方式。一种是用颜色名 ...
相关推荐
"InfoQ 用JSF-DWR-DOJO创建动态Web应用.htm"暗示了一篇InfoQ网站上的文章,该文章可能讲解了如何结合DWR、JSF(JavaServer Faces)和DOJO这三种技术构建动态Web应用,展示了它们之间的协同工作原理和优势。...
随着Ajax技术的兴起,JSF也迅速跟进,支持与DWR、Dojo、JQuery、RichFaces、MyFaces等框架的集成。这不仅提升了用户体验,还极大地增强了Web应用的实时性和交互性。 ### 开发环境与依赖库 对于JSF开发而言,需要的...
JavaServer Faces (JSF) 是一个用于构建Java Web应用的标准框架。通过使用特定的扩展和库(如RichFaces、IceFaces等),可以将JSF转变为一个支持AJAX的框架,从而提高用户界面的响应性和交互性。 ##### 4. Wicket ...
6. **AJAXandJSFBestPractices.pdf**:AJAX与JavaServer Faces(JSF)的结合使用是构建动态Web应用的常见方式。这份文档可能讨论了如何在JSF中有效地使用Ajax,以及遵循的最佳实践,以提高性能和可维护性。 7. **...
Tapestry是一个开源的基于servlet的应用程序框架,它使用组件对象模型来创建动态的,交互的web应用。一个组件就是任意一个带有jwcid属性的html标记。其中jwc的意思是Java Web Component。 Tapestry使得java代码与...
11. **ZK**:ZK框架设计的Web应用使用组件模型,允许开发者构建高度互动的用户界面,且内部集成了AJAX技术,提供高效且易于使用的开发体验。 以上这些框架各有特点,适用于不同的开发需求和场景。选择合适的框架取...
JavaServer Faces(JSF)是Java平台上的一种服务器端组件框架,它支持创建丰富的Web应用。通过AJAX-enabled JSF,开发者可以在不刷新整个页面的情况下更新JSF组件,从而提供更好的用户体验。这种方式结合了JSF的强大...
对于Ajax框架,如Prototype、jQuery、DWR、Dojo和ExtJS,它们提高了Web应用的交互性。 在业务逻辑层,Java支持Servlet和JSP处理HTTP请求,以及各种框架如Struts、Struts2、JSF和Spring MVC,这些框架简化了开发过程...
在Web浏览器端,HTML、CSS和JavaScript构成了网页的基础,Ajax技术则用于实现页面的异步更新,常见的Ajax框架有Prototype、jQuery、DWR、Dojo和Ext。 进一步深入,开发者需要掌握Web服务器的基础知识,如Servlet和...
这种方法涉及到使用专门为AJAX设计的框架,如DWR (Direct Web Remoting) 或者 Dojo Toolkit。这些框架不仅提供了强大的客户端功能,还包含了一些服务器端组件,使得开发者能够轻松地在客户端和服务器之间传递数据。 ...
Ajax框架如Prototype、jQuery、DWR、Dojo和Ext.js提供了更高效的前端交互功能。同时,开发工具如ANT、LOG、JUnit等提高了开发效率和测试质量。 接着是业务逻辑层,Java的核心基础如类、对象、封装、继承和多态构成...
- JBossWS,Axis,XFire:用于创建和消费Web服务。 19. **JDBC连接池**: - C3P0,DBCP,Proxool:管理数据库连接的工具。 20. **搜索引擎和爬虫**: - Lucene+Heritrix:全文搜索和爬虫。 21. **开源许可协议...
对于Web应用,HTML/CSS/JavaScript/Ajax是基础,而Ajax框架如prototype、jquery、dwr、dojo和ext则提供了更强大的交互功能。此外,构建工具如ANT、日志工具(LOG)、单元测试框架JUNIT也是开发者必备的。 进一步...
As a Java developer, you want a guide that shows you how to add Ajax functionality to your web applications with a minimum of effort. Well look no further than Pro Ajax and Java Frameworks. In this ...
- **预期成果**:能够使用JSF框架开发Web应用程序。 - **Struts2.0** - **学习目标**:掌握Struts2.0框架的使用。 - **具体内容**:学习Struts2.0的新特性和优化之处。 - **预期成果**:能够使用Struts2.0框架...
Svarog是基于AsteriskPBX的基于Web的实时呼叫中心,包括诸如portlet,ajax(DWR / Dojo),jsf(MyFaces)和SpringFramework之类的技术。
熟练掌握常见的Ajax框架(如Dojo、ExtJS、DWR、GWT、Prototype、jQuery等)。 - **RIA方向**:拥有多年的Flex项目经验,精通Flex体系架构及与服务器端的多种通信方式;熟悉Cairngorm、PureMVC等常见Flex MVC框架;...