蜀川居 2011-12-27
JSFPKTapestry,谁将成功晋级J2EE5Web层框架?作者:sterning自从2000年Struts诞生以来,基于动作(action-based)的MVC架构在web开发方面可谓风光无限。目前主流的WEB框架如Struts、Webwork(Java)、RubyonRails(Ruby)、ZendFramework(PHP)等都采用这种设计模式。URL映射到控制器(controller)和控制器中的动作(action),由action来处理请求并输出响应结果。然而风水轮流转,基于组件(component-based)和事件驱动(event-driven)的开发模型,抢占了动作开发模型的不少风光,出演了一场“狼来了”的好戏。有的成为了PKStruts的优秀选手。而由Sun公司推出的JSF(JavaServerFaces)和Apache组织主导的Tapestry是这场选秀的成功晋级者。JSF将是J2EE5.0中所包含的Web开发框架,这应该是第一个成为JCP(JavaCommunityProcess)标准,并且随J2EESDK一起发布的web框架,可以看出sun对它的期望很高。JSF最大的竞争对手是Tapestry,是Apache的产品。但是Apache又推出Myfaces,这是对JSF标准的另一个实现。也许读者也和笔者一样,在JSF和Tapestry之间犹豫很久,将来从Apache的态度上应该可以看出二者的走向。在本文中,笔者将对JSF和Tapestry这两种框架进行详细的比较。比较将涉及到这两种框架的设计、运行环境以及如何开发等方面的内容。希望通过这样的比较,让读者了解这两种框架各自的优缺点,以便于在自己的项目中,根据实际情况,选择合适的框架。本文的内容基于JSF1.1和Tapestry4.0。一、JSF和Tapestry的简介JSFJSF是Sun公司在JCPJSR127标准倡导下的技术实现。另外一个JSF的实现,就是Apache的一个项目MyFaces。JSF的目的是为Web应用的用户界面创立标准的框架。采用JSF开发的Web应用,可以运行在Java服务器上,把用户界面传递到客户端。JSF通过控制servlet和具有事件处理和组件加工的丰富的组件模型管理Web应用生命周期。TapestryTapestry是在Apache软件许可下发布的一个开放源码且基于Java的框架。Tapestry最初于2000年在SourceForge注册,来自于AppleWebObjects,随后,于2003年成为Apache的一个项目。与JSF不同的是,Tapestry并不是某一个JSR规范的实现,它仅仅是一个开源项目。它是专门为了简化Web开发设计的。它有以下关键特性:易安装性:不需要是Web应用程序高手,就可以让Tapestry启动并运行。易使用性:只需要基本的Java和HTML是的,确实是HTML,而不是servlet)技能就可以编写Tapestry应用程序。健壮性强。当站点增长超过10、50或100个页面时,也不必抛弃Tapestry。对于多数Web应用程序来说,Tapestry都足够健壮。二、Web开发JSFJSF对servletAPI进行了封装,采用JSP的技术作为其表现层技术。程序员在使用组件做JSF应用程序的开发时基本上不需要直接操作HttpRequest和HttpResponse,并且对用户输入验证、手机等其它设备(通过rendererKit)、多语言(通过资源文件方式)和换肤(通过rendererKit)的支持都有相应的封装,可以方便的实现。目前开源的组件库有MyFaces,ADF等可以使用,其中有些组件内置对Ajax的支持。开发工具方面,IBM的WebSphereStudio,Oracle的JDeveloper10g和FaceIDE等IDE对JSF应用开发提供可视化编辑支持。在大多数情况下,Web应用并不需要编写适应于不同设备的程序。尽管JSF设计工具提供了简单的图形化方法来构建和预览JSF应用,但是在一个开发中,页面设计人员更多的是喜欢用流行的HTML设计工具来编写和预览页面,这就发生了一个冲突,即只有将更多的页面工作转移到java程序员身上,因为一个页面设计人员通常情况下是不乐意去操作JSF设计工具的。JSF开发者一直在寻找一种解决这些问题的方法。JSF技术设计良好的扩展体系,使得这成为可能,其中一个技术浮现出来,那就是表现层控制器。一个非常有前途的表现层控制器的实现就是Facelets。由java.net创建的开放源代码项目。Facelets的灵感就来源于Tapestry的模板模型,这使得JSF不再依赖于JSP技术。Facelets允许开发者创建Tapestry风格的标签。TapestryTapestry把一个应用程序分成一系列的页面。每一个页面由Tapestry的组件组成。组件本身也许是由组件构成。tapestry页面本身就是组件,只是有特殊用处的组件。所有的tapestry的组件可以成为其他组件的容器。Tapestry页面,和许多用户定义的组件一样,有一个模板,由一个特殊的html定义了一些静态的和动态的组件位置,同时有标签表明那些内嵌的组件是活跃的。组件不需要有标签。Tapestry组件参数也许是双向的,一个组件可以读取一个参数来获得一个值,或者写一个参数来设置一个值。其他的组件。如form和form控制组件(TextField,PropertySelection,Checkbox等等)使得html中的form的实现变得容易。当这样的组件被显示的时候,他们从程序对象中读取属性值来提供默认值。当form被提交的时候,form中的组件读取http的查询参数,转换数值为合适的类型并且更新程序对象的属性。对于大多数的Tapestry应用来说,Tapestry的表现层模板看起来就是一个只有简单规则的Html,只不过其中加入了一些Tapestry的属性。Tapestry的模板不仅仅可以用HTML作为载体,它也支持其他的一些标记语言,Tapestry标签是具有良好格式的标签,即必须成对出现。Tapestry模板技术支持的标记语言典型的就是HTML以及用于无线应用的WML。其最大的一个特点就是,可脱离Servlet容器而直接预览。组件和页面的开发过程完全一致,都是由模板、page/componentclass和specification文件组成。IDE方面目前有开源社区开发的eclipse插件Spindle和TapestryPalette可用,对开发效率有一定的提升。三、请求处理生命周期何为请求处理生命周期呢?简而言之,过去必须自行编写代码才能处理的必要的后端处理,现在全由请求处理生命周期执行。除了处理进入的请求参数,它还管理服务器端的用户界面组件集,并把它们与用户在客户端浏览器中看到的组件同步。请求处理生命周期在一个web应用中是很重要的,它反映了一个请求从提交到将信息返回给客户端的处理过程。当然,请求处理生命周期必须能以某种优雅的方式,在正确的地方插入用户定制的请求处理操纵逻辑。JSFJSF的请求处理生命周期清晰的定义成六个步骤:恢复视图、应用请求值、处理验证、更新模型值、调用应用程序和渲染响应。从第二步应用请求值开始,可以直接跳到最后一步渲染响应,甚至可以直接返回给客户端并且通知JSF运行时,响应操作已经完成了。有些方法要访问JSF的FacesContext对象,比如状态监听器(phaselisteners)、事件操纵器(eventhandlers)、转换器(converters)、验证器(validators)等,这都可能忽略请求处理生命周期中的某些步骤。Tapestry相对JSF有一个单一的生命周期模型而言,Tapestry的生命周期依赖于其调用的引擎服务(engineservice)。每一个引擎服务(engineservice)都有其自己的生命周期。比如,Tapestry中的DirectService控制标单的提交,而PageService用于渲染页面,并且不需要额外的服务端操作。每一个引擎服务(engineservice)都被设计成在自身的生命周期内完成一些特定的任务。这就意味着,对于一个特定的需求,你可以创建一个对应的引擎服务(engineservice),并且可自己定制生命周期。JSF的生命周期概念更容易理解,而Tapestry可对一个特定的操作定义一个生命周期,这在某些问题的解决上,可能会提供更优雅的解决方案。四、性能比较JSF在只使用JSF及JSF自定义组件的情况下,demo应用速度最快,200用户并发访问的响应时间为1.8秒,基本上可以达到servlet+jsp的性能。使用JSF+5个Faceletcomposition组件的情况下,demo应用仍可达到200用户并发访问的响应时间为2.6秒的性能。使用JSF+20个Faceletcomposition组件的情况下,demo应用可达到200用户并发访问的响应时间为3.1秒的性能。如果在业务层方法没有大的效率问题、并在压力较大的页面适当使用缓存的情况下,JSF应用程序可以达到在dell2850机器上100-200并发5秒内响应的性能Tapestry在Tapestry4之前的版本,Tapestry使用了大量的动态调用(大部分是使用OGNL调用的),这样势必会造成大量运行效率的损失。好在大多数WEB程序的瓶颈是在访问数据库而不是在页面上,所以并没有对Tapestry的推广构成毁灭性的影响。但是随着Tapestry社区的发展,使用人群的增加,HowardLewisShip(Tapestry的作者)和一些支持Tapestry项目的开发者,意识到了这个问题,并作了大量的工作对性能进行改进。在Tapestry引入HiveMind之后,Tapestry的活力明显的增强了,第三方支持包也越来越丰富。这种丰富不仅仅是组件的丰富,而是包括框架在内。其它人可以很容易的为Tapestry提供高效的服务。从测试数据可以看到tapestry在使用相同数量框架自身提供组件的情况下,运行效率比JSF明显要低一些,但也算是在可以接受的范围内。五、JSF和Tapestry的全面比较为了对JSF和Tapestry进行全面的比较,让读者了解这两种框架各自的优缺点,以便于在自己的项目中,根据实际情况,选择合适的框架,对它们两者进行比较,总结了如下表分析比较。JSFTapestryArchitecture跳转模型:FrontController+组件化编程。页面模型:PageController+组件化编程。ProgrammingModel业务逻辑:POJO的编程风格;页面逻辑:主要是JSP,也可以用HTML风格。业务逻辑:Taperstry4需要继承基类;但Taperstry5就是POJO风格;页面逻辑:普通的HTML。RequestProcess由官方定义的六个步骤组成;取决于EngineService。Navigation通过faces-config.xml配置文件完成。URL是全局的,没有额外的配置文件;除非显式跳转,所以行为都在本Page上。而跳转分两种:1.DirectLink写在页面上2.在代码逻辑中定义页面跳转逻辑。Eventhandling页面定义事件发起;两种方式参数传递方式:一种分离传递;另一种通过FacesContext。页面定义事件发起;直接赋予参数,没有参数个数限制;除此外还有内置的生命周期相关的eventComponentState没有状态维护机制,每次request都从建组件。提供组件状态的维护机制。ComponentDev基于JSPTag的开发方式。开发方式类似Page,逻辑代码和页面分离,页面输出使用HTML。View主要是JSP,也可以用HTML风格。HTMLValidationandConversion提供了多种方式支持,但客户端验证支持不好,同时在form一级的支持不好,通常需要项目自己定制。同样提供多种方式支持;此外提供客户端的Validation;天然地支持form一级支持。I18N较好的支持。很好的支持,额外提供预览功能。Testability测试支持简单容易。Tapestry4的测试不容易,不过Tapestry5的测试可以很简单。Extensibility良好良好IndustryomentumJSF业界标准,业内厂商支持会比较多,不过未必不会出现EJB2的结局。应用范围小于Struts,之前的版本学习曲线太高。Migrate从Struts迁移不难;从Struts或者JSP迁移难度较大些。六、结论JSF是一个强大的且可扩展的框架,无疑它将会是很成功的。尽管它目前还有不少的缺陷。它致力于解决JSP模板问题的方向是正确的,但可能不是最好的方法。笔者认为,能提供丰富的组件选择,特别是像Tapestry一样基于属性模型的设计,也许将会更加的适合JSF未来的方向。同时,降低组件开发的难度,也应将是JSF努力的方向之一,可以将模板机制引入组件开发模型。而这方面,Facelets无疑是最成功的。JSF只有在组件和事件机制这个概念上类似Tapestry,但是不似Tapestry那样是一个完全组件的框架,所以,如果读者做一个对页面要求灵活度相当高的系统,选用Tapestry是第一考虑。JSF则适合在一般的数据页面录入的系统中,对一个新的系统,可以直接从JSF开始;如果需要切换,可以将JSF和Tapestry一起考虑。另外,JSF/Tapestry不只是支持Html,也支持多种客户端语言如WML或XUI等。这二者之间关系:如果说Tapestry比较极端点,那么JSF则比较中庸一点,中庸主义是Sun联盟的一贯策略。总的来说,J2EEWeb框架目前处在一种群雄逐鹿的状态,没有一个绝对的领导者。Struts是最流行的,但是它的主架构师也是主要的开发者已经抛弃了它。被称为Struts取代者的JSF目前还没有获得足够的影响力。而同时,其他的框架如Tapestry正在慢慢开始流行。