内容


使用 JavaServer Faces 构建 Apache Geronimo 应用程序,第 3 部分

使用 ajax4jsf 添加 Ajax 功能

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: 使用 JavaServer Faces 构建 Apache Geronimo 应用程序,第 3 部分

敬请期待该系列的后续内容。

此内容是该系列的一部分:使用 JavaServer Faces 构建 Apache Geronimo 应用程序,第 3 部分

敬请期待该系列的后续内容。

开始之前

本教程向 Java 程序员讲解如何使用 JSF 组件构建高度交互性的部署在 Apache Geronimo 上的 Java EE 应用程序。本教程假设读者将使用 Eclipse IDE 作为开发平台。

关于本教程

本教程讲解 Sun Ajax4jsf 开放源码框架,这个框架为 JSF 应用程序添加 Ajax 功能,而无需编写任何 JavaScript 代码。我们将继续改进 第 2 部分 开发的示例应用程序,增加一个对温度进行转换并以图形化方式显示结果的实用程序。

关于本系列

本教程是关于使用 JSF 构建 Apache Geronimo 应用程序的分五部分的教程系列的第 3 部分。整个系列教程包括以下几个部分:

  • 第 1 部分:使用 Eclipse 和 Apache MyFaces Core 构建基本的应用程序 介绍如何使用 JSF 标准的 Apache MyFaces 实现以及 Geronimo(一种也是来自 Apache 的免费应用服务器)。这个教程讲解如何使用 Eclipse IDE 的 Web Tool Platform(WTP)来构建 JSF 应用程序。
  • 第 2 部分:在 JavaServer Faces 中使用 Tomahawk 展示如何在 Geronimo 应用程序中集成 Apache Tomahawk。Tomahawk 提供了几个与 JSF 100% 兼容的定制组件。
  • 第 3 部分:在 JavaServer Faces 中使用 ajax4jsf 演示如何使用 Sun 的免费开放源码框架 ajax4jsf 在 Geronimo 应用程序中添加 Asynchronous JavaScript + XML(Ajax)功能。
  • 第 4 部分:使用 Application Development Framework(ADF)Faces 扩展 JSF 讲解怎样将 ADF Faces 中的组件集成到 Geronimo 应用程序中。Oracle 的 ADF Faces 是构建于 JSF 之上的一组非常丰富的 UI 组件(它是用 Trinidad 这个名称捐献给 Apache 的代码的一部分)。
  • 第 5 部分:将 JSF 应用程序与 Spring 集成 展示如何将 JSF 应用程序与 Spring 框架集成。Spring 是一个流行的框架,它使 Geronimo 开发者能更容易地构建 Java EE 应用程序。

系统需求

为了学习本教程,需要有下列工具:

  • 第 2 部分 源代码,我们将对这个应用程序进行改进。
  • Geronimo,Apache 的 Java EE 服务器项目。根据需要,Geronimo 提供 Tomcat 和 Jetty 两种风格。我们采用的是 Jetty 风格(1.1 版),因为它小一点儿。
  • MyFaces,Apache 的 JSF 实现。请从 Apache 下载核心版本(不带 Tomcat)。本教程中使用的版本是 1.1.3 版。
  • Tomahawk,它提供用于 MyFaces 的额外组件和输入验证器,同时与 JSF 100% 兼容。
  • Eclipse,这是一个可支持大量语言和平台的可扩展开放源码 IDE。
  • Eclipse Web Tools Platform(WTP),它给 Eclipse 添加了对 XML 和 JavaScript 编辑的支持以及对 JSF 的基本支持。
  • Ajax4jsf,这是 Sun 的开放源码框架,用于在现有的 JSF 应用程序中添加 Ajax 功能。在编写本文时的当前版本是 1.0rc4。
  • Java 1.4 或更新版本 安装到您的系统中。Eclipse 二进制文件中带有自己的 Java 运行时,但 Geronimo 和 MyFaces 则没有(带运行时会使下载归档文件的尺寸显著变大)。

Ajax4jsf —— 概述

