级别: 中级 Dan Allen ([email protected]), 高级 Java 工程师, CodeRyte, Inc. 2007 年 5 月 21 日 JavaServer
JSF 不是为成为一个完整的 Web 应用程序框架而设计的。相反,它提供一个健壮的、事件驱动的 API 和 UI 组件库,用于构建更复杂的应用程序框架。
Struts 2,因为它将 JSF 看作是面向更大范围的设计。而
在阅读本系列之前,如果您想下载 Seam,那么请阅读 参考资料 一节。 寻找 Seam
刚刚阅读到关于 尽管 Seam 显然非常适合作为 JSF 的补充,但是在激烈的竞争环境中,它遭到了一定程度的轻视。当今市场中充斥着各种各样的 Web 应用程序框架 —— 包括 Shale 和 Struts 2,新来者往往不受重视,Seam 还没有在主流行列站稳脚跟。 我
对 EJB3 的考虑 正如我将要解释的那样,Seam 通过一些有价值的 hook 和组件管理进程 扩展默认 JSF
注释处理,而不需要依赖于 EJB 3 中的任何机制。的确 依赖于 EJB3 容器的一组有限的注释则是专用于那个环境的。在某些情况下,将 Seam 集成到一个没有 EJB 3 耦合的 IT 投资中可以获得更好的成本效益。如何使用 Seam 视个人偏好而定。
配置并使用 如今有那么多种 Java 框架,每天只有有限的那么多小时,显然,如果 Seam 难于集成的话,它就无立足之地。幸运的是,将 Seam 添加到项目中很简单。因为
的 jar,以及它的众多的依赖项。Seam 还使用 Hibernate 注释用于数据验证,所以除了主 Hibernate jar
生命周期中。(图 3 大致描绘了集成到这个生命周期中的 Seam 增强。) 清单 2. Seam phase 监听器配置
最后,将一个空的 seam.properties 文件放在 清单 3. Seam 属性文件
过滤器,该过滤器扩展 JSF 生命周期以外的 Seam 特性。
与 Seam 关联
生命周期中,只需在类定义的上面添加一个简单的注释 清单 4 显示了 在 Seam 用语中,这个动作被称作双射(bijection,即 显然,清单 4 中的 POJO bean 只是简单地演示了 Seam 的用法。随着本系列讨论的继续,我将探索另外的方法来实现 Seam。 清单 4. 一个典型的 Seam POJO bean
Spring 的注入
了使用由一个已有的 Spring 容器管理的服务层对象中的投资,需要将所有处理相关业务逻辑的 Spring bean 注入到 Seam 清单 5. 注入一个 Spring bean
这个例子设置支持使用以轻量级容器(这里就是 Spring)配置的无状态服务和数据访问(DAO)层。因为不需要 EJB3,所以部署的目标可以是任何基本的 servlet 容器。 现在,您对 Seam-JSF 实现有了一个初步的印象,接下来我将更深入地探讨我在使用 JSF 时遇到的挑战,以及 Seam 如何缓解这些挑战。 再谈 JSF 为了充分理解 Seam 为 JSF 带来了什么,就需要理解 JSF 与其他流行的基于 Web 的编程方法有何不同。JSF 是实现传统的 如果将基于动作的框架想象为使用 “push” 模型,而将组件框架想象为使用 “pull” 模型,那么这种区别就很容易理解了。组件框架中的控制器不是预先处理页面请求(在基于动作的框架中控制器就是这么做的),而是在请求生命周期中作出让步, 在视图中调用数据提供方法。此外,页面上的元素,即组件被绑定到事件,这些事件可以触发服务器端对象(激活后)的方法调用,从而导致重新显示相同的视图, 或者转换到另一个页面。因此,组件框架也被归类为事件驱动的。组件框架抽象出用于事件通信的底层请求-响应协议。 事件驱动方法的优点是可以减少单个方法在呈现视图时需要预先做的工作。在组件框架中,UI 事件或解析的值绑定表达式直接导致方法调用。 一 个应用程序即使只达到中度成熟,它通常也需要在任何给定页面上使用很多不相关的活动。如果将对所有这些信息的管理全部放入一个动作或者一个动作链中,那么 势必给维护带来极大的困扰。因此,开发人员常常发现他们的代码偏离了面向对象模型的轨道,反而陷入了过程编程模型的泥潭。相反,组件框架将这种工作隔离出 来,更自然地加强了对象的角色和责任。
Seam 与 JSF 对 于 JSF 和组件框架的基础已经介绍得差不多了。实际上 —— 很多 Java 开发人员最近发现 —— 转移到 JSF 并非总是一帆风顺。采用组件模型会带来一些全新的问题,首要的一个问题是您通常需要试着使应用程序符合基于动作的 Web。很多时候,JSF 需要具有像基于动作的框架那样的行为,但是在标准 JSF 中这是不可行的,至少不为每个请求使用 phase 监听器就不行。 JSF 的其他主要缺点还包括对 HTTP 会话的依赖过重(尤其是在一序列的页面之间传播数据时),简陋的异常处理,缺少书签支持,以及太多的 XML 配置。 通过与 JSF 自然地集成,同时加入 JSF 规范委员会放弃的或者忽略掉的新功能,Seam 解决了很多这样的问题。Seam 的框架鼓励使用紧凑的、易读的、可重用的代码,并且避免了所有为解决上述问题而常常加入的 “粘连(glue)” 逻辑。图 3 涵盖了 JSF 生命周期中用于简化应用程序代码的大多数 Seam 扩展点:
注释的类创建一个 Seam 组件。由于 Java 语言缺乏用于在代码级添加元数据的一种公共语法,因此需要设计很多 XML 配置。当 Java 页面动作和 RESTful URL
不使用组件框架的情况下,另一个必须解决的熟悉的问题是预先处理每个请求,就像在基于动作的框架中那样。受此影响的用例是 RESTful 当 首先,您可能会本能地想要在页面的主 backing bean 上实现一个 页面动作来帮忙 Seam 页面动作是启用对 JSF 的书签支持的关键。Seam 的创立者允许在进入页面时请求参数 您 工厂组件 JSF 最大的一个失败是没有在用户触发的动作或动作监听器方法以外的其他地方提供可靠的机会来为视图准备数据。将逻辑放在一个动作方法中并不能保证该逻辑在视图呈现之前得到执行,因为页面视图并不总是在用户触发的事件之后。 例
provider)的概念,工厂数据提供者由 有状态 conversation
于 JSF 很容易引起困惑的一个地方是它的状态管理功能。JSF 规范解释了在接收一个动作之后页面是如何 “恢复(restored)” 不将值绑定数据存储在组件树中的一个最值得注意的不利方面是虚幻事件效果(见 参考资料),这是由 虽然丢失的事件看上去像是异常状况,但并不会导致 JSF 生命周期中出现红色标志。因为这些组件依赖底层数据,以保持稳定和适当地被恢复,所以 JSF 难于知道丢失了什么。
幸的是,JSF 规范天真地引导开发人员将大多数 backing bean 放入 conversation 作用域中 —— 甚至可以在 Seam 的 conversation 作用域 “Seam JSF 在 Seam 之前,使用有状态数据的惟一方便的方式是依赖于 HTTP 会话。Seam 纠正了这个问题,它通过建立一个全新的 conversation 作用域, 异常处理
JSF 规范完全忽视异常管理,将责任完全放在 servlet 容器上。允许 servlet 容器处理异常的问题在于,这严重限制了错误页面上显示的内容,并且禁止了事务回滚。由于错误页面是在请求分发器转发之后显示的,
Ajax remoting
最终的解决办法是建议使用 JSF
为 JavaScript remoting(常常记在 Ajax 名下的一种技术)提供了一种独特的方式,该方式与 Direct
结束语 根据您目前在
显然,在不久的将来,Seam 会成为一个官方规范,Java EE 栈最终将提供 “显著简化的基于 Web 的应用程序编程模型”。这对 JSF Seam 只需很少的设置就可以开始用于 JSF —— 而正是这一点小小的付出,就能解决 JSF 开发中的一些最麻烦的难题。回报胜于付出 ——
注意:
参考资料 学习
获得产品和技术
讨论
关于作者
|
转自:http://www.ibm.com/developerworks/cn/java/j-seam1/