跳到导航
dev2dev.bea.com.cn
首页 资源中心 dev2dev学堂 在线技术论坛 专家Blog User Group CodeShare
dev2dev 首页 > 资源中心 > 技术文章
在WebLogic Workshop中使用ICEfaces入门

时间:2007-11-16
作者:Tom Stamm
浏览次数:
本文关键字:icefaces ajax weblogic workshop JSF 教程
文章工具
推荐给朋友 推荐给朋友
打印文章 打印文章

摘要

  ICEsoft的 ICEfaces 框架提供了一种开发支持Ajax的标准JavaServer Faces (JSF)应用程序的方法,并且不需要在客户端编写Javascript代码。本文简要介绍了如何在BEA WebLogic Workshop中使用ICEfaces增件工具。文章涵盖了ICEfaces工具的安装,如何创建支持ICEfaces的项目,以及如何使用ICEfaces和JSF轻松地创建支持Ajax的应用程序以显示输入数据。ICEfaces的本质是将Ajax功能添加到常规JSF编程模型中,因此阅读本文需要对JSF有一定的了解。

简介

  ICEfaces框架构建于JSF组件模型之上,它提供了一种以服务器为中心的开发方式,用于创建具有各种功能的Internet应用程序。在常规JSF组件的生命周期中,需要处理一些事件并创建一些组件,最终会在服务上创建一个HTML DOM用以呈现页面。使用ICEfaces时,服务器组件可以响应操作并只修改DOM中的一部分并将其呈现出来。然后,不必重新加载整个页面,经过修改的DOM部分将发回客户端,只有页面中相应的部分才会得到更新。这可以通过客户机发起的异步请求,或者通过服务器的“推送(push)”技术来实现。使用FireBug之类的Javascript调试程序,我们可以在这些更新过程中查看消息的来回传递情况。ICEfaces提供了所有核心JSF组件的实现,以及一些其他利用到异步更新的实现。在这篇教程中,我们将使用到一个选项卡控件、一个可以实现动态排序和分页的数据表格和一个模式弹出对话框。图1显示了最终完成的应用程序:

  在WebLogic Workshop中使用ICEfaces入门

  图1.示例用户数据表格

安装ICEfaces支持

  ICEfaces工具提供在WebLogic Workshop 10.1的一个更新中,必须通过一个Eclipse更新单独安装。为此,运行Workshop中的软件更新工具(可以在Help->Software Updates-> Find and Install中找到)。选择“Search for new features to install”并单击Next。单击New Remote Site并输入以下URL:http://dev2dev.bea.com/eclipse/icefaces-tooling/。确保选择的是新站点,然后单击Finish。在下一个向导中,确保选择了归档文件,然后单击Next。接受许可证条款并单击Next,然后单击Finish。然后会出现Feature Verification窗口,请单击Install All。更新完成之后,将弹出提示框询问是否重新启动Workshop以使改动生效。

  注意:由于这个更新加入了一个片断到已有插件中,因此Workshop必须使用-clean选项进行重启。可以在用于启动Workshop的命令行中加入这个选项,也可以将其添加到<BEA Home>/workshop_10.1/workshop4WP/workshop4WP.ini文件中的-vmargs一行前面。

创建一个支持ICEfaces的项目

  ICEfaces工具更新包含有一个WTP项目面(project facet),它将ICEfaces运行时库安装到一个项目中,并对项目的配置文件进行必要的修改。创建支持ICEfaces的项目最简单的方法是运行New Dynamic Web Project向导(选择File->New->Project...,然后选择Web/Dynamic Web Project作为项目名称)。输入项目名称,并在Configurations下拉菜单中选择ICEfaces Project或ICEfaces Project with WLS 10.0。后一个选项将使用WebLogic库模块完成所有处理,除了ICEfaces本身之外。单击Next查看面(facet)的选择,然后再单击Next查看各个库的选择。对于ICEfaces,我们需要单击Add...按钮并从BEA网站下载最新的ICEfaces库。最后,单击Finish创建项目。

  现在可以打开生成的web.xml,查看为支持ICEfaces所做的一些修改;尤为明显的是,其中添加了一些Persistent Faces Servlet和Blocking Servlet条目。这些条目分别可以提供服务器端的DOM呈现和ICEfaces运行时所使用的异步通信。其中还添加了一个映射,这样匹配模式*.iface的请求将路由到ICEfaces servlet而不是常规的JSF servlet。可以将*.iface更新为*.faces或*.jsf,并且可以移除Sun JSF servlet,从而所有面的请求都将使用ICEfaces进行处理。这篇教程将使用默认的配置和.iface扩展。

  ICEfaces还要求JSP在导入标记库时使用XML名称空间语法,而不是JSP的taglib导入命令。ICEfaces运行时无法解析JSP命令,因此如果遇到此类情况将抛出错误。比如说,新Web应用程序中的默认页面(/WebContent/pages/welcome.jsp)中含有以下打开标记:

