在 IBM Rational Application Developer V7.5 中创建自定义 JavaServer Faces 组件

Comments

JSF 组件:它们是什么以及谁需要它们

JSF 框架的优势之一是它基于组件的构架。组件是使用 JSF 技术构建任何 Web 应用软件的构建板块:它们会实现下面所有任务:

  • 在客户端中控制 UI 实现
  • 将 UI 窗口小部件的绑定控制在后台数据中
  • 回发到这台服务器过程中对如何请求要处理的参数进行控制
  • 控制如何提交转换以及确认有效的值
  • 取消对于用户行为做出回应的事件
  • 等等

JSF 的规范以及它的实现提供了大量您(作为一个应用软件开发者)可以立即使用的基础组件:若干输入组件(比如 inputText),若干输出组件(比如 outputText),一个数据表格,一对布局面板(比如 panelGrid),一个按钮,一个链接,以及图像。

使用核心 JSF 实现所提供的这些组件构建一个功能性的 Web 应用软件是可能的。然而, 对于这个组件设置却有一定的限制。当您设计最新 Web 应用软件时,您要尽量为您的用户提供丰富的经验,而且这些经验与 JSF 规范相比提供了更多复杂的组件。您需要的组件有这些,比如菜单,丰富的文本编辑器,文件上载,以及日历:这些正是用户所期望的功能。

值得庆幸的是,JSF 构架非常灵活,并且除了 JSF 应用软件所提供的那些之外,它还允许您创建您自己的组件。因此,开发者创建了 JSF 组件库来满足其它应用软件开发者的需求。在当今市场上已经有几种重要且普遍使用的组件库,包括以下这些:

  • IBM JSF Widget Library (JWL)
  • MyFaces’ Tomahawk
  • Trinidad 和 Tobago
  • JBOSS 的 RichFaces
  • ICEFaces
  • 等等

然而,虽然这些组件库十分庞大,却没有一个能满足所有开发人员需求的组件库。您可能需要一个在您选择组件库中没有的特殊 JSF 组件。

如果是这样的话,您可能要自己反思反思,“我应该自己来构建这个组件吗?”

很多情况下,答案是“是的”。构建一个自定义 JSF 组件通常是正需要做的事情。一个自定义组件可以让您在一个 JSF 标签中容纳许多功能。那么您就可以在许多页面和应用软件中重新使用这个标签,并可以在您的组织中与其他开发人员共享。它还简化了维护工作,因为这个功能保存在一个位置,而不是散布在您组织中的许多页面中。

例如,假想您的应用软件需要搜集关于一个用户地址的信息。您很可能需要不止一次的操作:您可能对其他用户的家庭地址,办公地址,运输地址,以及上演地址感兴趣。您会查看所有的常见组件库,但是没有一个拥有处理地址的组件。因此您就要使用标准的 JSF 组件,并从各种输入和输出域中快速构建一个地址(图 1)。

图 1. 地址组
街道,城市,州,以及邮政编码域
街道,城市,州,以及邮政编码域

因为您不止一个页面上需要这样的地址组,您要在各个页面上重复操作,还有可能在不同的应用软件上重复此操作。您的页面都能够正常地运作吗?是的。是不是有大量类似的编码被重复了一次又一次呢?的确是这样。这难道就是维护的噩梦吗?完全正确。如果一周后您需要重新排列这些域或者添加其它国家的域怎么办?您需要在创建这个地址组的每个页面进行变更!

如果用您自己创建的包含这个组的组件来替代,然后使用单个的标签,比如很普遍的 <my:inputAddress value="#{address}" /> 就会容易多了。您的 JSP 源代码应给更精悍更清晰,如果您曾需要变更这个地址组,您就只需要在一个位置进行变更。您还可以与您的同事或者在线社区共享您的 inputAddress 组件,这样每个需要这样组件的人都可以从您的工作中获益。

到目前为止可以很清楚地看到,创建一个自定义组件是一件有益的事情,但是最佳创建方法是什么呢?虽然 JSF 规范可以创建新的组件,但是它不能使其简化。如果您想创建一个组件,您需要创建三个 Java 类:

  • 一个组件类
  • 一个呈递类
  • 一个标签处理函数类。

除了那些类,还应该在 faces-config.xml 文件以及 标签库 文件中提供关于这个新组件的信息。这是一项乏味且容易出错的工作。

这就是为什么 Rational Application Developer V7.5 要有一个能够帮助 JSF 开发人员快速且简便地创建自定义组件的新特征。作为一名组件创造者,您可以使用熟悉的 Rational Application Developer 工具(比如从面板中拖放,WYSIWYG 编辑器, Properties, 以及 PageData 视图),并且 Rational Application Developer 能够自动为您创建所有所需的 Java 类和配置文件。

