级别: 初级 盛培莹 (shengpy@cn.ibm.com), 高级信息工程师, IBM应用开发合作中心
2004 年 3 月 01 日 本文通过实例详细介绍了J2EE Web应用架构的新兴标准Java Server Faces,该标准着眼于简化J2EE服务器端Web应用尤其是前端UI的开发,使得拥有不同技术能力的开发者都能够方便快捷地开发J2EE的Web应用。
有关JSF
最近的六七年间,随着JAVA服务器端编程技术的不断成熟与普及,能够熟练运用Servlet/JSP等标准来开发HTML-based Web应用的队伍也在不断发展和壮大,但是很明显,Servlet/JSP等规范仅仅定义了基于Java技术的Web应用最底层基础编程架构,而并未对上层应用架构以及可重用组件等高级特性作出任何规定,因此,如果要真正完成这样一个基于Java技术的Web应用,除了懂得运用Servlet/JSP等技术进行编程之外,还有很多工作需要完成。通常,为了开发出一个优秀的J2EE Web应用,许多开发队伍的骨干们开始设计和实现自己的Web应用框架,用来定义诸如导航规则、可重用UI组件、数据访问模型等等一系列重要的高级特性,其目的也无非是为了保证自己的应用能够获得更高的可扩展性、可重用性、易开发性、易维护性等等这些作为一个优秀应用所不可或缺的特点,当然,近几年来Apache Struts - Open Source的Web应用框架在业界得到了很高的认可,然而,我们显然仍然需要一套工业标准来统一和规范基于JAVA技术的Web应用框架,而工业标准就意味着该框架能够得到几乎所有业界J2EE平台提供商和工具提供商的全面支持。
目前Java Community Process(JCP)正在进行最终草稿审核的Java Specification Requests(JSR) 127 - Java Server Faces(JSF)(
http://www.jcp.org/en/jsr/detail?id=127)就是一个基于JAVA技术的Web应用框架标准,同时也是对于J2EE标准的一个重大补充。JSF使得您能够轻松而方便地设计开发基于JAVA技术的Web应用,同时所开发出来的应用也会非常易于维护、重用和扩展。 JAVA/J2EE业界普遍认为JSF将会在不久的未来取代目前业界非常流行的Apache Struts框架。
有一个事实非常有趣,Apache Jakarta Struts框架的作者Craig McClanahan同时也是JSR 127 JSF项目的两个领导人之一,这似乎保证了未来两种框架之间的易迁移性;那么再从应用开发的角度来看的话,Struts和JSF两种框架也有很多相似之处,比如就像Struts框架一样,JSF也充分遵循MVC设计模式,也定义了一整套JSP标记库来生成与JavaBean属性绑定的HTML元素,也定义了相应的组件导航模型等等,接下来,JSF这个即将出台的新标准将会成为J2EE的一部分,而目前业界所有的J2EE应用服务器,不论是免费的还是商用的,以及相应的开发工具都会正式公开对于JSF的支持。从以上两点来看我们有理由相信,在不久的未来,把已有的Struts应用转向JSF将不会存在很大的困难。
现在让我们进一步来看看JSF到底是什么。 JSF为广大基于JAVA的 Web应用用户界面的开发人员提供了标准的编程接口、丰富可扩展的UI组件库(一个核心的JSP标记库用来处理事件、执行验证以及其他非UI相关的操作和一个标准的HTML 标记库来表示 UI组件)、事件驱动模型等一套完整的Web应用框架,通过 JSF ,您可以在页面中轻松自如地使用 WEB 组件、捕获用户行为所产生的事件、执行验证、建立页面导航…,同时您会发现,当使用支持JSF的开发工具来开发 JSF 应用的时候,一切将会变得异常简单,就类似于我们现在开发VB或者PowerBuilder程序一样的简便,GUI方式拖放组件、修改组件属性、建立组件间关联以及编写事件侦听器等等,这样,一个并不是特别熟悉Java的Web应用开发人员也能够轻松地完成自己的任务了,这种易开发性对于J2EE而言无疑是太重要了。
IBM的WebSphere Studio Application Developer (WSAD 5.1.1)是第一个对JSF提供支持的商用IDE,由于目前该标准还未最后发布,因此我们所公开申明的支持都是Tech Preview性质的,但事实上,WSAD5.1.1对于JSF的支持已经相当完整,为开发JSF应用提供了丰富的编程特性,比如对于action, managed bean,faces配置文件,拖拽式组件编程以及页面导航等等的支持,甚至还提供了Web数据访问模型(WDO)的支持。因此,现在大家已经完全可以使用WSAD 5.1.1来尝试开发您自己的JSF应用并熟悉这一新兴的Web应用框架。本文会集中介绍一些JSF的基本特点并通过一个简单的示例来向大家展示JSF应用开发的Rapid Application Development(RAD)特性。
在向大家介绍一个简单示例之前,让我们先来了解一下JSF的一些基本特点。
首先,JSF应用需要一些必须的运行态组件来保证其运行:
- Faces servlet - 在J2EE Web部署描述符(web.xml)中配置。Faces Servlet是一个JSF应用的引擎,同一个Web容器中的不同JSF 应用都会有一个自己的 Faces servlet ,它担任了类似于 Model-View-Controller 中controller的角色,用来控制所有发向后端应用组件的请求,使用Apache Struts框架的开发人员会发现这个组件和Struts的controller servlet异曲同工。
- Faces配置文件 - 作为一个单独的配置文件(faces-config.xml)存放在WEB-INF/lib 目录下。这个文件非常类似于Apache Struts框架的配置文件(struts-config.xml),用来担任应用组件和导航模型的主配置文件。
- 一些必须的JAR文件 - 每一个JSF应用必须的JAR文件, 存放在WEB-INF/lib 目录下: jsf-api.jar, jsf-ri.jar, jstl.jar, standard.jar, commons-beanutils.jar, commons-digester.jar, commons-collections.jar, 和 commons-logging.jar。
通常以上这些组件都能够由支持JSF的开发工具帮您自动生成或配置, 而一个完整JSF的应用除了包含上述必须的组件之外,还需要一些其他的东西,比如:
- 管理JavaBean。用来定义和Web UI组件绑定的Java对象。
- JSP和HTML文件。完成UI展现。
- 页面模板。定义了一个JSF应用统一的页面风格和一些通用的Meta设置。
- 自定义事件侦听器。用来处理用户操作或者组件状态变化产生的事件。
当然,JSF应用的UI完全可以不用JSP/HTML,而是用well-formed的XML文件来构建。对于部署而言,JSF应用并不需要有特殊的运行态环境支持,它可以跑在任何一个标准的J2EE容器上,比如WebSphere, Tomcat等等。
其次,我们需要明白一个JSF应用实际上就是一个标准的J2EE Web应用,它有Web部署描述符、JSP文件、标记库和一系列静态资源,只不过和普通的J2EE Web应用相比,它依靠一系列运行在一个普通J2EE Web容器中的特殊组件,来达成自己特殊的运行态模式,事件驱动是其中一个很重要的特点。让我们来大致看一下JSF是如何运作的。
我们通常会编写一个JSP 页面作为 JSF 应用的用户界面,每个这样的JSP页面都会包含一些 JSF 组件来描述Web元素,比如表单、输入框、按钮等等,一个组件可以嵌套在另一个组件当中,比如输入框、按钮可以放置在表单当中。每一个JSP页面都可以被表示成为一个组建树,同时对应一个或者多个管理JaveBean来保存用户输入以及组件间交互的数据。
每当用户做了任何操作,比如点击按钮或者提交表单的时候,都会有事件产生,这些事件会通过 HTTP协议被传送到服务器端的Faces Servlet进行处理。Faces Servlet 会根据Faces配置文件了解整个JSF应用的组件导航模型以及受管JavaBean的绑定,于是该JSF应用在运行过程中会渐渐被表示成为一棵组件树,当这个组件树状态发生变化的时候会触发一些事件,这时会由注册过的侦听器来进行相应的处理。
通常,建立一个简单的JSF 应用需要以下几个步骤:
1. 创建一个页面模板。为整个JSF应用定义统一的页面风格和一些通用的Meta属性。
2. 创建基于JSF的 JSP页面。用 JSF 组件包装 HTML 元素,使得用户可以为其对应的管理JavaBean属性赋值,比如文本组件的相关属性:字体、大小、 颜色、摆放位置、事件触发的动作等等。
3. 创建管理JavaBean。将用户界面组件与JavaBean属性绑定,以保存用户输入以及组件间交互的数据。
4. 利用已有的事件监听器或者创建自己的事件侦听器来定义当一个特定事件发生的时候应该做出什么样的处理,比如当用户点击了一个按钮或者提交了表单,服务器端应该如何动作。JSF 支持两种类型的事件:ActionEvent 与 valueChangeEvent。ActionEvent 是针对用户提交表单以及点击按钮的,而valueChangeEvent是当一个 JSF 组件值发生改变时被触发。
一个简单的 JSF 应用示例
接下来我们来展示一个非常简单的JSF应用:用户输入自己的姓名信息,来查找他/她在数据库中存放的地址信息。在开发这个应用的过程中,你只需要有IBM WebSphere Studio Application Developer(WSAD) 5.1.1就可以了,如果手边没有,可以去这个站点下载一个试用版:
http://www.ibm.com/developerworks/cn/downloads/
该示例的主要目的在于向大家展示使用支持JSF的J2EE开发工具来编写JSF应用是多么的简便,拖拽UI组件、绑定受管JavaBean和JSP UI组件、图示化的页面导航、方便易用的数据访问模型(WDO)以及简单的事件处理。该示例主要有由以下几个基本元素构成:
Input.jsp 一个Faces JSP, 用户输入姓名
Result.jsp 一个Faces JSP, 输出该用户在数据库中存储的地址信息
Bean.java 一个管理JavaBean, 用来存放用户输入以及UI组件间交互的数据
|
当然,为了使这个应用能正常工作,我们还需要前面所说的那些必须组件,比如faces servlet, faces配置文件还有UI组件的管理JavaBean以及一些必须的jar 文件,这些我们在前面已经都有提到。
以下分几个小段来说明这个 JSF 示例。最后一小段"发布与运行"将描述 JSF 应用如何在WSAD 5.1.1内置的WebSphere 5.1上发布和运行。
一. 创建一个动态Web项目
在这一小段中,我们将创建一个动态Web项目,并给它加入JSF支持,这将使得一些基础的JSF组件被自动添加到我们的项目中来。
1. 打开WebSphere Studio Application Developer(WSAD) 5.1.1
a. 运行WebSphere Studio Application Developer Version 5.1.1
b. 设置工作区目录,比如: G:\WSAD5.1.1WorkSpace,如果你不能设置工作区目录,到命令行运行 G:\WSAD5.1.1>wsappdev -setworkspace (图示 1)
图示1.打开WSAD 5.1.1并设置工作区
c. 打开J2EE 视图
2. 创建一个动态Web应用,在创建过程中,我们将加入JSF应用所需要的相关支持
a. 在J2EE视图中打开J2EE 层次结构图,右键点击Web模块并选择 新建 => 动态Web 项目 (图示 2)
图示2. 创建动态Web项目
b. 在项目创建向导中,输入JSTestWeb作为动态Web项目名,确保左下角的配置高级选项被选中,点击下一步。在下一页J2EE设置页里,在EAR项目一栏里输入JSFTestEAR, 如果不作任何指定的话一个缺省的EAR项目将会被创建, 输入JSFTest作为上下文根,并确保J2EE的版本是1.3, 选择下一步 (图示 3)
图示 3. 为新建的Web项目指定EAR项目名称以及上下文根
c. 接下来在功能部件页面上选择以下的功能部件,相应的类库和组件就会被预先配置到这个Web项目中: (图示 4)
- 添加Faces基本组件
- 缺省样式表(CSS 文件)
- WDO 关系型数据库运行时
- JSP 标记库
点击 完成
图示 4. 选择Web项目的功能部件
3. 导入一个写好的JavaBean
a. 从本文的末尾的链接处下载本文相关的源代码JSFTest.zip,并找到Bean.java
b. 在J2EE试图里打开项目导航器,展开JSFTestWeb目录,并在Java资源目录下创建一个Java包spydemo,然后将Bean.java拖入spydemo目录下(图示 5)
图示 5. 导入Bean.java
二. 创建Faces JSP并建立管理JavaBean绑定和关系数据对象绑定
在这一小段中,我们将创建两个Faces JSP: Input.jsp和Result.jsp,我们可以从中了解WSAD 5.1.1所提供的页面导航,拖拽式编程,GUI方式管理JavaBean及关系数据对象(Web Data Object) 绑定,还有简单的事件处理
1. 首先,我们来创建一个Faces JSP Input.jsp
a. 打开Web试图的项目导航器, 展开JSFTestWeb目录,右键点击WebContent目录,选择 New新建 =>Faces JSP 文件 (图示 6)
图示 6. 创建Faces JSP Input.jsp
b. 在下一页面的文件名处填入Input,确保没有选择从页面模板创建,点击下一步配置高级选项
c. 在下一页标记库页面中,点击添加,通过向导增加一个标记库 h
http://java.sun.com/jsf/html(图示 7)
点击 完成
图示 7. 添加一个标记库
d. 这时候WSAD5.1.1会带你自动进入Web试图并在工作台打开Input.jsp的编辑窗口,如果该窗口没有打开,你可以在JSPTestWeb目录下的WebContent目录下找到并打开这个文件。
2. 接下来我们要编辑Input.jsp, 并给Input.jsp拖入一些UI组件
a. 在Input.jsp的编辑窗口里将页面上的缺省文字删除并输入以下文字,见图示8,然后从右边的选用版里选择输入组件拖拽到如图示8所示的位置, 当问及输入组件的类型, 选择文本 (图示8)
图示 8. 拖拽输入组件到如图位置并指定输入类型
b. 继续用步骤a的方法拖入UI组件,如图示 9
图示9. 完整的Input.jsp设计图
c. 注意一个有趣的小细节, 我们在编写Input.jsp过程中只是拖拽了一些UI组件,而类似输入组件<h:input_text id="text1"></h:input_text>的元素是需要放置在表单组件中的,在我们这个例子里,<h:form formName="form1" id="form1"></h:form>是由WSAD5.1.1工具自动为我们添加的。
<h:form formName="form1" id="form1">
<P>您好, 请输入您的姓名:</P>
<P>姓:<h:input_text id="text1"></h:input_text></P>
</h:form>
|
d. 还有一个细节值得注意,如图示10,在Java资源目录下面,WSAD5.1.1自动为我们创建了一个和Input.jsp对应的管理JavaBean Input.java,用来保存JSP页面中UI组件的数据模型,并将它加入了WEB-INF目录下面的faces-config.xml中,作为JSF应用组件树的一部分 (图示 10 和 11)
图示 10. JSFTestWeb项目目录结构
图示11. faces-config.xml
<faces-config>
<managed-bean>
<managed-bean-name>cb_Input</managed-bean-name>
<managed-bean-class>codebehind.Input</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>
|
3. 接下来我们将利用WSAD5.1.1提供的Web站点导航功能来创建我们的另一个Faces JSP Result.jsp
a. 打开JSFTestWeb的页面导航 (图示12)
图示12. 打开JSFTestWeb项目的Web站点导航
b. 将左下角的Input.jsp拖入导航面板 (图示13)
图示13. 将Input.jsp拖入导航面板
c. 在Input.jsp下面创建子代页面Result.jsp, 输入显示名为Result.jsp (图示 14)
图示 14. 在Input.jsp下面创建子代页面Result.jsp
d. 双击Result.jsp标签,开始创建这个文件,并选择创建Faces JSP (图示 15)
图示15. 创建Faces JSP Result.jsp
e. 接下来的步骤和创建Input.jsp类似,参照之前的描述即可。完成向导之后,进入Result.jsp的编辑页面,如图示16,填入文字,并拖入输出组件,并选择文本作为输出类型 (图示 16)
图示16, 填入文字,并拖入输出组件,并选择文本作为输出类型
f. 注意保存Input.jsp和Result.jsp
4. 接下来我们将重新打开 Input.jsp来为它作管理JavaBean的绑定
a. 到Web试图的项目导航器里打开Input.jsp, 在左侧页数据窗口里新建管理JavaBean关联 (图示 17)
图示 17. 新建管理JavaBean关联
b. 在创建管理JavaBean关联的时候,注意选择spydemo.Bean (图示 18)
图示18, 创建管理JavaBean关联
c. 回到Input.jsp编辑窗口,选中姓右边的输入框,然后到左下角的属性栏里去设置和受管JavaBean域的绑定,姓的输入框绑定Bean的lname域,而名输入框侧绑定Bean的fname域 (图示 19)
图示19.设置和受管JavaBean域的绑定
d. 注意保存Input.jsp
5. 现在我们来为Result.jsp建立管理JavaBean以及关系数据对象((WDO))的关联, Web Data Object(WDO)是类似于未来的Service Data Object(SDO)来规范和定义数据访问模型。
a. 在本文末尾的链接里下载相关的源代码JSFTest.zip,找到t3.dll,从DB2命令窗口执行 db2 -tvf t3.ddl, 用来创建一个数据库JSF,一个表Customer,并插入一条记录
b. 接下来到Web试图的项目导航器里打开Result.jsp,和刚才对于Input.jsp的操作一样,在左侧页数据窗口里新建管理JavaBean关联,与前面不同的是这次我们选择已有的受管JavaBean。然后我们在左侧页数据窗口里再新建一个关系数据列表对象的关联 (图示 20)
图示 20. 新建关系数据列表
c. 在数据列表属性对话框里,输入 Customer 作为数据列表的名称,然后选择新建一个数据库连接,在我的例子当中使用的DB2/UDB 8.1 (图示 21)
图示 21. 新建一个数据库连接
d. 在接下来的数据列表属性对话框里,选择CUSTOMER表,点击下一步,进一步选择需要包括在数据列表对象中的列 (图示22)
图示 22. 选择CUSTOMER表,然后选择需要包括在数据列表对象中的列
e. 然后要为我们的数据列表对象添加两条过滤条件 (图示 23)
图示 23 . 添加两条过滤条件
f. 在Result.jsp中将会出现一个输出列表,删除这个自动生成的列表 (图示 24)
图示 24. 删除自动生成的列表
g. 接下来我们从右面的选用板里面拖入一个输出组件,类型为文本,然后选中该输出组件,到左下方的属性窗口去绑定数据列表对象Customer的CUST_ADDR (图示 25)
图示 25. 绑定输出组件与数据列表对象属性
h. 保存您的修改
6. 接下来我们来为Input.jsp定义一个当表单提交时候执行的一个操作
a. 在Web试图的项目导航器里找到并打开Input.jsp, 用鼠标点中提交按钮,然后到下方的快速编辑窗口里找到命令,选中命令,然后在右边的return null之前单击鼠标右键,插入一个操作转至页,选择Result.jsp (图示 26)
图示 26. 插入一个转至页操作
b. 保存您的修改
三. 部署与测试
在这一小段中,我们将在WSAD 5.1.1内置的WebSphere 5.1测试环境中部署和测试我们的例子
1. 在Web试图的项目导航器里找到JSFTestWeb项目WebContent目录下的Input.jsp
a. 在Inupt.jsp上单击右键,选择在服务器上运行,创建新的服务器,接受默认的参数配置 (图示 27)
图示 27 .在服务器上测试运行
b. 待服务器启动后,如图示,测试我们的应用,当我们输入姓名并提交请求之后,将会得到该姓名在数据库相应记录中的地址信息(图示 28)
图示 28. 测试应用
总结
这篇文章描述了JSF的基本组件和运行方式,也向大家展示了如何开发一个非常简单的JSF应用,可以肯定的是,实际应用中的 JSF会复杂得多,您可能需要自己编写一个事件侦听器或者页面模板等等,这些更加深入的问题我预备在另一篇文章中涉及。
下载 | 名字 | 大小 | 下载方法 |
|---|
| JSFTest.zip | 2 KB | HTTP |
参考资料
关于作者  | 
|  | 盛培莹,IBM应用开发合作中心高级信息工程师,在WebSphere/MQSeries/J2EE应用开发方面有4年的相关经验,对Web Services, Service Oriented Architecture, Aspect Computing方面有着浓厚兴趣。 |
对本文的评价
|