Ajax4jsf 允许开发人员将 Ajax 功能添加到 JSF 应用程序中,而不需要 JavaScript 或用 Ajax 图形部件替换现有的组件。这个包还允许在使用 Java 2D 库时动态地生成图像。Ajax 是一种编程技术,它处理只有页面的一部分需要处理而不需要重新装载整个页面的情况。这种方式的好处包括减少服务器上的处理时间以及加快客户端的响应速度。

与 Tomahawk 相似,Ajax4jsf 提供了一套可以很容易地与 JSF 标记一起使用的标记。在本教程后面对 Developer Forum Signup 示例应用程序进行改进时,将讨论这些标记的示例以及如何将 Ajax4jsf 与 Eclipse 进行集成。接下来,将学习组成这个库的每个组件、在使用它时必须记住的限制以及如何在 Eclipse 项目中添加 Ajax4jsf。

组件

Ajax4jsf 组件被设计成可以轻松地与现有的 JSF 应用程序进行集成,同时提供了改进性能的 Ajax 功能。表 1 中描述了 Ajax4jsf 库中包含的所有标记。

表 1. Ajax4jsf 库标记
Ajax4jsf 组件描述
<a4j:actionListener>其效果类似于 JSF 中的 <f:actionListener><f:valueChangeListener> 标记,但是它用于 Ajax 容器。
<a4j:actionparam>结合了 <f:actionListener><f:param> JSF 标记的功能。
<a4j:commandButton>效果类似于被点击时的表单 Submit 按钮,但是呈现为 HTML <input> 标记。
<a4j:commandLink>效果类似于被点击时的表单 Submit 按钮,但是呈现为 HTML <a> 锚标记。
<a4j:loadBundle>装载当前视图的本地化资源束。
<a4j:mediaOutput>允许创建动态生成的内容。
<a4j:outputPanel>在页面上创建一个启用 Ajax 的部分,允许这个区域中的内容重新呈现(即使导致 Ajax 请求的组件没有专门提到这个区域)。
<a4j:page>呈现完整的 HTML 页面结构。但是,它必须是 JSF <f:view> 标记的第一个和惟一的子元素,在它外边不能有 HTML 代码。
<a4j:region>决定 JSF <f:view> 的哪个部分将通过为相关联的 Ajax 请求提供内容来处理。这会只更新页面中需要更新的部分,从而改进性能。
<a4j:status>通过指出请求何时开始或结束,提供关于指定区域的 Ajax 请求的客户端状态。
<a4j:support>将 Ajax 功能添加到与 JSF 相关的组件中。这个标记可能是最常用的。

根据场景,某些组件会比其他组件更常用。接下来,将学习在使用 Ajax4jsf 时必须记住的条件。

条件

根据 Ajax4jsf 文档所述,开发人员必须记住某些限制才能创建正确的 Ajax 和 JSF 应用程序:

  • Ajax4jsf 框架并不在页面上追加或删除元素,它只会替换页面上的元素。要想在页面上追加代码,应该使用一个空元素标出它的位置。
  • 应该只创建严格的符合标准的 HTML 和 XHTML 代码,不要省略任何必需的元素或属性,因为 Ajax 请求由 XMLHttpRequest 函数以 XML 格式创建。但是,这些请求的 XML 格式可能会避开浏览器中的大多数检验和任何纠正处理。
  • 最后,大多数 Ajax4jsf 标记有一个属性,它指定在发出 Ajax 请求之后要处理的元素的 ID。这些元素的 ID 必须匹配在 Ajax4jsf 标记的属性中指定的 ID,只有这样更新才会成功。

既然已经了解了组件和使用 Ajax4jsf 的条件,就需要将这个库添加到 Eclipse 项目中,然后才能对 Developer Forum Signup 应用程序进行改进。

将 Ajax4jsf 添加到 Eclipse 项目中

本教程中的 第 2 部分 介绍了将 Tomahawk 作为 JSF 组件库添加进项目中的步骤。使用同样的步骤将 Ajax 作为 JSF 组件库添加进项目中。

  1. 右击 devSignup 项目,并在上下文菜单中选择 Properties。Eclipse 显示 Properties 对话框,见 图 1
