[翻译] JSF VS Tapestry 全面比较 <二>
标题: JSF VS Tapestry 全面比较 <二>
作者: by Phil Zoio
翻译: BlueCrystal
来自: http://www.theserverside.com/articl...s?l=JSFTapestry
正文:
Sidebar: 例子程序
在下面本文提供了一个例子程序,该程序的代码大部分都将在这片文章中做出详细的描述。这个程序主要就是一个管理个人假期的工具,它的主要功能包括:
* 一个home界面, 列出所有登记的假期,包括假期开始时间、天数以及一下描述信息;
* 一个detail界面,用于浏览某一登记假期的详细信息;
* 一个new界面,用于添加一个假期信息。
下面这幅图展示了该程序的主体流程和功能:
你可以从下列地址下载该程序基于不同框架的源代码:
JSF version
Tapestry version
对比1: 页面开发(Page Development)
一个web应用实际上就是后端用java代码获取相应数据,并将数据传递给前端表现层代码,然后最终返回给终端用户。因此,在一个开发人员看来,当他初次接触JSF和Tapestry时,最直接的感觉就是JSF的表现层是基于JSP的模板技术,而Ta pestry的表现层模板基本就可以看作是一个HTML。
JSF
JSF采用JSP的技术作为其表现层技术。与标准兼容的JSF实现必须实现一个核心组件的JSP标签集。下面的代码就是一个使用了JSF组件标签的Html代码:
代码:
<h:form>
<h:panelGrid columns="2" border = "1">
<h:outputText styleClass = "label" value="No"/>
<h:outputText value="#{holidaySession.currentHolidayBooking.holidayID}"/>
<h:outputText styleClass = "label" value="Date"/>
<h:outputText value="#{holidaySession.currentHolidayBooking.date}"/>
<h:outputText styleClass = "label" value="Number of days"/>
<h:outputText value="#{holidaySession.currentHolidayBooking.amount.value}"/>
<h:outputText styleClass = "label" value="Description"/>
<h:outputText value="#{holidaySession.currentHolidayBooking.description}"/>
</h:panelGrid>
<BR>
<h:commandButton value="Back" action="#{holidaydetail_backing.home}" immediate = "true"/>
</h:form>
含有JSF标签的html页面不能在标准浏览器中预览。要想浏览,必须使用JSF设计工具或者直接部署到应用中,在真实运行环境中浏览。
对于JSF技术来说,其表现层技术就是JSP,但是这不是唯一的解决方法。Hans Bergsten的文章介绍了可供选择的其他的方法,读者可阅读该文章获取详细信息,Improving JSF by Dumping JSP。 Bergsten的文章中指出了混合JSF和JSP标签暴露出的一些问题。当然,这些问题在JSF1.2和JSP2.1中会得到解决。
Tapestry
对于大多数的Tapestry应用来说,Tapestry的表现层模板看起来就是一个简单的规则的Html,只不过其中加入了一些Tapestry的属性。下面是一段例子代码:
代码:
<span jwcid = "@Conditional" condition = "ognl:currentHolidayBooking">
<p><strong>Holiday Details</strong></p>
<table>
<tr>
<td class = "label">No</td>
<td><span jwcid = "@Insert"
value = "ognl:currentHolidayBooking.holidayID">1</span>
</td>
</tr>
<tr>
<td class = "label">Start date</td>
<td><span jwcid = "@Insert"
value = "ognl:currentHolidayBooking.date" format = "ognl:dateFormat">1</span>
</td>
</tr>
<tr>
<td class = "label">Number of days</td>
<td><span jwcid = "@Insert"
value = "ognl:currentHolidayBooking.amount.value">1</span>
</td>
</tr>
<tr>
<td class = "label">Description</td>
<td><span jwcid = "@Insert"
value = "ognl:currentHolidayBooking.description">1</span>
</td>
</tr>
</table>
</span>
大家可以尝试把这段代码放入一个Html的body标签当中,你会发现浏览器可以正常的观看它。
上面的例子中,jwcid = "@componentName"属性就是定义了一个Tapestry标签。
Tapestry的模板不仅仅可以用HTML作为载体,它也支持其他的一些标记语言,Tapestry标签是具有良好格式的标签,即必须成对出现。 Tapestry模板技术支持的标记语言典型的就是HTML以及用于无线应用的WML。其最大的一个特点 就是,可脱离Servlet容器,直接预览。
事实上JSF标签由于不是标准的html标签,使得它对于初学者来说,是难于使用的。而对于很多java程序员来说,他们喜欢编辑HTML代码,至少是乐意编写html代码。
JSF技术宣称的一个技术优点就是,可使用同一个模板编写运行在不同设备上的应用,由此带来很大的灵活性。然而,这样做,由于要协调不同设备间的表现差异性,那么很可能同一个模板,将不能正好表现你的输出。同时,你不得不学习新的标签库的使用方法,并且搞懂它们是怎样映射到html的。随着时间的推移,JSF标签的简洁可帮助你很快的编写表现层代码,同时也降低了开发者对jsf设计工具的依赖。
本文认为,JSF的学习成本高于其技术优点。在大多数情况下,我们并不需要编写适应于不同设备的应用。尽管JSF设计工具提供了简单的图形化的方法来构建和预览JSF应用,但是在一个开发中,页面设计人员更多的是喜欢用流行的HTML设计工具来编写和预览页面,这就发生了一个冲突,即只有将更多的页面工作转移到java程序员身上,因为一个页面设计人员通常情况下是不乐意去操作JSF设计工具的。
JSF开发者一直在寻找一种解决这些问题的方法。JSF技术设计良好的扩展体系,使得这成为可能,其中一个技术浮现出来,那就是表现层控制器。一个非常有前途的表现层控制器的实现就是Facelets,由java.net创建的开放源代码项目。Facelets的灵感就来源于Tapestry的模板模型,这使得JSF不再依赖于JSP技术。Facelets允许开发者创建Tapestry风格的标签,就像下面这段代码一样:
代码:
<input id="bar" type="text" jsfc="h:inputText" value="#{foo.bar}"/>
在未来的一段时间内,Facelets将会被开发者所采用,或许会影响JSF未来的版本。
和JSF比较,Tapestry在表现层方面基于HTML代码,可被标准浏览器所浏览,这正是它在表现层上的优势所在。
比较2: java编程模型(Java Programming Model)
在前面我们提到Tapestry和JSF都允许表现层的模板直接和一个Java类中的属性和方法进行交互,那这些类的实例在运行时是怎么创建和管理的呢?
Tapestry
Tapestry的一个完整过程通常都要包括三个部分:用于显示的页面模板(一般就是html),带有相关属性和方法的java类,用于定义页面模板上的控制元素和java类的关系的页面定义文件。Tapestry有着一套特殊的访问HttpSess ion、ServletContext的体系。
在一个页面定义文件中描述所有的数据绑定是可以的,但是一个页面控制元素却不能在request周期内,绑定一个java类。在request周期内只能通过一个page类访问一些属性和方法。这其中最主要的限制就是关于page类的问题,一个pag e类必须是BasePage或者AbstractPage的派生类。从另一方面来说,这就意味着你所编写的表现层逻辑的代码将会和框架本身的实现有着非常紧密的耦合。不过,Tapestry未来的版本就会减少这种耦合,努力成为一个松耦合的编程模型。
JSF
在JSF应用中没有页面定义文件。它只有一个全局的配置文件,命名为:faces-config.xml,里面通常都定义了一堆"managed beans"。这些managed beans都是带有属性和事件监听器的定义良好的java bean。在faces-config.xml中定义的后端bean都有三个参数:一个标识符、一个java类名、一个bean的生存周期,生存周期可以是request、session、application中的一种。一旦在 faces-config.xml中定义好了一个managed bean,那一个前端页面上的显示控制元素就可以使用标识符来关联这个bean。managed bean也可以配置为引用另外一个managed bean。
JSF和Tapestry都可以方便的与其他的中间层技术整合,比如Spring。JSF managed bean facility是一个IoC(Inversion of Control)。通过诸如 JSF-Spring 这样的扩展技术,我们可以方便将其和Spring很好的整合在一起,使得JSF的表达式可以调用Spring的bean的方法。虽然Spring可以与 Tapestry3.0整合,但是在Tapestry4.0当中才能更好的充分发挥IoC特性;Tape stry的领导Howard Lewis Ship已经在Tapestry启动了IoC框架的工作。Spring的bean将会很轻松的注入到Tapestry应用的类中。
JSF的编程模型提供了更大的灵活型,因为你可以通过组合的方式来丰富你的代码功能。比如,你可以设定一个指定的managed bean完成页面的某些功能,同时,你也可以在这些bean里引用其他的managed bena,从而可在页面间共享一些功能。
而Tapestry必须使用类继承的方法,也就是说,Tapestry应用中的一个页面类必须从框架指定的基类中派生(包含一大堆框架指定的状态),这并不是一个理想的方法。
JSF能够非常直观的管理session和application周期内的状态: 页面代码可以方便的访问managed bean,而不管其生命周期是request、session还是application。而Tapestry在这方面就相对差点,不过, Tapestry4.0在这方面做了很大的改进,引入了类似于JSF managed bean的技术,同时,还支持Java 5.0的annotaions技术,减少对XML配置文件的依赖,从而降低应用配置的复杂性。
JSF在编程模型上来看,与Tapestry相比具有更大的灵活性。