悦's profileMy Digital StoryPhotosBlogListsMore Tools Help

Blog


    6/10/2008

    Javaserver Faces 简介 — 什么是 JSF?

    什么是 JSF?

    JavaServer Faces (JSF) 是一种用于构建 Web 应用程序的新标准 Java 框架。它提供了一种以组件为中心来开发 Java Web 用户界面的方法,从而简化了开发。JavaServer Faces 还引起了广大 Java/Web 开发人员的兴趣。“企业开发人员”和 Web 设计人员将发现 JSF 开发可以简单到只需将用户界面 (UI) 组件拖放到页面上,而“系统开发人员”将发现丰富而强健的 JSF API 为他们提供了无与伦比的功能和编程灵活性。JSF 还通过将良好构建的模型-视图-控制器 (MVC) 设计模式集成到它的体系结构中,确保了应用程序具有更高的可维护性。最后,由于 JSF 是通过 Java Community Process (JCP) 开发的一种 Java 标准,因此开发工具供应商完全能够为 JavaServer Faces 提供易于使用的、高效的可视化开发环境。

    JSF 体系结构

    JavaServer Faces 的 MVC 实现

    JSF 的主要优势之一就是它既是 Java Web 用户界面标准又是严格遵循模型-视图-控制器 (MVC) 设计模式的框架。用户界面代码(视图)与应用程序数据和逻辑(模型)的清晰分离使 JSF 应用程序更易于管理。为了准备提供页面对应用程序数据访问的 JSF 上下文和防止对页面未授权或不正确的访问,所有与应用程序的用户交互均由一个前端“Faces”servlet(控制器)来处理。

    图 1:JavaServer Faces 的 MVC 实现

    JSF 生命周期

    Faces Controller servlet 充当用户和 JSF 应用程序之间的纽带。它在明确限定的 JSF 生命周期(规定了用户请求之间的整个事件流)的范围内工作。例如,一收到访问 JSF 应用程序的初始 Web 请求,Faces Controller servlet 便通过首先准备 JSF 上下文(存放所有应用程序数据的一个 Java 对象)来处理请求。然后控制器把用户指引到所请求的页面。该页面通常使用简单的表达式语言来处理来自 JSF 上下文的应用程序数据。一收到后续请求,控制器就更新所有模型数据(假设输入了新数据)。JSF 开发人员可以通过编程的方式在应用程序运行期间随时访问整个 JSF 生命周期,从而可以随时对应用程序的行为进行高度控制。

    JavaServer Faces 的用户界面组件

    JavaServer Faces 的真正威力在于它的用户界面组件模型。在该模型中,应用程序完全用组件集合构建,这些组件可以针对多种客户端类型用不同的方式来进行显示。与其他专有技术(如 ASP.Net)有点类似,JSF 的 UI 组件模型技术使开发人员能够使用预先构建的用户界面 (UI) 组件来构建 Web 用户界面(而非完全从头构建用户界面),从而提供了前所未有的开发效率。JSF UI 组件有多种形式,可以简单到只是显示文本的 outputLabel,或者复杂到可以表示来自数据集合(如数据库表)的表格化数据的 dataTable

    JavaServer Faces 规范在其参考实施中提供了一组基本 UI 组件,这些组件本身是非常有用的。它们包括两个组件库,即“HTML”组件库 — 它大部分映射了标准的 HTML 输入元素;以及“核心”库 — 它辅助常见的应用程序开发任务(如,国际化和验证/转换输入数据)。除了提供一个基本 UI 组件库之外,JSF API 还提供了扩展和创建定制 JSF UI 组件的功能,从而在基本组件之上提供更多功能。

    其他用户界面组件库

    由于 JSF API 的丰富性和灵活性,许多 Java 开发人员开始创建新的 JSF 组件库和实现。Oracle 的 ADF Faces 是一个完全符合 JSF 规范的组件库,它为 JSF 应用程序开发提供了一组广泛的增强 UI 组件。这些组件包括针对每种客户端类型的多种呈现器、高级表格、颜色和日期选择器以及大量通用组件(如菜单、命令按钮、转移选择器和进度指示计)。

    图 2:Oracle 的 ADF Faces JSF UI 组件

    除了 Oracle 的 ADF Faces 之外,还有其他新的 JSF 组件库开始从开放源代码社区和软件供应商社区中出现。MyFaces 就是一个新 JSF UI 组件库的例子,它通过 Apache 作为一个开放源代码项目提供的。Myfaces 还是对 JSF 基本 UI 组件的增强,它拥有更广泛的 UI 功能,如集成的 Tiles 支持、支持 Javascript 的菜单和树控件。

    图 3:开放源代码的 MyFaces 实现和 UI 组件库

    JSF UI 组件的可插入呈现技术

    JSF UI 组件技术最引人注目一个方面就是它的可插入呈现功能。JSF UI 组件能够根据查看组件的客户端的类型来以不同方式呈现自身。例如,HTML 浏览器将看到特定 UI 组件的“HTML 浏览器友好”版本,而支持无线或 WAP 的微型设备将看到同一 UI 组件的“WML 友好”版本!JSF 通过解除 UI 组件与其呈现逻辑之间的耦合从而能够为同一 UI 组件创建多个呈现器实现了这一功能。不同的呈现器可以与 UI 组件相关联,在运行时 UI 组件可以根据请求的客户端类型决定使用哪个呈现器。

    图 5:一个 ADF Faces 表格组件针对无线客户端和 HTML 客户端进行了不同的呈现

    还应当指出的是,由于 JSF 的可插入呈现功能,使得 JSF UI 组件能够显示任何类型的数据,无论它是标记数据(如 HTML、XML、WML 等)还是二进制数据。例如,UI 组件还可以显示二进制数据,如图像流或不同的文档类型,如 SVG、PDF 和 Word。

    一个新的 JSF 组件开发人员社区

    随着 JSF 开发人员和拥护者社区的不断壮大,现在有几个网站致力于进一步推动独立的 JSF 开发。JSFCentral 就是一个完全为 JSF 开发社区服务的新网站。它包含 JSF 技术信息、产品/组件信息以及大量与 JSF 相关的文章。

    图 4:JSFCentral — 一个免费的 Javaserver Faces 社区

    (JSFCentral 的地址是:http://jsfcentral.com

    JSF 开发工具

    因为 JavaServer Faces 是一种标准的 Java 技术,因此软件开发工具完全能够为 JavaServer Faces 提供高级的集成开发工具支持。多个供应商现在不同程度地支持 JSF 开发,这大大提高了 JSF 的易用性和功能。Oracle、Sun、Borland 和 IBM 都为 JavaServer Faces 提供了开发环境。由于开发工具供应商在竞相提供更好、更简单和更多的开发环境,因此基于 IDE 的 JSF 开发拥有美好的前景!

    图 6:Oracle 的 JDeveloper 提供高效、可视化的 JSF 开发体验

    总结

    JavaServer Faces 通过提供模型-视图-控制器设计模式的一个简洁实现,同时在不牺牲开发能力和灵活性的前提下提供高效的以组件为中心的开发,解决了 Java Web 开发的许多历史问题。此外,因为 JSF 是一种 Java 标准,因此多个软件供应商将继续提供始终高效的开发环境,这些开发环境毫无疑问将达到或很可能超过专有的可视化开发环境。请继续关注!

    BEA , WebLogic , Workshop 是什么? JSTL是什么?

    BEA 是个美国公司 , 做JAVA中间件产品.
    WebLogic是 BEA 的一个JAVA应用服务器的产品,类似于TOMCAT.
    Workshop是BEA的一个JAVA IDE产品, 类似于Eclipse.
    JSTL , JSP 标准标记库(JSP Standard Tag Library,JSTL)是一个实现 Web 应用程序中常见的通用功能的定制标记库集,这些功能包括迭代和条件判断、数据管理格式化、XML 操作以及数据库访问。

    BEA WebLogic是用于开发、集成、部署和管理大型分布式Web应用、 网络应用和数据库应
    用的Java应用服务器。将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的
    开发、集成、部署和管理之中。

      BEA WebLogic Server具有开发和部署关键任务电子商务Web应用系统 所需的多种特色和优
    势,包括:
      1)领先的标准
      对业内多种标准的全面支持,包括EJB、JSB、JMS、JDBC、XML和WML,使Web应用系统的实
    施更为简单,并且保护了投资,同时也使基于标准的解决方案的开发更加简便。
      2)无限的可扩展性
      BEA WebLogic Server以其高扩展的架构体系闻名于业内,包括客户机连接的共享、资源
    pooling以及动态网页和EJB组件群集。
      3)快速开发
      凭借对EJB和JSP的支持,以及BEA WebLogic Server 的Servlet组件架 构体系,可加速投
    放市场速度。这些开放性标准与WebGain Studio配 合时,可简化开发,并可发挥已有的技能,
    迅速部署应用系统。
      4)部署更趋灵活
      BEA WebLogic Server的特点是与领先数据库、操作系统和Web服务器 紧密集成。
      5)关键任务可靠性
      其容错、系统管理和安全性能已经在全球数以千记的关键任务环境中得以验证。
      6)体系结构 
      BEA WebLogic Server是专门为企业电子商务应用系统开发的。企业电 子商务应用系统需
    要快速开发,并要求服务器端组件具有良好的灵活性和安全性,同时还要支持关键任务所必需
    的扩展、性能、和高可用性。BEA WebLogic Server简化了可移植及可扩展的应用系统的开发,
    并为其它应用 系统和系统提供了丰富的互操作性。
      凭借其出色的群集技术,BEA WebLogic Server拥有最高水平的可扩展 性和可用性。BEA
    WebLogic Server既实现了网页群集,也实现了EJB组件 群集,而且不需要任何专门的硬件或
    操作系统支持。网页群集可以实现透明的复制、负载平衡以及表示内容容错,如Web购物车;
    组件群集则处理复杂的复制、负载平衡和EJB组件容错,以及状态对象(如EJB实体)的恢复。
    无论是网页群集,还是组件群集,对于电子商务解决方案所要求的可扩展性和可用性都是至关
    重要的。共享的客户机/服务器和数据库连接以及数据缓存和EJB都增强了性能表现。这是其它
    Web应用系统所不具备的。
    3/16/2008

    java里抽象类和接口的区别

    下面的这篇文章讲的十分透彻了,所以转载之
    abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力。abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于abstract class和interface的选择显得比较随意。其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意图的理解是否正确、合理。本文将对它们之间的区别进行一番剖析,试图给开发者提供一个在二者之间进行选择的依据。 
    理解抽象类 
    abstract class和interface在Java语言中都是用来进行抽象类(本文中的抽象类并非从abstract class翻译而来,它表示的是一个抽象体,而abstract class为Java语言中用于定义抽象类的一种方法,请读者注意区分)定义的,那么什么是抽象类,使用抽象类能为我们带来什么好处呢? 
    在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。 
    在面向对象领域,抽象类主要用来进行类型隐藏。我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。熟悉OCP的读者一定知道,为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。 
    从语法定义层面看abstract class和interface 
    在语法层面,Java语言对于abstract class和interface给出了不同的定义方式,下面以定义一个名为Demo的抽象类为例来说明这种不同。 
    使用abstract class的方式定义Demo抽象类的方式如下: 
    abstract class Demo { 
    abstract void method1(); 
    abstract void method2(); 
    … 
    } 
    使用interface的方式定义Demo抽象类的方式如下: 
    interface Demo { 
    void method1(); 
    void method2(); 
    … 

    在abstract class方式中,Demo可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface方式的实现中,Demo只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。从某种意义上说,interface是一种特殊形式的abstract class。 
          从编程的角度来看,abstract class和interface都可以用来实现"design by contract"的思想。但是在具体的使用上面还是有一些区别的。 
    首先,abstract class在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。也许,这是Java语言的设计者在考虑Java对于多重继承的支持方面的一种折中考虑吧。 
    其次,在abstract class的定义中,我们可以赋予方法的默认行为。但是在interface的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会 增加一些复杂性,有时会造成很大的麻烦。 
    在抽象类中不能定义默认行为还存在另一个比较严重的问题,那就是可能会造成维护上的麻烦。因为如果后来想修改类的界面(一般通过abstract class或者interface来表示)以适应新的情况(比如,添加新的方法或者给已用的方法中添加新的参数)时,就会非常的麻烦,可能要花费很多的时间(对于派生类很多的情况,尤为如此)。但是如果界面是通过abstract class来实现的,那么可能就只需要修改定义在abstract class中的默认行为就可以了。 
    同样,如果不能在抽象类中定义默认行为,就会导致同样的方法实现出现在该抽象类的每一个派生类中,违反了"one rule,one place"原则,造成代码重复,同样不利于以后的维护。因此,在abstract class和interface间进行选择时要非常的小心。 
    从设计理念层面看abstract class和interface 
    上面主要从语法定义和编程的角度论述了abstract class和interface的区别,这些层面的区别是比较低层次的、非本质的。本小节将从另一个层面:abstract class和interface所反映出的设计理念,来分析一下二者的区别。作者认为,从这个层面进行分析才能理解二者概念的本质所在。 
    前面已经提到过,abstarct class在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is a"关系,即父类和派生类在概念本质上应该是相同的(参考文献〔3〕中有关于"is a"关系的大篇幅深入的论述,有兴趣的读者可以参考)。对于interface 来说则不然,并不要求interface的实现者和interface定义在概念本质上是一致的,仅仅是实现了interface定义的契约而已。为了使论述便于理解,下面将通过一个简单的实例进行说明。 
    考虑这样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示: 
    使用abstract class方式定义Door: 
    abstract class Door { 
    abstract void open(); 
    abstract void close(); 

    使用interface方式定义Door: 
    interface Door { 
    void open(); 
    void close(); 

    其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。看起来好像使用abstract class和interface没有大的区别。 
    如果现在要求Door还要具有报警的功能。我们该如何设计针对该例子的类结构呢(在本例中,主要是为了展示abstract class和interface反映在设计理念上的区别,其他方面无关的问题都做了简化或者忽略)?下面将罗列出可能的解决方案,并从设计理念层面对这些不同的方案进行分析。 
    解决方案一: 
    简单的在Door的定义中增加一个alarm方法,如下: 
    abstract class Door { 
    abstract void open(); 
    abstract void close(); 
    abstract void alarm(); 

    或者 
    interface Door { 
    void open(); 
    void close(); 
    void alarm(); 

    那么具有报警功能的AlarmDoor的定义方式如下: 
    class AlarmDoor extends Door { 
    void open() { … } 
    void close() { … } 
    void alarm() { … } 

    或者 
    class AlarmDoor implements Door { 
    void open() { … } 
    void close() { … } 
    void alarm() { … } 
    } 
    这种方法违反了面向对象设计中的一个核心原则ISP(Interface Segregation Priciple),在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为"报警器"这个概念的改变(比如:修改alarm方法的参数)而改变,反之依然。 
    解决方案二: 
    既然open、close和alarm属于两个不同的概念,根据ISP原则应该把它们分别定义在代表这两个概念的抽象类中。定义方式有:这两个概念都使用abstract class方式定义;两个概念都使用interface方式定义;一个概念使用abstract class方式定义,另一个概念使用interface方式定义。 
    显然,由于Java语言不支持多重继承,所以两个概念都使用abstract class方式定义是不可行的。后面两种方式都是可行的,但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。我们一一来分析、说明。 
    如果两个概念都使用interface方式来定义,那么就反映出两个问题:1、我们可能没有理解清楚问题领域,AlarmDoor在概念本质上到底是Door还是报警器?2、如果我们对于问题领域的理解没有问题,比如:我们通过对于问题领域的分析发现AlarmDoor在概念本质上和Door是一致的,那么我们在实现时就没有能够正确的揭示我们的设计意图,因为在这两个概念的定义上(均使用interface方式定义)反映不出上述含义。 
    如果我们对于问题领域的理解是:AlarmDoor在概念本质上是Door,同时它有具有报警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢?前面已经说过,abstract class在Java语言中表示一种继承关系,而继承关系在本质上是"is a"关系。所以对于Door这个概念,我们应该使用abstarct class方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行为,所以报警概念可以通过interface方式定义。如下所示: 
    abstract class Door { 
    abstract void open(); 
    abstract void close(); 

    interface Alarm { 
    void alarm(); 

    class AlarmDoor extends Door implements Alarm { 
    void open() { … } 
    void close() { … } 
        void alarm() { … } 

    这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。其实abstract class表示的是"is a"关系,interface表示的是"like a"关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有Door的功能,那么上述的定义方式就要反过来了。