图 1. devSignup 的 Properties 对话框
devSignup 的 Properties 对话框
devSignup 的 Properties 对话框
  1. 访问 JSF Library References 面板,见 图 2
图 2. JSF Library References 面板
JSF Library References 面板
JSF Library References 面板
  1. 点击面板中间偏下的 Component Libraries 部分中的 New 按钮,显示 Create JSF Library 对话框(见 图 3)。
  2. Library Name 字段中输入库名(例如,Ajax4jsf)。
图 3. Create JSF Library 窗口
Create JSF Library 窗口
Create JSF Library 窗口
  1. 点击 Add 按钮,然后选择发布版存档中的以下 Ajax4jsf JAR:
    • ajax4jsf.jar
    • oscache-2.3.2.jar
  2. 根据需要重复这个步骤。
  3. 点击 Finish 将新的 Ajax4jsf 库添加到项目 Properties 的 JSF Library References 面板中的列表中。这个新的 Ajax4jsf 库添加到右边的列表中,它会自动地包含在项目的 .war 文件中。现在对话框应该与 图 4 相似。
  4. 点击 OK 应用修改并关闭项目 Properties 对话框。
图 4. Ajax4jsf 和 Tomahawk 作为组件库列出
Ajax4jsf 和 Tomahawk 作为组件库列出
Ajax4jsf 和 Tomahawk 作为组件库列出

为了启用 Ajax4jsf 组件,必须在应用程序的 web.xml 文件中声明相应的 <filter> 标记。

  1. 打开 devSignup 项目下面的 WebContent/WEB-INF/web.xml。如果编辑器仍然处于 Design 模式,那么必须点击编辑器底部的 Source 选项卡,切换到 Source 模式。
  2. 清单 1 中的代码添加到 web.xml 文件中。<filter><filter-mapping> 元素应该是 <web-app> 元素的子元素。
清单 1. 在 web.xml 中启用 Ajax4jsf 组件
	<filter>
		<display-name>Ajax4jsf Filter</display-name>
		<filter-name>ajax4jsf</filter-name>
		<filter-class>org.ajax4jsf.Filter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>ajax4jsf</filter-name>
		<servlet-name>Faces Servlet</servlet-name>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>INCLUDE</dispatcher>
	</filter-mapping>

一定要将 <filter><filter-mapping> 标记放在 web.xml 文件中其他任何过滤器的前面。根据文档所述,必须这样做才能防止 web.xml 中其他任何过滤器与 Ajax4jsf 冲突。

<filter> 元素仅仅声明 Ajax4jsf 过滤器类。<filter-mapping> 元素将 Ajax4jsf 过滤器与这个文件中其他地方声明的 Faces Servlet 关联起来。

既然已经在项目中添加并配置了 Ajax4jsf,就可以开始改进 Developer Forum Signup 应用程序了。下一节通过讨论 Temperature Conversion 实用程序的细节来讨论这个问题。

Temperature Conversion 实用程序

对于在 Developer Forum 应用程序中登录后的成员,提供 Temperature Conversion 实用程序作为实际功能。这个实用程序将温度从摄氏温度转换为华氏温度,或者相反。每种温度转换的结果显示为一个动态生成的温度计图像。首先,学习如何用 Ajax4jsf 实现这个用户界面。然后,看看实现这个实用程序的 bean。

使用 Ajax4jsf 实现温度转换器页面

本系列的 第 2 部分 扩展了 Developer Forum Signup 应用程序,添加了字段验证器和弹出式日历来帮助用户选择生日。这些改进都集中在注册页面上。现在,将创建一个新页面,它允许用户输入摄氏或华氏温度,然后就会看到转换后的温度显示为数字和图像。

首先,需要提供一个链接,它允许成员在成功登录之后访问这个实用程序。更新后的 signup-success.jsp 页面使用与 清单 2 相似的一行代码提供这个链接。

清单 2. 更新后的 signup-success 页面的部分清单
*New* The Temperature Converter is 
<a href="temperature-converter.faces">here</a>!

