现在的位置: 首页 > 综合 > 正文

Seam 和 JSF

2013年10月06日 ⁄ 综合 ⁄ 共 2494字 ⁄ 字号 评论关闭

Seam 和 JSF

很多 Java 开发人员最近发现 —— 转移到 JSF 并非总是一帆风顺。采用组件模型会带来一些全新的问题,首要的一个问题是您通常需要试着使应用程序符合基于动作的 Web。很多时候,JSF 需要具有像基于动作的框架那样的行为,但是在标准 JSF 中这是不可行的,至少不为每个请求使用 phase 监听器就不行。

JSF 的其他主要缺点还包括对 HTTP 会话的依赖过重(尤其是在一序列的页面之间传播数据时),简陋的异常处理,缺少书签支持,以及太多的 XML 配置。通过与 JSF 自然地集成,同时加入 JSF 规范委员会放弃的或者忽略掉的新功能,Seam 解决了很多这样的问题。Seam 的框架鼓励使用紧凑的、易读的、可重用的代码,并且避免了所有为解决上述问题而常常加入的 “粘连(glue)” 逻辑。图 3 涵盖了 JSF 生命周期中用于简化应用程序代码的大多数 Seam 扩展点:

图 3. Seam 生命周期增强

让我们来考虑其中一些增强,因为它们适用于 JSF 开发中一些常见的挑战。

并不复杂的配置

Seam 演示了 Java 5 注释的一个非常实用的用法。Seam 的部署扫描程序检查所有包含 seam.properties 文件的归档文件,并为所有标有 @Name 注释的类创建一个 Seam 组件。由于 Java 语言缺乏用于在代码级添加元数据的一种公共语法,因此需要设计很多 XML 配置。当 Java 5 规范中加入注释后,就获得了一个更好的解决方案。由于大多数 backing bean 是为了在特定应用程序中使用而开发的,因此没有理由将这些 bean 的配置 “抽象” 到类本身以外的任何文件中。附带的好处是,您可以少处理一个文件。Seam 提供了一组完整的注释来帮助将 bean 集成到 JSF 生命周期中。清单 4 显示了其中一些。

页面动作和 RESTful URL

在不使用组件框架的情况下,另一个必须解决的熟悉的问题是预先处理每个请求,就像在基于动作的框架中那样。受此影响的用例是 RESTful URL、书签支持、通过 URL 模式获得的安全性以及页面流验证等。这也是学习使用 JSF 的开发人员容易感到困惑的主要原因之一。有些 JSF 供应商通过用开发人员工具提供 onPageLoad 功能来绕过这个问题(见 参考资料),但这不是核心规范的一部分。

当用户直接从书签(比如)请求一个商品详细信息屏幕时,通常会发生什么事情呢?由于 JSF 控制器采取被动方式,当页面开始呈现时,即使明显没有目标数据,也不能将用户重新带到逻辑流的开始处。相反,这种情况下只能显示一个空页面,其中只有一些空值或其他可能存在的假信号。

首先,您可能会本能地想要在页面的主 backing bean 上实现一个 “prerender” 方法。然而,在组件框架中,backing bean 与页面之间的关系并不一定都是一对一的。每个页面可能依赖于多个 backing bean,每个那样的 bean 也可能在多个不同的页面上使用。必须用某种方式将一个视图 ID(例如 /user/detail.jspx)与一个或多个方法关联起来,当选择呈现相应的视图模板时就调用这个(些)方法。您可以使用 phase-listener 方法,但是这仍然需要定制的逻辑来确定对于当前视图和阶段是否应该执行该功能。这种解决方案不但会导致很多冗余逻辑,而且会将视图 ID(很可能是应用程序中最不确定的部分)硬编码到编译后的 Java 代码中。

页面动作来帮忙

Seam 的页面动作可以帮助您预先拦截呈现的假信号。页面动作是使用方法绑定指定的,方法绑定在进入页面时、Render Response 阶段之前执行。对于 /WEB-INF/pages.xml 配置文件中一个给定的视图 ID,可以配置任意数量的方法绑定。(或者,可以通过将它们放在视图模板邻近的一个文件中,复制它的名称,但是将文件扩展名换为 *.page.xml,从而分解每个页面的定义)。对于页面动作,XML 是有必要的,因为视图 ID 非常容易变化。就像 JSF 通过 Apply Request Values 阶段的值绑定将 post 数据映射到模型对象一样, Seam 可以通过执行页面动作之前的值绑定将任意请求参数映射到模型对象。这些请求参数注入的配置嵌套在页面动作 XML 声明中。如果页面动作方法调用返回一个非空字符串值,则 Seam 将其当作一个导航事件。因此,不必迁移到一个完整的基于动作的框架中,仍然可以比得上最特别的特性。Seam 包括很多内置的页面动作,它们通常跨应用程序使用。其中包括用于验证 conversation 是否建立的一个动作;可以启动、嵌套和结束 conversation 的动作;处理预期异常的动作;以及确保适当的凭证的动作。

页面动作是启用对 JSF 的书签支持的关键。Seam 的创立者允许在进入页面时请求参数 actionMethod 触发一个方法调用,从而利用了这一特性。更妙的是,您不需要做任何额外的工作就能为书签创建链接。 Seam 提供了两个组件标记:s:link 和 s:button,用以处理细节。这两个标记分别对应于 JSF 中的 h:commandLink 和 h:commandButton。不同之处在于,Seam 组件标记组装的链接使用一个 HTTP GET 操作发出请求,而不是使用 JSF 的 HTTP POST 表单提交模型表示。因此,Seam 创建的链接对书签更 “友好”,对于开发人员来说更方便。

您可能还注意到,当使用页面动作时,地址栏中的 URL 对应于正在显示的页面,而不总是背后的一个页面。(后一种情况之所以会发生,是因为 JSF 将表单配置为 post 回生成它们的 URL。地址栏没有更新,以反映执行动作后的新视图,因为 JSF 通过一个服务器端重定向使之前进。)如果您想演示页面动作的灵活性,那么可以使用它们来创建 RESTful URL(例如 /faces/product/show/10)。为此,将页面动作方法映射到视图 ID“/product/show/*”,其中 /faces 前缀是 JSF servlet 映射部分。然后,该页面动作方法利用请求 URL,以判断数据类型和数据标识符,加载数据,然后导航到适当的模板。这个例子很明显地演示了 JSF 请求 URL 与视图模板之间并不一定存在一对一的关系。

抱歉!评论已关闭.