<f:view xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ice="http://www.icesoft.com/icefaces/component">

  可以使用类似的方式导入其他的标记库。JSP编辑器目前只生成JSP taglib导入命令,因此如果要从调色板中还未导入的库中拖放某个标记出来,那么必须移除生成的导入命令并添加一个等价的XML名称空间声明。在这个项目中创建新JSP时,可以选择新JSP向导中的New ICEfaces JSP模板使用这种语法生成各种页面。

  至此,您可以运行/WebContent/index.jsp,该页面将重定向到/WebContent/pages/welcome.iface,因此会使用ICEfaces servlet执行欢迎页面。欢迎页面中的默认内容毫无新意可言,因此我们将添加一些其他的功能。

使用ICEfaces显示数据

  首先,我们需要添加数据表格。这与JSF数据表格极其类似,而且实际上ICEfaces的dataTable标记是JSF HTML dataTable标记的一个超集。然而,通过使用ICEfaces扩展和一些其他的标记,这个表格将具有排序和页面切换的特性,而不需要对整个页面进行更新。

  要支持这个示例的开发,首先我们必须将一些文件(下载 部分提供了imports.zip文件的下载)导入到项目中。在Project Explorer中右击该项目,打开Import->Import...选项并选择Archive File。在新出现的窗口中,浏览到imports.zip并选择所有的文件,确保Into Folder中的文本框显示的是正确的项目名称,然后单击Finish。这样会将beans和businessObjects导入到该项目的src目录中,并且一些样式表和图像导入到WebContent目录中。

  businessObjects包中的类是表示Customer数据的简单的POJO。beans.CustomerBean类将被注册为一个JSF bean,并提供了一些示例Customer数据和一些应用程序控制逻辑。在实际应用程序中,这个bean可以查询数据库中的Customer数据,不过此处我们是硬编码的。导入源代码之后,必须在面配置(faces configuration)文件中注册CustomerBean。为此,打开/WebContent/WEB-INF/config/faces-config.xml并右击Managed Beans,然后选择New Managed Bean。输入customers作为bean的名称,将作用域修改为session并输入beans.CustomerBean作为bean的类型。单击Finish,然后保存文件。

  现在,打开欢迎页面(/WebContent/pages/welcome.jsp)。对于这个示例,所有的功能都将包含在该页面中,与服务器的所有交互都将异步地执行,页面初次载入后就不再需要刷新。首先,删除body标记中的所有内容,这样我们便可以从一个空页面开始。对于使用ICEfaces小部件的页面,其样式表引用是一个关键因素:

<link href="./xmlhttp/css/xp/xp.css"
      rel="stylesheet"
      type="text/css" />

  这个样式表是ICEface运行时的一部分,用于为一些小部件提供默认的样式。由于它是运行时的一部分,因此我们不需要将它复制到各个ICEfaces Web应用程序中。大多数标记都有style和styleClass属性,因此我们可以覆盖其默认样式,但是这个示例仍然坚持使用默认样式。注意,应用程序还需要xmlhttp servlet的支持,它也是ICEfaces运行时的一部分。由于Workshop工具并不清楚这个servlet的访问权限,因此会弹出一个警告框提示无法找到样式表;我们可以安全地忽略这一点。

  这个应用程序的接口将有两个选项卡:一选项卡个用于显示数据,另一个选项卡包含一个用于添加数据的表单。ICEfaces panelTabSet标记提供了该表单的实现。panelTabSet标记必须封装在一个form标记中,因此首先从调色板的ICEfaces区域拖动一个form标记到页面上。这个表单不需要id或任何其他的属性。然后,将panelTabSet标记拖放到表单中。这时将弹出一个对话框。单击“Tab items”旁边的“...”按钮添加选项卡。我们将需要一个id标记为viewTab的View选项卡和一个id标记为addTab的Add选项卡。同时,设置样式类为componentPanelTabSetLayout。最终的结果类似于以下代码:

<ice:form>
      <ice:panelTabSet var=""
                         styleClass="componentPanelTabSetLayout">
            <ice:panelTab id="viewTab" label="View">
            </ice:panelTab>
            <ice:panelTab id="addTab" label="Add">
            </ice:panelTab>
      </ice:panelTabSet>
</ice:form>

  可以在各个选项卡中添加一些文本,然后运行页面查看运行是否正常。确保是将页面作为/pages/welcome.iface调用或者运行/index.jsp,从而可以确定是由ICEfaces servlet执行的。

  现在,我们将在第一个选项卡中添加一个数据表,该数据表将绑定后备bean(backing bean)所提供的Customer对象列表中的数据。表格中将包含一个可点击的头部,用于对数据进行排序,还有一个分页控件(paginator control)用于移动各页中的数据。最终结果可以从 下载 部分提供的project.zip文件中获得。可以将完整的项目导入执行过clean操作的工作空间中。要执行此操作,可以打开File->Import并选择“Existing Projects into Workspace”,然后使用“Select archive file”选项选择下载的zip文件。本节将带您了解该项目中的一些重点内容。

  要创建表格,请将dataTable标记拖放到tabset中的第一个选项卡上。这时会弹出一个表格对话框,选择customers JSF managed bean的customers属性为可枚举类型(enumerable),然后将迭代变量命名为“customer”。对话框将自动识别其类型为businessObjects.Customer。就是这个变量将在表格列中被引用。单击Next并选择要显示的first、id和last属性,然后单击Next对它们进行排序。这样将生成一个基本的表格,类似于一个无格式的JSF dataTable 。如果愿意的话,还可以选择显示一些地址属性。使用智能编辑器(smart editor)将表格的id设置为custTable、以便稍后引用,并将rows属性设置为5以避免一次显示太多行的数据。

  现在可以加入排序功能了。拖放一个commandSortHeader标记到id列的header facet中,调用列名称“id”并单击“arrow”复选框以指示排序的顺序。接下来,将带有列名称的outputText标记移动到commandSortHeader标记中。然后,对last列执行同样的步骤,并将其命名为“LastName”,这样表格将可以根据用户id和姓氏(last name)进行排序。ICEfaces要依靠后备bean才能启用排序功能;bean将跟踪哪一列中的数据需要排序,并能知道如何对基于该列的数据进行排序以及排序的方向。数据表格访问customers属性时,将返回一个预排序的列表。在本例中,bean只对一个内部列表进行了排序;如果执行的是数据库查询操作,则可以指定对查询结果进行排序。要实现这一目的,我们需要将数据表格中的sortColumn属性与后备bean中的sortColumnName属性绑定在一起。为此,可以在智能编辑器中单击各个属性旁边的按钮,并浏览到相应的bean属性。

  现在,表格内容类似于以下代码:

<ice:dataTable rows="5"

               value="#{customers.customers}"
               var="customer"
              id="custTable"
              sortColumn="#{customers.sortColumnName}"
              sortAscending="#{customers.sortAscending}">
  <h:column>
    <f:facet name="header">
      <ice:panelGroup>
        <ice:commandSortHeader columnName="id" arrow="true">
          <h:outputText value="Id"/>
        </ice:commandSortHeader>
      </ice:panelGroup>
    </f:facet>
    <h:outputText value="#{customer.id}"/>
  </h:column>
  <h:column>
    <f:facet name="header">
      <h:outputText value="First"/>
    </f:facet>
    <h:outputText value="#{customer.first}"/>
  </h:column>
  <h:column>
    <f:facet name="header">
      <ice:panelGroup>
        <ice:commandSortHeader columnName="LastName" arrow="true">
          <h:outputText value="Last"/>
        </ice:commandSortHeader>
      </ice:panelGroup>
    </f:facet>
    <h:outputText value="#{customer.last}"/>
  </h:column>
  ...