这个清单中惟一有意思的东西是温度转换器页面的扩展名。在 Eclipse 中,这个文件实现为 JSP。当部署这个页面时,必须用 .faces 扩展名引用它,从而让 Faces Servlet 处理它。

现在看看温度转换器页面的实现。清单 3 中给出这个页面的部分清单。

清单 3. temperature-converter.jsp 的部分清单
<%@ taglib uri="https://ajax4jsf.dev.java.net/ajax" prefix="a4j"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Temperature Converter</title>
</head>

<body>
<h1>Temperature Converter</h1>
<hr/>
<p>The Temperature Converter is provided as a benefit for our
members in the Developer Forum!</p>

<f:view>
<a4j:region id="CtoF" selfRendered="true">

<a4j:mediaOutput element="img" cacheable="false" session="true"
 createContent="#{temperature.drawFahrenheitThermometer}"
 value="#{thermometer}" mimeType="image/jpeg" />

<a4j:status startText="Processing..." stopText="" for="CtoF"/>

<h:form>
<h:panelGrid columns="2">
	<h:outputText value="Temperature in Fahrenheit:" />
	<h:outputText id="tempFahr"
 value="#{temperature.outputFahrenheit}"/>

	<h:outputText value="Temperature in Celsius:" />
	<h:inputText size="5" value="#{temperature.inputCelsius}">
		<a4j:support event="onkeyup" reRender="tempFahr" />
	</h:inputText>
	</h:panelGrid>
</h:form>
</a4j:region>

</f:view>

<hr/>

<p>Thank you for using the Temperature Converter!</p>
</body>
</html>

这个 JSP 清单中有几个有意思的元素。第一个是开头的 a4j <taglib> 声明。对于任何使用 Ajax4jsf 组件库的 JSP,这个声明都是必需的。

<a4j:region> 标记声明 Ajax 区域的开头和结尾。selfRendered 属性设置为 true,这意味着当发出相关联的 Ajax 请求时将处理这个区域。

<a4j:mediaOutput> 标记允许创建动态生成的内容,在这个示例中就是反映转换后的华氏温度的温度计图像。createContent 属性指定负责创建此内容的 bean 方法。value 属性指定一个对象,这个对象包含着 createContent 中的 bean 方法所需的数据。注意,value 中的数据对象必须实现 java.io.Serializable 类。

<a4j:status> 标记提供 Ajax 请求的客户端状态。当请求开始时,显示消息 "Processing..."。当请求停止时,不显示消息。for 属性将这个状态与指定的 ID 关联起来。这正好是前面定义的 "CtoF" 区域。

最后,<a4j:support> 标记将 Ajax 支持添加到 JSF <h:inputText> 标记中。event 属性指出哪个 JavaScript 事件将触发 Ajax 请求。reRender 属性包含在发出请求之后将重新呈现的对象的 ID 列表。在这个示例中,当用户输入摄氏温度值时,在每次释放键盘键之后,发出一个 Ajax 请求,从而用转换后的华氏温度重新呈现匹配的 JSF <h:outputText> 标记。图 5 给出页面的样子。

图 5. 运行时的 Temperature Conversion 实用程序
运行时的 Temperature Conversion 实用程序
运行时的 Temperature Conversion 实用程序

这就是在温度转换器页面上使用 Ajax 的方式。正如 清单 3 所示,这个库提供的组件很容易与 JSF 标记进行集成。接下来,研究一下处理实际温度转换和图像创建的代码。

温度转换器 bean

温度转换器 bean 是实现 Temperature Conversion 实用程序的模块。负责进行温度转换和图像创建的所有方法都保存在 TemperatureConverter.java 文件中。下面几个清单给出令人感兴趣的几个方法,首先是 清单 4