当然,如果您是一名高级用户,您仍然可以自己调节生成的 Java 类来实现更大的动力和灵活性。然而,您不需要了解内部 JSF 构架的用来在 Rational Application Developer 中创建组件的相关知识。

要论证这个新特征,您要为每个常用案例,比如附有标签的输入域,来创建一个简单的自定义 JSF 组件,如列表 1所示。

列表 1. 附有一个标签的输入域
<h:outputText value=”Name:” / > <h:inputText value=”#{person.name}” />

这样的对几乎在每个 JSF 应用软件中都能找到。即使这个地址组先前显示在 图 1 中也能找到三次。您需要将这两个标签置于一个单个的可用组件中,如列表 2所示。

列表 2. 可用组件
<my:inputLabel value=”#{person.name}” label=”Name:” />

创建一个自定义 JSF 组件

JSF 组件很少独立存在。相反,它们多数是一个组件库的组成部分,组件库就是组件的集合,您可以将它们拖入到任何应用程序中,可以重复使用,以及共享。组件库通常是一个单独的 Java™ archive (JAR) 文件,它包括大量的组件,并且组件库可以使用所有的配置文件。IBM 的 JWL, MyFaces 的 Tomahawk, 以及 JBOSS 的 RichFaces 都是组件库的例子。

因此,要创建一个自定义组件,您首先要创建一个组件库。

创建一个组件库

要创建一个组件库:

  1. 选择 File > New > Project
  2. Web 目录下,选择 Faces Component Library Project
  3. 点击 Next

New Faces Component Library 会打开。注意它看起来与您用来创建新 Web Project 的向导十分相似。唯一的区别是,Configuration 域设置为 Faces Component Library,如图 2 所示。Rational Application Developer 中的整个自定义 JSF 组件的设计与您所熟悉的标准 Web 和 JSF 工具十分相似,这样您的学习曲线就可以降到最低。

图 2. New Faces Component Library 向导
箭头指向所选择的 Configuration
箭头指向所选择的 Configuration
  1. 给您的组件库输入一个名称(在这个案例中是 MyComponents),然后点击 Finish
  2. 作为一名高级用户,您可能需要在点击 Finish 之前三次点击 Next 按钮。这样您就可以调节一对组件库设置,比如图 3 中所显示的它的 URI,前缀, 以及生成的 Java 类包裹名称。
图 3. Component Library 设置对话框
配置组件库的对话框
配置组件库的对话框

创建一个组件

  1. Library 项目已经创建,在 Enterprise Explorer 视图中右键点击这个项目的名称,并选择 New > Faces Custom Component

一个 New Custom Component 向导会被打开。再次注意,这个向导与您曾打算创建的常规 Web 页面几乎一模一样。唯一的不同是,您选择用来将页面定义为 Custom Faces Component 的特殊模板,如图 4 所示。

图 4. 新的自定义组件
箭头指向模板,在右边预览
箭头指向模板,在右边预览
  1. 为这个新组件输入一个名称(在这个案例中是 inputLabel),然后点击 Finish

当您点击 Finish之后, Rational Application Developer 将创建一个 JSP 文件,可以让您设计这个组件并在这个编辑器中打开。注意这只是一个常规的 JSP 文件,当您用它工作时,所有您熟悉的 Rational Application Developer 工具您都可以使用:

  • Palette
  • Properties
  • QuickEdit
  • PageData 视图

然而,与常规 JSF 页面不同的是,自定义组件并没有 <BODY> 或者 <f:view> 标签。相反,它使用了一个特殊的 <jsfc:component> 标签,可以包含将组成您的自定义组件的其它 JSF 标签。

检查 Enterprise Explorer 视图中您的存储库项目。注意您刚才创建的组件 JSP 文件之外,Rational Application Developer 还在这个存储库中生成了大量其它的文件,如图 5 所示。

图 5. 生成的文件
MyComponents 在树形图中展开
MyComponents 在树形图中展开

生成的文件包含以下内容:

  1. Component 类 (InputLabelComponent.java)
  2. JSP 标签处理 (InputLabelTag.java)
  3. Renderer 类 (CustomComponentRenderer.java)
  4. 配置文件: faces-config 和标签存储库 (faces-config.xml)
  5. Library JAR 文件包含所有的组件构架 (MyComponents.jar)
  6. 测试这个组件的页面 (testInputLabel.jsp)

