JSF实战.docx
- 文档编号:12786262
- 上传时间:2023-04-22
- 格式:DOCX
- 页数:55
- 大小:1.42MB
JSF实战.docx
《JSF实战.docx》由会员分享,可在线阅读,更多相关《JSF实战.docx(55页珍藏版)》请在冰豆网上搜索。
JSF实战
本章内容
l JSF是什么,不是什么
l 基础技术(HTTP、servlet、portlet、JavaBean以及JSP)
l JSF与现有的Web开发框架的关系
l 构建简单的应用程序
欢迎阅读本书。
JSF(JavaServerFaces),或简称Faces,通过将丰富的、强大的UI组件(如文本框、列表框、分页面板和数据网格等)的支持引入Web开发领域,使得Web开发更加容易。
目前,JSF已经正式成为JavaEE的一个组成部分。
本书将帮助你了解JSF到底是什么,它如何工作,以及现在怎样将它应用到项目之中。
1.1 这是RAD化的世界
前Web时代的一个流行词汇是快速应用开发(RapidApplicationDevelopment,简称RAD)。
RAD的主要目标是使你能够使用大量可重用的组件来构建强大的应用程序。
如果曾用过诸如VisualBasic、PowerBuilder或者Delphi之类的工具,你就知道它们对提高软件开发的生产率来说是一个极大的飞跃。
我们第一次能够很容易地开发复杂的UI并将其与数据源进行集成。
你可以从组件面板拖出应用部件(UI控件或者其他组件),然后放到应用中。
这些组件都有它们自己的、影响其自身行为的属性(例如,font是所有显示文本的控件的公共属性;而数据网格则具有表达其数据存储源的dataSource属性)。
这些组件会产生一组事件,而事件处理函数则定义UI与应用的其他部分之间的交互。
你可以在集成开发环境(IDE)中直接访问它们,还可以很方便地在设计视图和代码视图之间进行切换。
RAD工具最适于开发全面完整的应用,同时它们对开发快速原型也是十分有用的,因为它们只需要很少代码甚至不需要代码就可以快速地创建UI。
另外,不管是对经验丰富的程序员还是新手来说,较低的门槛都能使他们立竿见影地得到开发结果。
这些工具通常分为四层:
l 基础组件架构;
l 标准部件;
l 应用基础设施(applicationinfrasturcture);
l 工具自身。
基础组件架构具有足够的可扩展性,这带出了第三方组件开发产业,比如Infragistics和DeveloperExpress这些专业的组件开发商。
当然,RAD的理念并未消失,它只是被其他更流行的词汇所代替而已。
它在某些JavaIDE和其他一些如BorlandDelphi和C++Builder的开发环境中仍然根深蒂固。
但是,这些环境没有将RAD的概念用于Web开发。
Web开发领域对RAD的采用异常缓慢。
这种缓慢的部分原因在于,对不简单、不一致的应用创建简单、一致的视图本身的复杂性。
与标准的桌面应用相比,Web应用要复杂得多。
有太多的资源需要管理——页面、配置文件、图像以及代码。
用户可能使用运行于不同操作系统上的不同类型的浏览器。
你还不得不应对HTTP,这是个非常难以构建复杂系统的协议。
软件领域对于屏蔽复杂性已经做得很好,所以过去几年出现了许多RAD风格的Web解决方案。
这些方案都将可视化、面向组件的强大威力带到了复杂的Web开发领域。
它们的祖先都是Apple的WebObjects,而微软则将这种概念通过VisualStudio.NET和ASP.NETWebForms带入了主流Web开发。
在Java世界也出现了许多框架,它们大多是开源的。
某些框架有工具支持,而有些则没有。
但是标准JavaRADWeb框架的缺乏使得Java解决方案的魔方缺少了一块,而这一块正是微软的.NET框架早就涵盖的范围。
JSF就是来填补这个空缺的。
1.1.1 什么是JSF
对于RAD工具的四个层次,JSF定义了其中三个:
基础组件架构、标准的UI部件(widget)集以及应用基础设施。
JSF的组件架构定义了一种通用方式来建立UI部件。
此架构能驱动标准的JSFUI组件(按钮、超链接、复选框、文本框等),也为第三方组件留出了空间。
组件是面向事件的,所以JSF允许处理客户端产生的事件(比如,文本框中的值发生变化或者用户点击某个按钮)。
因为对Web应用来说,与桌面应用不同,它总是要满足多个客户端(比如桌面浏览器、移动电话和PDA等)。
而JSF则有一个可以按照不同方式显示组件的强大架构。
它还具有可扩展机制来进行输入验证(如字段长度),以及在显示字符串和对象之间进行转换。
Faces也能自动保持UI组件和收集用户输入值的Java对象之间的同步,并且通过调用后台bean(backingbean)来响应事件。
另外,它有一个强大的导航系统并且全面支持多语言特征。
这些特征构成了JSF的应用基础设施,即构建新的应用系统必不可少的基本构建块。
JSF定义了工具支持的基础,但是将实现留给了工具厂商,这是Java的习惯。
你可以自行选择业界领先者提供的工具,它们都使你能够像使用其他RAD开发工具(如VisualStudio.NET)一样可视化地布局和设计WebUI(图1-1、图1-2和图1-3就分别展示了在IBM、Oracle和Sun的IDE开发工具中开发JSF的情形)。
或者,如果你愿意,也可在没有设计工具的情况下开发Faces应用。
图1-1 IBM的WebSphereApplicationDeveloper(WSAD)进行了扩展,在其所支持的无数种技术之外又增加了对JSF应用的支持。
你可以使用WSAD中熟悉的Eclipse环境可视化地构建JSF应用,并且可以混合使用其他JSP标签库
图1-2 Oracle的JDeveloper[Oracle,JDeveloper]具有对JSF的全面支持,并通过大量的UIX组件来对其进行完善和增强,而这些都可以集成到标准的JSF应用之中。
它也支持在其应用开发框架(ADF)[Oracle,ADF]中使用JSF组件(这个屏幕取自JDeveloper10g中的UIX组件,这是在下一版本JDeveloper中对JSF的基本支持)
图1-3 Sun的JavaStudioCreator[Sun,Creator]是个易用的、基于可视化的JSF应用开发环境。
你可以在用户熟悉的环境如VisualStudio.NET、VisualBasic或者Delphi中,在可视化JSF页面设计、JSP源代码编辑以及相关Java代码编写之间轻易地切换
赞美过后,我们应该指出JSF和桌面UI框架(如Swing或者SWT)之间的关键不同之处在于:
JSF运行在服务器上。
因此,Faces应用将运行在标准的JavaWeb容器中,比如ApacheTomcat[ASF,Tomcat]、OracleApplicationServer[Oracle,AS]或者IBMWebSphereApplicationServer[IBM,WAS],然后再向客户显示HTML或者其他标记语言。
点击Swing应用中的一个按钮,将产生一个事件,你可以直接在驻留于桌面的代码中处理该事件。
Web浏览器并不知道有关JSF组件及其事件的任何内容;它仅仅知道显示HTML[3]而已。
所以当点击一个Faces应用按钮时,将产生一个请求,由浏览器发送到服务器。
Faces负责将该请求转换成可以被服务器中的应用逻辑处理的事件。
它也负责保证在服务器中所定义的每个UI部件都正确地显示给浏览器。
图1-4展示了Faces应用的高阶视图。
你可以看到,应用系统运行在服务器上,并且可以集成其他子系统,比如EJB服务或者数据库服务。
当然,JSF还提供许多其他服务,可以帮助你以更小的代价构建更强大的Web应用。
图1-4 JSF应用的高阶视图。
JSF通过提供UI组件的支持,以及处理大量通用的Web开发事务而使Web开发更加容易
JSF有个特定的目标:
使Web开发变得更快、更容易。
它允许开发人员基于组件、事件、后台bean以及它们之间的交互性来进行思考,而不是基于请求、响应和标记来考虑问题。
换句话说,它屏蔽了Web开发中大量的复杂性,使开发人员能够集中于他们最擅长的事情:
开发应用系统。
注解 JSF是一种技术,本书用数百页的内容来尽量完整地介绍它。
开发工具通过能够产生JSP的GUI设计器和编辑配置文件的屏幕,包装了大量的开发难题。
在整本书中,我们都会展示JSF所使用的真实的Java、JSP和XML代码以及相关配置,这将使你感觉到工具可以使你的开发工作容易一些。
通过这种方法,你将完全了解IDE到底在幕后干了些什么,这对于应用构建之后的维护,以及在你想从一个工具厂商转移到另一个工具厂商的情况下,都非常有用。
当然,如果你根本不喜欢IDE,知道IDE实际是如何工作的也很重要(如果你是个IDE的发烧友,别担心,我们在书中会展示各种工具的屏幕截图,并且在线扩展的附录B中还包括对3个工具的详细介绍)。
1.1.2 业界支持
JCP社区过程(Sun公司扩展Java的方式)最好的一点莫过于有大量的公司、组织和个人投身其中。
通过JCP产生一种规范实际上并不算快速,但结果却非常之好。
JSF在2001年5月通过Java规范请求(JSR)127被引入;规范的最终版本JSF1.0在2004年3月3日才发布。
而JSF1.1(维护发布版)则是2004年5月27日发布的,1.2规范于2006年5月11日发布。
参与开发Faces的公司和组织(除Sun之外)包括Apache软件基金、BEA系统、Borland软件、
IBM、Oracle和Macromedia等。
这些公司开发的产品可分为三类(很多适合不只一类):
J2EE容器、开发工具以及UI框架。
因为JSF是与工具协作并运行于J2EE容器中的UI框架,这样划分是合理的。
最重要的是,这些公司中包括许多业界巨头。
这意味着可以期望JSF具有强大的业界支持。
并且,如果你的供应商不支持JSF,还可以免费下载并使用Sun的参考实现[Sun,JSFRI]。
要跟踪最新的关于JSF的新闻、文章、产品和厂商,请访问JSFCentral[JSFCentral],它是笔者维护的专门针对JSF的社区站点。
1.2 幕后的技术
所有JSF应用都是标准的JavaWeb应用。
JavaWeb应用通过ServletAPI和其他显示技术(如JSP)来运行超文本传输协议(HTTP),如图1-4。
显示技术用来定义与Java代码交互的组件所组成的UI。
Faces应用也可以运行于portlet之中,它类似于servlet。
JSF组件架构使用JavaBean来暴露属性和处理事件。
在这一节,我们将简述这些技术,并解释它们和JSF之间的关系。
如果你已经熟悉JavaWeb开发并且理解了它们和JSF之间的关系,则可以跳过这一节。
1.2.1 HTTP
外交官和政府首脑们来自不同的文化地区,讲着不同的语言。
为了沟通,他们遵循特定规则的礼仪和礼节,这就是协议(protocol)。
遵循协议使他们能够有效地沟通,即便他们具有完全不同的背景。
计算机也使用协议来进行通信。
遵循已经建立的协议使得程序之间能够互相通信,而不关心是何种特定的软件、硬件或者操作系统。
万维网(WWW)开启了共享文档机制。
这些文档通过超文本标记语言(HTML)来标记,允许人们查看文档并且可以方便地通过点击链接在文档间进行切换。
为了适应这种文档以及支持这种超链接能力,开发了HTTP(超文本传输协议)。
通过它各种Web浏览器能够以标准的方式从服务器获取文档。
定义 Web原本是针对静态内容设计的,比如学术文献,它们不会经常变更。
相反,动态内容,比如股票信息或者产品订单,却是经常改变的。
应用通常会产生动态内容。
HTTP是个简单的协议——它基于文本首部。
客户发送一个请求给服务器,服务器发送一个响应给浏览器并附带所请求的文档。
服务器是个失忆症患者——如果再请求文档,它不记忆关于客户的任何信息。
这种失忆意味着HTTP是“无状态”协议,它不在请求之间维护客户的信息。
HTTP的无状态性意味着它的伸缩性好(毕竟它是一个Internet协议,而Internet涵盖面广)。
这种特性对于HTTP原本要服务的静态文档不成问题。
请想象一下代客泊车的情况,如果服务生既没有给你收据也没有记住你的样子,当你返回时,他一定会花很多时间来寻找到底那一辆车是你的。
这就是在无状态环境中开发应用的问题。
要解决这个问题有两种方法:
cookie和URL重写。
这有点像泊车人给你开个收据,他自己也留着一联。
不管你使用何种语言,如果要编写Web应用,都要使用HTTP。
servlet和JSP的开发使得在该协议之上构建应用较为容易一些。
JSF的引入则使得开发人员能够彻底忘记他们所使用的协议。
1.2.2 servlet
HTTP能很好地服务于静态内容,Web服务器本身都自带这个功能。
但是需要编写代码来创建动态的内容。
即便HTTP是很简单的,仍然要做许多工作来编写与之协同工作的程序代码。
你不得不解析HTTP首部,理解它们的意义,然后以正确的格式创建新的头部。
而这正是JavaServletAPI所关心的:
提供面向对象的视图来简化Web应用开发[5]。
HTTP请求和响应被封装为对象,通过访问输入和输出流来读取用户请求和写入动态内容。
请求由servlet处理——servlet是处理特定HTTP请求的对象。
根据定义,标准的J2EEWeb应用基于ServletAPI。
servlet运行在容器中,容器本质上是一个Java应用,它执行所有幕后工作,比如与运行多个servlet相关的工作、关联那些组成一个Web应用的所有资源的工作以及管理所有其他相关服务的工作。
最流行的servlet容器是Tomcat[ASF,Tomcat],但是有些J2EE应用服务器(比如IBMWebSphere[IBM,WAS]和SunJavaSystemApplicationServer[Sun,JSAS])也提供servlet容器。
在前一节中说过,HTTP的一个大问题是无状态性。
Web应用解决这种问题的方法是使用会话(session),这使得用户好像总是在那里,即使他们实际上并不在。
会话是ServletAPI提供的一个最大的亮点。
虽然幕后它依然使用cookie或者URL重写,但已经对程序员屏蔽了这种复杂性。
ServletAPI还有其他很多优点,比如安全性、日志、生命周期事件、过滤、打包和部署等。
这些特征形成了JSF的基础。
事实上,JSF本身就实现为一个servlet,而所有的JSF应用都是标准的J2EEWeb应用。
但JSF在ServletAPI之上更进一步。
servlet包含了构建Web应用最基本的、必要的基础设施。
但是,你仍然不得不自己处理底层协议HTTP的属性:
请求和响应。
JSF应用具有UI组件,它们和后台bean相关联,并产生应用逻辑所使用的事件。
Faces使用ServletAPI作为其底层设施,但是应用开发人员却可工作在更高的抽象层次:
开发Web应用而无需过多关心HTTP或者ServletAPI自身的特定之处。
1.2.3 portlet
大多数Web应用都需要从数据存储中——通常是从数据库获得动态数据(即便业务逻辑是运行在另一种服务之上,如EJB或者CORBA服务,最后也要有些代码用来和数据库交互)。
然而,从Web的早期开始,就有从各种数据源汇聚信息到易于使用的用户界面之中的需求。
这种应用类型,称为门户(portal),最初应用于某些公司的领域,如Netscape和Yahoo等。
然而,越来越多的公司意识到,这种概念也非常适合于公司将来自各种内部数据源的信息汇聚到一起提供给员工使用。
所以各种厂商,包括像IBM、BEA和Oracle这样的巨头,都纷纷提供门户产品来简化这种任务。
每个数据源都显示在Web页面中的某个区域,有点像一个窗口——你可以关闭该区域、定制其行为或者与页面中的其他独立部分进行交互。
每个这种区域就称为portlet(门户组件)。
这些厂商都开发各自的API来编写工作于其门户产品中的portlet。
为了更容易地开发能够运行于不同门户中的portlet,JCP制定了portlet规范[Sun,Portlet],它已于2003年年末发布。
所有主要的门户厂商(包括Sun、BEA、IBM和Oracle)以及开源组织(如Apache软件基金)都宣布在其门户产品中支持该规范。
portlet规范定义了PortletAPI。
像ServletAPI一样,它定义了大量的底层细节,但是并没有简化UI开发或者屏蔽掉HTTP。
而那正是JSF的用武之地,JSF开发的目的在于能够与PortletAPI协作(它在很多方面都类似于ServletAPI)。
你可以在portlet中使用常规的JSF组件、事件处理和其他特征,就像在servlet中使用它们一样。
注解 贯穿本书,我们主要针对servlet讨论JSF。
同时,我们的大多数讨论也适合于portlet。
1.2.4 JavaBeans
相当一部分JavaWeb开发人员都以为JavaBeans就是这样一些类,它们具有一些可通过获取和设置方法(访问器和修改器)来暴露的属性。
例如,有个Java类,具有方法getName和setName,就表示它暴露了一个可读写的属性name。
然而,属性仅仅是其冰山一角,JavaBeans是一个完善的组件架构,其设计本身是为了工具支持。
这很重要。
因为这意味着对它来说除属性之外还有很多内容。
JavaBeans遵循一定的模式,以便其他Java类能够动态发现事件和除属性之外的其他一些元数据。
事实上,正是JavaBeans驱动了Swing技术,并使得IDE能够提供GUIbuilder来构建桌面应用和applet。
使用JavaBean,可以开发一个组件,使其不仅可以很精确地与可视化的GUIbuilder一起工作,还可以提供特定的向导(或者定制器)以引导用户完成配置流程。
JavaBean还包括一个强大的事件模型(与Swing和JSF组件所使用的一样)、持久化服务以及其他一些优雅的特征。
理解JavaBeans的强大之处将有助领会JSF的全部魔力。
与Swing组件一样,每个JSF组件都是一个全功能的JavaBean。
另外,设计Faces组件就是为了与后台bean(实现为JavaBean的对象,它可以处理事件)一起工作的。
如果只是计划编写应用代码或者构建UI,那么JavaBean的基本知识(修改器和访问器)已经足够。
如果想开发定制组件,对JavaBean的深入了解将会使开发工作更加容易。
1.2.5 JSP和其他显示技术
servlet对Web开发来说是很低阶的构建块,它们并不能充分地简化显示动态内容的任务。
你必须手动处理每一个请求的响应。
假定发送的每一行HTML都由一行Java代码来处理。
如果应用中有30个页面,每一个页面有80行HTML。
将有2400行类似于下面这样的语句:
这真是单调乏味的工作,特别是还不得不转义大量的字符,而且很难快速修改它们。
毫无疑问,必须要有更好的解决办法。
为了解决这个问题,Sun引入了JSP来作为标准的模板机制。
JSP看起来像是HTML页面,但是它具有可以进行定制处理或显示JavaBean属性值的特殊标签,而且还可以在其中嵌入Java代码[6]。
从根本上说,其行为类似于看起来极像上面所示的代码片段的servlet。
JSP翻译器承担了那些令人厌烦的工作,所以自己可以不必亲为。
你可以创建你自己的定制标签来执行额外的处理(比如访问数据库),并且已经有了很有用的标准标签集,称为JSP标准标签库(JSTL)[Sun,JSTL]。
这样,就可以通过类似于HTML的标签来定义UI,而不必使用Java代码。
虽然JSP是工业标准的显示技术,你还可以有很多其他选择。
可以完全使用扩展标记语言/扩展样式表语言转换(XML/XSLT)方法,使用如Cocoon[ASF,Cocoon]之类的框架,或者更为严谨的基于模板的方法,如Velocity[ASF,Velocity]或者WebMacro[WebMacro]。
还有其他更多的选择。
JSF的设计目标之一就是避免对某种显示技术的依赖。
所以JSF提供了可插入接口以允许开发人员将其集成到各种显示技术之中。
然而,因为JSF是标准的Java技术,并且JSP也是,所以毫不奇怪Faces推出时含有一个JSP实现(通过定制标签)。
并且因为JSP是唯一的必须与JSF集成的显示技术,所以本书的大部分例子都是使用JSP。
1.3 框架,框架,还是框架
先前说过,JSF是在Java中开发WebUI的框架。
近来好像框架非常流行,这有一个很好的原因:
它们能够使Web开发更加容易。
像大部分JavaWeb框架一样,JSF遵循业务逻辑和显示的分离。
并且,它更偏重于问题的UI那一侧,还可以和其他框架进行集成,比如Struts。
1.3.1 为什么使用框架
随着开发越来越多的Web应用,我们很明显了解到,虽然servlet和JSP非常有用,但它们处理很多常见的任务都需要大量烦琐的编程工作。
框架的目的就是简化这些任务。
其中最基本的任务是表单(form)处理。
HTML页面中有表单,它们是收集用户输入的控件集,比如文本框、查找列表、复选框等等。
当用户提交表单时,输入字段中的所有数据都发送给服务器。
HTML中的一个文本字段可能像这样:
在标准的servlet应用中,开发人员必须直接从HTTP请求中提取这些值:
如果有大量的表单,工作就会变得很烦琐。
因为你要直接处理这些发自浏览器的值,而且Java代码必须保证这些数据的有效性。
此外,每个值都必须手动地与应用的业务对象发生关联。
表单仅仅是JSP和servlet不能完全解决的任务中的一个例子。
Web应用必须管理大量的页面和图片,如果没有以一个中心化的管理方式来管理它们,在大型的应用中引用所有这些资源将是一场噩梦。
页面结构的管理是另一个问题。
虽然JSP提供了创建动态页面的机制,但它对于用多个较小的可重用的部件组合成一个页面的支持有限。
更有意思的是,servlet的处理居然不支持国际化、类型转换和错误处理。
为了以一种简单的方式来解决所有这些问题,出现了许多框架。
其中一些还非常流行,比如Struts[ASF,Struts]和WebWork[OpenSymphony,WebWork]。
这些框架的开发旨在解决以上这些常见问题。
1.3.2 它是模型2的
对大型Web应用来说,基本的组织和管理服务是必要的,但是它们也需要良好的结构。
大部分Web框架,包括JSF,都遵循模型—视图—控制器(MVC)设计模式的某种变体。
为了理解MVC,我们用驾驶来打个比方。
当你在高速路上向着一个方向前进时,通常在你和向反方向行驶的车辆之间有一个隔离带或者中线。
这里,设置隔离带是合理的,这使反方向快速移动的车辆不能混到你行驶方向的车流中来;否则,如果没有隔离带,轻微的事故也可能造成严重的后果。
应用也有相似的问题:
业务逻辑代码不能混合到UI代码之中。
当这两者混起来时,应用将难以维护,仅具有很小的伸缩性,并且通常更加脆弱。
此外,无法让一个团队从事UI表现代码,而另一个团队负责业务逻辑。
MVC是这种问题的标准解决方案。
当观看新闻的时候,你观看的是一个现实的版本。
对于某个实际事件,新闻频道会负责解释该事件并将其广播。
虽然你在电视上看到了节目,但是实际发生的事情,与做报道的记者的理解以及电视上看到的节目之间,可能截然不同。
新闻频道控制着电视节目(视图)与实际事件(模型)之间的交互。
即使你可能正在观看电视上的新闻,但同样的频道可能正通过因特网或者纸质的出版物传播。
这些视图都可以选择。
如果这些生产环节不是分离的,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JSF 实战