清单 4. 对输入的温度进行转换
    public void setInputCelsius(String inputCelsius)
    {
        Float tmpCelsius = null;

        this.inputCelsius = inputCelsius;

        // convert C to F
        tmpCelsius = new Float(inputCelsius);
        fahrenheitValue = new Float(celsiusToFahrenheit(tmpCelsius.floatValue()));

        setOutputFahrenheit(fahrenheitValue.toString());
    } // end setInputCelsius

    
    public void setInputFahrenheit(String inputFahrenheit)
    {
        Float tmpFahrenheit = null;

        this.inputFahrenheit = inputFahrenheit;

        // convert F to C
        tmpFahrenheit = new Float(inputFahrenheit);
        celsiusValue = new Float(fahrenheitToCelsius(tmpFahrenheit.floatValue()));

        setOutputCelsius(celsiusValue.toString());
    } // end setInputFahrenheit

当用户在温度转换器页面上的文本字段中输入一个值之后,会调用对应的 set 方法。这些方法调用代码来转换对应的温度并相应地设置输出值。清单 5 给出实际的转换公式。

清单 5. 包含转换公式的支持方法
private float celsiusToFahrenheit(float celsius)
{
    float fahrenheit = 0.0f;
    fahrenheit = ((9.0f / 5.0f) * celsius) + 32.0f;
    System.out.println("celsius: " + celsius + "\tfahrenheit: "
                + fahrenheit);
    return fahrenheit;
} // end celsiusToFahrenheit

    
private float fahrenheitToCelsius(float fahrenheit)
{
    float celsius = 0.0f;
    celsius = (5.0f / 9.0f) * (fahrenheit - 32.0f);
    System.out.println("fahrenheit: " + fahrenheit + "\tcelsius: "
                + celsius);
    return celsius;
} // end fahrenheitToCelsius

这两个方法相当简单明了。输入一个温度,输出转换后的温度。System.out.println 语句在启动时显示的 Geronimo 控制台上显示字符串。这适合进行快速调试,但是真正的日志记录实用程序适合更复杂的应用程序。清单 6 包含负责创建华氏温度计图像的方法。

清单 6. 生成华氏温度计图像的方法
    public void drawFahrenheitThermometer(OutputStream out, Object object)
        throws IOException
    {
        BufferedImage thermometerImage = null;
        Graphics2D image = null;
        Thermometer thermometer = null;

        if (object instanceof Thermometer)
        {
            thermometer = (Thermometer) object;
        }
        else
        {
            return;
        } // end if
        
        thermometerImage = new BufferedImage(
                thermometer.getWidth().intValue(),
                thermometer.getHeight().intValue(),
                BufferedImage.TYPE_INT_RGB);

        image = thermometerImage.createGraphics();
        image.setBackground(thermometer.getThermometerColor());
        image.clearRect(0, 0, thermometer.getWidth().intValue(),
                thermometer.getHeight().intValue());

        drawMercury(fahrenheitValue, thermometer, image);
        drawThermometerUnits(thermometer, image);

        ImageIO.write(thermometerImage, "jpeg", out);
    } // end drawFahrenheitThermometer

这就是在 <a4j:mediaOutput>createContent 属性中指定的方法。它需要两个参数,而且 Object 类型的第二个参数必须实现 java.io.Serializable。这个方法使用标准的 Java 2D 图形库来创建温度计图像。尺寸存储在数据对象 thermometer 中。drawMercurydrawThermometerUnits 方法见 清单 7

清单 7. 绘制刻度和更新水银柱的支持方法
private void drawThermometerUnits(Thermometer thermo, Graphics2D image2D)
{
    Integer tmpInteger = null;
    int blockCounter = 0;
    int textCounter = 0;
    int unitCounter = 0;

    for (int x = 0; x < thermo.getWidth().intValue(); x++)
    {
        if (x == blockCounter)
        {
            image2D.drawLine(x,0,x,30);
            tmpInteger = new Integer(textCounter);

            image2D.setColor(thermo.getThermometerTextColor());
            image2D.drawChars(tmpInteger.toString().toCharArray(),
                0, tmpInteger.toString().length(), x, 45);

            blockCounter = blockCounter + BLOCK_INCREMENT;
            textCounter = textCounter + TEXT_INCREMENT;
            unitCounter = unitCounter + UNIT_INCREMENT;
        }
        else if (x == unitCounter)
        {
            image2D.drawLine(x, 0, x, 10);
            unitCounter = unitCounter + UNIT_INCREMENT;
        } // end if
    } // end for
} // end drawThermometerUnits