无论何时您对包含这个组件定义(在这个案例中是 inputLabel.jsp) 的 JSP 文件进行变更时,Rational Application Developer 就会自定重新生成所有其它功能组件存储库所需的文件。它然后会将它们打包到一个单独的 JAR 文件中。这个 JAR 文件能够有效地变成您自己的组件库,您可以在以后项目中使用这个组件库并与其他人一起分享。Rational Application Developer 还会生成一个测试页面,使您能够看到这个自定义组件被分配到这个服务器时是如何操作的。

配置一个 Component

既然您现在已经创建了一个新组件,该配置它的属性和属性了。

  1. 回到在这个编辑器中打开的组件定义页面 (inputLabel.jsp),然后选择 <jsfc:component> 标签(要么通过点击 Source 视图中的标签,要么点击 Design 视图中的虚线矩形中的标签来实现)。

您现在可以使用 Properties 视图来配置这个新组件,如图 6 所示。

图 6. 组件属性
指定名称,属性,描述以及行为
指定名称,属性,描述以及行为
  1. 使用 Properties 视图,您可以配置:
    • 这个组件的 Tag 名称 。默认情况下,这个标签名称与您创建的 JSP 名称是相匹配的,但是这两者不完全一样。
    • 这个组件的 Description。这个描述应该对您组件的其他用户有所帮助(如果您决定将它与其他人一起共享)。
    • 指定详细的 Component 操作。JSF 规范定义了少量标准的组件,而且这些组件正是您希望您自己的组件在操作时与之相似。除了 Basic JSF 组件 之外,选项还包括一个 Input 组件,一个 Multi-Select 组件,以及一个 Command 组件。 当您选择其中一个选项时,Rational Application Developer 将会自动生成被选择组件类型的生成属性,并在这个组件类中生成代码来支持所选择的操作。
    • 这个组件的 Attributes
    • 最后,您要按照下面的操作来指示 Rational Application Developer: 当这个 JSP 变化时,不要改写生成的 Java 类。这个选项对高级用户是非常有帮助的,一旦这个组件类生成,这些用户就会选择手工调整这个类。在这种情况下,您要将 JSP 中的组件定义从这个组件的 Java 源中分离出来。

对于您的 inputLabel 组件,将它配置成得像一个 Input 组件一样进行操作,并添加两个属性:标签和值。

  1. 要添加属性,可以点击 Properties 视图中的 Add 按钮并输入属性 Name Class,如图 7 所示。您添加的两个属性将会成为 Class java.lang.String
图 7. 添加一个属性
定义组件属性对话框
定义组件属性对话框

一旦配置,这个 inputLabel 组件的 Properties 视图看起来就应该如图 8 所示。

图 8. 配置的组件
组件特性资料
组件特性资料

注意,因为您使这个组件像一个 Input 组件一样操作,因而 Rational Application Developer 会自动添加 最接近的需要的,以及典型的 Input 组件的 valueChangeListener 属性。

创建组件内容

现在该是定义这个 inputLabel 组件实际内容的时候了。正如您所记住的那样,您想要它成为一个显示标签的 outputText,紧跟着的是显示一个值的 inputText

  1. 从 Palette 中,将一个 Output 和一个 Input 组件拖拽到这个页面上。
  2. 从这个 PageData 视图中,将 Output 组件捆绑到 标签 属性上,并将 Input 组件捆绑到 属性上,可以通过将那些属性拖拽到 Design 视图组件顶端来实现,如图 9 所示。
图 9. 创建组件内容
浏览器在左边,设计页面在中间,调色板在右边
浏览器在左边,设计页面在中间,调色板在右边

注意您在 Properties 视图中配置的自定义组件属性也列在 Faces 组件 类别下的 PageData 视图中。

当您将一个组件属性捆绑到另一个组件上时,一个特殊的 JSF 表达就会产生来访问这个属性的运行时: #{component.attribute},如图 10 所示。

图 10. 组件源
代码显示了将一个组件属性捆绑到另一个组件上
代码显示了将一个组件属性捆绑到另一个组件上

这意味着,如果您将如这个案例一样来使用这个组件, <my:inputLabel value=”#{person.name}” label=”Name:” />,那么 outputText 的值将会变成 “Name:” ,同时 inputText 的值将会变成 #{person.name}

这就是您在定义一个新组件内容所要做的一切。一旦您保存了这个页面,Rational Application Developer 将会自动更新所有所需的构件,而且这个组件库也可以随时被使用。

测试这个组件