</ice:dataTable>

  视图选项卡中的最后一个组件将用于向表格中添加分页(pagination)。选择dataTable标记,然后在属性视图中将行数设置为5从而限制每页所显示的行数。接下来,拖动一个dataPaginator标记到数据表格下方。在对话框中,将For字段设置为表格的id(在本例中为custTable),然后选中Paginator筛选框(如果未选中这个筛选框,则该控件可用于显示“Page 1 of 12”之类的信息而不是支持切换页面的按钮)。单击Navigator属性旁边的“...”按钮可以为各个控件(first, next, last, previous)指定图像或文本。完成这些操作之后,标记内容将类似于以下代码:

<ice:dataPaginator id="custTableScroller"
                   for="custTable"
                   paginator="true">
  <f:facet name="first">
    <h:graphicImage style="border:none;"
                    url="/css/xp/css-images/arrow-first.gif"/>
  </f:facet>
  <f:facet name="previous">
    <h:graphicImage style="border:none;"
                    url="/css/xp/css-images/arrow-previous.gif"/>
  </f:facet>
  ...
</ice:dataPaginator>

  此处引用的图像是直接复制到Web应用程序中的,不过它也包含在运行时中并且可以作为./xmlhttp/css/xp/css-images/x.gif被引用。但是,Workshop JSP设计视图引用它时会有些问题,因为它不知道如何转换该路径并在运行时jar文件中找到该图像。因此我们将在示例中使用本地副本以保证设计视图可以正常运行。

  在WebLogic Workshop中使用ICEfaces入门

  图2.设计视图中的用户设计表格

  再重申一次,project.zip中含有完整的代码。现在,我们可以再次运行应用程序并验证一下排序和分页功能。

使用异步请求添加数据

  第二个选项卡将包含一个表单,用于向列表添加用户。对于本例而言,我们只需将用户添加到一个由后备bean维护的列表中,不过在实际应用程序中该数据将存储在数据库或一些其他的后备存储器中。要演示ICEfaces的异步特性,数据将以异步请求的方式发送,并且将显示出一个模式对话框通知用户新用户已添加。

  在tabset中的第二个选项卡中,拖放出一个panelGrid标记并将其设置为三行两列。列和行是隐藏的。panelGrid的子节点是一组panelGroup标记,行/列布局是根据方格(grid)中的列数目而决定的。在本例中,每行都需要有一个标签和一个文本框,对应于用户的姓氏(last name)和名称(first name)属性。通过绑定到customers.newCustomer.address.*属性,我们还可以添加更多行以表示新用户的地址。最后一行需要使用一个commandButton来真正保存数据:

<ice:panelGrid columns="2" width="100%">
  <ice:panelGroup>
    <f:verbatim>First Name:</f:verbatim>
  </ice:panelGroup>
  <ice:panelGroup>
    <ice:inputText value="#{customers.newCustomer.first}"/>
  </ice:panelGroup>
  <ice:panelGroup>
    <f:verbatim>Last Name:</f:verbatim>
  </ice:panelGroup>
  <ice:panelGroup>
    <ice:inputText value="#{customers.newCustomer.last}"/>
  </ice:panelGroup>
  <ice:panelGroup>
    <ice:commandButton
           actionListener="#{customers.customerSaved}"
           value="Add"/>
  </ice:panelGroup>
  <ice:panelGroup></ice:panelGroup>
</ice:panelGrid>

  Customers后备bean中有一个newCustomer属性,该属性是添加的Customer对象的占位符。此处的输入文本框与该对象的属性绑定在一起。后备bean还有一个动作监听方法customerSaved,单击命令按钮(command button)时将调用该方法。这样将会“保存”新用户,并重置newCustomer对象从而清除表单中的内容。

  在WebLogic Workshop中使用ICEfaces入门

  图3.设计视图中的用户输入表单

  现在,我们还需要实现通知用户新用户已添加的对话框。ICEfaces提供了一个panelPopup标记,该标记可以使用样式模拟常规HTML DOM中的对话框。它有一个visible属性,可以绑定后备bean属性中的数据。customers bean将公开一个此处可以使用的属性,当添加了一个用户时该属性将被设置为true;当对话框解除后该属性将重置为false。

  考虑到模式对话框的作用域,我们必须将其包含在它自己的form标记中。因此,首先在表单下面创建一个新表单用于封装数据表格。接下来,拖放一个panelPopup标记到该表单中。在属性视图中,将visible属性绑定到customers后备bean中的popupVisible属性。panelPopup使用了两个面(facet)——header和body——来设置对话框的标题栏和主体内容。在这两个面中加入消息,并在主体(body)中添加一个commandButton标记,用于调用后备bean中的closeNewCustomerPopup动作监听方法。其代码如下所示:

<ice:form>
  <ice:panelPopup visible="#{customers.popupVisible}"
                  modal="true">
    <f:facet name="header">
      <f:verbatim>Customer Added</f:verbatim>
    </f:facet>
    <f:facet name="body">
      <ice:panelGrid columns="1" width="100%">
      <ice:panelGroup>
        <ice:outputFormat
               value="Customer {0} {1} added with id {2}">
          <f:param value="#{customers.lastCustomer.first}"/>
          <f:param value="#{customers.lastCustomer.last}"/>
          <f:param value="#{customers.lastCustomer.id}"/>
        </ice:outputFormat>
      </ice:panelGroup>
      <ice:panelGroup>
        <ice:commandButton
               actionListener="#{customers.closeNewCustomerPopup}"
               value="Close"/>
      </ice:panelGroup>
      </ice:panelGrid>
    </f:facet>
  </ice:panelPopup>
</ice:form>

  设计视图中也将呈现该对话框,如图4所示。

  在WebLogic Workshop中使用ICEfaces入门

  图4.设计视图中的用户通知对话框

  再次运行应用程序,这时可以添加用户了,并且可以切换回第一个选项卡查看数据表格中的改动,而不需要刷新整个页面。图5显示了输入表单。

  在WebLogic Workshop中使用ICEfaces入门

  图5.运行时的用户输入表单

  添加一个用户后将出现图6所示的对话框。

  在WebLogic Workshop中使用ICEfaces入门

  图6.运行时的用户通知对话框

故障排除

  有一点值得谨记于心:由于ICEfaces在服务器中保存了一个可呈现的DOM(将会在JSF生命周期中更新),因此在迭代开发过程中这个DOM会比较难以同步。发生这种情况时,服务器会报错:非法的DOM层次结构请求。一般而言,可以重新发布应用程序,或者(如果该方法不起作用)重新启动服务器绕过这一错误。

  在进行ICEfaces开发时还有一点值得注意:即所有的JSP文件都是有效的XML格式。ICEfaces解析器将不会接受任何JSP指令。

  最后,使用JSF开发时通常需要确保使用适当的扩展名发起页面请求——在本例中为*.iface。如果使用*.jsp扩展名发起请求,那么将无法调用ICEfaces servlet,而且JSP也无法正确执行。

下载

  • imports——支持本教程示例所需的一组JSF后备bean 和样式表。可以直接将它们导入支持ICEfaces facet的Web项目中。要执行导入操作,请打开File->Import并选择“Archive File”。
  • project——完整的教程项目。可以将其导入执行过clean操作的工作空间中。要执行此操作,可以打开File->Import并选择“Existing Projects into Workspace”,然后使用“Select archive file”选项选择下载的zip文件。

结束语

  通过这个示例应用程序,我们了解了ICEfaces框架的一些基本功能。ICEfaces中还提供了许多其他的控件,并且还有很技巧(比如说部分表单提交)并没有在本文中介绍。

  要进一步熟悉ICEfaces,也可以使用一个无格式的JSF应用程序,将其中的JSF HTML标记替换为等价的ICEfaces标记。在一些情况下,这种简单的步骤可以赋予应用程序一些Ajax功能,而不需要额外的工作。ICfcs发行版中含有一些示例和教程,可以将它们导入Workshop内部支持ICEfaces的Web应用程序中。

参考资料

原文出处:http://dev2dev.bea.com/pub/a/2007/06/icefaces-workshop.html

dot dot dot

dot
  作者其它文章
您对本文的评价
您对这篇文章的看法如何?
太棒了!5分 不错啊 4分 一般般 3分 有待提高 2分 不好 1分

   
相关产品