private void drawMercury(Float temperature, Thermometer thermo, Graphics2D image2D)
{    
    int mercuryValue = 0;

    if (temperature == null)
    {
        temperature = new Float(0.0f);
    } // end if

    // Scale temperature to thermometer units in image2D
    mercuryValue = temperature.intValue() * SCALE_TEMP;
    image2D.setColor(thermo.getMercuryColor());
    image2D.fill3DRect(0, 11, mercuryValue,
            thermo.getMercuryHeight().intValue(), true);
    System.out.println("temp.intVal: " + temperature.intValue() +
                "\t" + "mercuryValue: " + mercuryValue);
} // end drawMercury

drawThermometerUnits 方法绘制温度计的刻度来表示单位。这个方法逐一处理图像宽度上的每个像素。每隔一定的间距,绘制一条短刻度线或长刻度线。短刻度线代表 2 度,长刻度线代表 10 度并在它下面绘制对应的数字。drawMercury 方法将转换后的温度乘以一个缩放因子,得出要绘制的水银柱的像素数。

这就是转换温度和创建温度计图像所需的代码。清单 8 给出数据对象 Thermometer.java。这个支持 bean 包含创建温度计图像所需的图像信息。

清单 8. Thermometer.java 数据对象的部分清单
// Thermometer.java - Contains dimensions and color for thermometer
// image
package devSignup;

import java.awt.Color;
import java.io.Serializable;

public class Thermometer implements Serializable
{
    private static final long serialVersionUID = 1L;
    private static final int MERCURY_HEIGHT = 20;
    private static final int THERMOMETER_WIDTH = 600;
    private static final int THERMOMETER_HEIGHT = 50;

    private Color thermometerColor = new Color(235, 235, 235);
    private Color thermometerTextColor = new Color(0, 0, 0);
    private Color mercuryColor = new Color(135, 135, 135);
    private Integer mercuryValue = null;
    private Integer mercuryHeight = null;
    private Integer thermometerWidth = null;
    private Integer thermometerHeight = null;
    
    
    public Thermometer()
    {
        mercuryValue = new Integer(0);
        mercuryHeight = new Integer(MERCURY_HEIGHT);
        thermometerWidth = new Integer(THERMOMETER_WIDTH);
        thermometerHeight = new Integer(THERMOMETER_HEIGHT);
    } // end Thermometer


    public Color getThermometerColor()
    {
        return thermometerColor;
    } // end getThermometerColor


    // ...additional get/set methods trimmed here...


    public void setThermometerColor(Color thermometerColor)
    {
        this.thermometerColor = thermometerColor;
    } // end setThermometerColor
} // end Thermometer

Thermometer 就是 <a4j:mediaOutput> 标记的 value 属性中指定的数据对象。正如前面提到的,这个数据对象必须实现 Serializable Java 类。注意,温度计图像所需的所有颜色和尺寸都在这个模块中定义,但是 mercuryValue 除外。这个值实际上是未定义的,因为它是惟一一个根据用户输入而改变的值。

在使用这两个 bean 之前,需要在 faces-config.xml 部署描述符中定义它们。打开这个文件,确保选择 Source 选项卡。确保在这个文件中输入 清单 9 的内容。

清单 9. 更新的 faces-config.xml 内容
    <managed-bean>
        <description>Temperature Converter Bean</description>
        <managed-bean-name>temperature</managed-bean-name>
        <managed-bean-class>devSignup.TemperatureConverter</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>

    <managed-bean>
        <description>Thermometer Bean</description>
        <managed-bean-name>thermometer</managed-bean-name>
        <managed-bean-class>devSignup.Thermometer</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>

这两个标记声明两个 bean 并让它们在被调用时对 JSF 库可用。这样就行了!Temperature Conversion 实用程序现在已经可以进行构建并部署到 Geronimo 上了,下面就来完成这些任务。

测试和故障排除