现在您已经创建了一个新组件,那么在将它应用到实际应用软件上或者将它与其它人共享之前,您可能要测试它是如何在服务器上运行的。为了达到这个目的,Rational Application Developer 已经创建了一个测试页面: testInputLabel.jsp。这个测试页面是一个常规的 JSP,它包含这个新组件标签,因此您要将它部署到一个服务器上,从而可以查看这个新组件的行为。

  1. 打开 testInputLabel.jsp 文件。注意这个页面源包含一个单独的 <m:inputLabel> 标签,然而这个 Design 视图却显示了 outputText 以及这个新组件所包含的 inputText (请看图 11)。 这个 Properties 视图列出了所有的 inputLabel 组件属性 (包括您早期添加的 标签)。这个 QuickEdit 显示了一个 Value Changed 事件,因为您配置了这个新组件,使它像一个 Input 样操作。
图 11. Component 测试页面
附有多个框架和标签的页面
附有多个框架和标签的页面
  1. 使用这个 Properties 视图,输入一些 标签 属性,保存此页面并在服务器上运行它。

一旦这个浏览器打开,您将看到一个标签后紧跟着的是一个输入域,两者都显示了这个新组件属性所制定的值(图 12)。

图 12. 在服务器上运行
Name 显示了 Yury
Name 显示了 Yury

您现在已经使用 Rational Application Developer 工具创建了一个完整的功能性新 JSF 组件。

使用 Web 应用软件中的自定义组件

您现在已经拥有一个全新的 JSF 组件库,您可以在您的 Web 应用软件中使用,也可以与其他同事分享。

Rational Application Developer 自动将属于您的组件库所有构件打包到一个单独的 JAR 文件中,您可以自己使用也可以分配给其他人。然而,要充分使用 Rational Application Developer 的工具特性,您需要为您的存储库创建一个 存储库定义。为了简短描述 Rational Application Developer 的支持,请看 参考资料 部分。

创建一个存储库定义

要为刚才创建的存储库创建一个存储库定义:

  1. 右键点击 Enterprise Explorer 视图中您的存储库项目 (MyComponents)。
  2. 选择 New > Faces Library Definition
  3. 在打开的 Create Faces Library Definition 向导中(图 13)
    1. 输入一个存储库名称 (例如, MyLibrary)。
    2. 注意您的存储库项目已经预先选择。
    3. 点击 Finish。
图 13. Library 定义
输入名称,选择 JAR,指定 Faces 项目
输入名称,选择 JAR,指定 Faces 项目

当 Rational Application Developer 完成了您存储库的处理过程后,编辑器就会打开。在编辑器中,您可以自定义您的新存储库和组件工具支持的所有方面:

  • Palette 中所显示的内容
  • 组件是如何形象化的
  • 在过拽和放下操作中发生了什么
  • 等等
  1. 制定一个超出这篇文章范围的存储库定义,这样您就只接受 Rational Application Developer 为定义所创建的构建。关闭浏览器。

既然 Library Definition 已经创建,您可以开始在常规 Web 项目中使用这个新存储库,或者您可以与其他人共享这个 Library Definition 项目 (MyLibrary)。

在 Web 应用软件中使用这个自定义组件

  1. 使用 Faces 项目配置中创建一个新 Dynamic Web 项目,然后在其中创建一个新 Web 页面。

当这个页面在这个编辑器中打开时,您将看到您所创建的新组件存储库和新组件在 Palette 上都是可利用的,紧邻所有常规 Rational Application Developer 面板抽屉,如图 14 所示。

图 14. Palette
MyLibrary 下的 input
  1. inputLabel 组件从这个 Palette 拖拽到您的页面上。因为这是您第一次在 Web 项目上使用这个新存储库, JAR 文件包括您的自定义组件,并且这些组件要拷贝到这个项目中。
  2. Rational Application Developer 将提示您来确认。点击 OK 即可确认。

有了更早期的测试页面,您将看到一个 <m:inputLabel> 标签被添加到这个 Web 页面的源中。这个标签像一对 outputTextinputText 组件,较为形象化地显示在 Design 视图中,如先前的 图 11 所示。这个标签在 Properties 视图中是可利用的,Value Changed 事件在 QuickEdit 视图中也可以被使用。

  1. 在服务器上运行这个页面,您将在这个浏览器中看到这个组件描绘器,如先前 图 12 所示。

您在 Web 项目中已经成功地使用了您自己自定义的 JSF 组件。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational, Open source
ArticleID=388152
ArticleTitle=在 IBM Rational Application Developer V7.5 中创建自定义 JavaServer Faces 组件
publish-date=05082009