本节简要地讨论如何构建和部署 Temperature Conversion 实用程序并在 Developer Forum 应用程序中访问它。还讨论在开发期间遇到的一些问题。

测试

首先需要在 Eclipse 中构建示例应用程序。

  1. 右击 devSignup 项目,然后选择 Build Project
  2. 在 Eclipse 编译并验证代码之后,再次右击 devSignup 项目。这一次选择 Export
  3. 在 Export 窗口中,展开 Web 文件夹,选择 WAR file 并点击 Next
  4. 在 WAR Export 面板中,点击 Browse 选择一个目标,输入 Web 存档的文件名(例如,devSignup.war)并点击 Save
  5. 返回 WAR Export 面板之后,点击 Finish 导出 .war 文件。如果需要的话,选中覆盖现有文件的复选框。

既然已经将示例应用程序导出为 Web 存档,就可以将它部署到 Geronimo 上了。有两种部署方法:热部署和通过 Geronimo 的 Console 应用程序进行部署。在 geronimo-1.1 安装文件夹下面有一个称为 deploy 的文件夹。复制到这个文件夹中的任何存档文件(比如 EAR 或 WAR)都由 Geronimo 自动地进行部署。反之,如果从这个目录中删除存档文件,那么 Geronimo 就会卸载它们。前面的教程使用 Console 应用程序,所以我们继续使用这种部署方法。

改进后的 Developer Forum 应用程序已经准备好了。用 URL http://localhost:8080/devSignup 访问这个应用程序。

第一个页面与 第 2 部分 中创建的注册页面相同。创建一个论坛帐号。成功之后,向用户显示一个与 图 6 相似的屏幕。

图 6. 成功!
成功!
成功!

在这个页面上,论坛成员现在可以点击 here 链接来访问 Temperature Conversion 实用程序。在访问这个实用程序之后,输入摄氏或华氏温度值。应该会出现两个现象。首先,在输入每个值之后,温度立刻被转换。其次,在输入值时,在温度计旁边显示状态消息 Processing...。在输入所希望的温度之后,按 Enter 键来更新温度计图像。恭喜!Ajax4jsf 提供的 Ajax 功能已经发挥作用了。

故障排除

请您自己试试。但是要记住两个问题。正如前面所提到的,Ajax4jsf 的过滤器必须列在 web.xml 描述符文件中其他任何过滤器的前面。必须这样做才能防止同一个文件中声明的其他任何过滤器与 Ajax4jsf 过滤器冲突。根据文档所述,这个条件和解决方案只适用于在 Apache MyFaces 中使用 Ajax4jsf。

Geronimo 提供了两种部署应用程序的方法:热部署和 Geronimo Console。这两种机制看起来是相互独立工作的。当总是只使用其中一种方法进行部署时,开发人员很容易管理应用程序的安装。但是,热部署的应用程序不会出现在 Geronimo Console 的 Web App WAR 链接中。同样,通过 Geronimo Console 的 Deploy New 链接部署的应用程序也不会出现在为热部署保留的 geronimo-1.1/deploy 文件夹中。因此,有可能在 Geronimo 上部署了同一应用程序的多个实例,而您却不知道。这种情况可能会导致不可预测的结果。强烈建议您选择一种部署方法并坚持使用它。

结束语

在这个教程中,通过添加 Temperature Conversion 实用程序改进了 Developer Forum Signup 应用程序。我们研究了 Ajax4jsf 库并使用几个 Ajax4jsf 组件创建了一个启用 Ajax 的前端。还学习了如何将这个库添加到 Eclipse Web 应用程序项目中。

本系列的第 4 部分将研究 Oracle 的 ADF Faces,这是构建于 JSF 之上的另一组 UI 组件,它最近被捐献给了 Apache。这个教程将讲解如何集成这个库中的组件,从而进一步改进 Developer Forum Signup 应用程序。敬请期待!


下载资源


相关主题


评论

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source, Java technology, Web development
ArticleID=185292
ArticleTitle=使用 JavaServer Faces 构建 Apache Geronimo 应用程序,第 3 部分: 使用 ajax4jsf 添加 Ajax 功能
publish-date=12262006