内容


ICEfaces 和 Google Translate

通过翻译功能丰富您的 Web 应用程序

Comments

简介

本教程描述如何使用带翻译选项的 JSF 开发出色的 Web 应用程序。您还将了解 ICEfaces 的用户界面组件以及 Google 的 API 的基本功能。最后,您将创建一个 WAR 文件并将其部署到 WebSphere® Community Edition (Community Edition)。

目标

在本教程中,您将:

  • 了解不同的 GUI 控件
  • 了解 Google Translate API 的基本功能
  • 学习如何在基于 JSF 的应用程序中使用 backing bean
  • 学习如何使用 Eclipse Web Tools Platform (WTP) 创建 JSF 页面

前提条件

在开始学习本教程之前,您应该具备基本的 Java 编程技能。

系统需求

要成功完成本教程,您需要以下软件:

  • Rational Application Developer Version 6 或 Eclipse WTP
  • WebSphere Application Server Community Edition

参见 参考资料,下载这些软件包。

背景知识

WebSphere Application Server Community Edition (Community Edition) 是 IBM 推出的支持 Java EE 5 标准的开源应用服务器。它构建于 Apache Geronimo 之上,并且集成了一流的开源技术,比如说 Apache Tomcat、Apache Axis2 和 Apache MyFaces。它的基于 Eclipse 的开发工具进一步加速了应用程序的开发过程,并且它的 Web 2.0 功能部件包提供了一个由 IBM 提供支持的解决方案,可用于创建基于 Ajax 的应用程序和 mashup。

默认情况下,Community Edition 包含三个 Tomcat 连接器:

  • HTTPS
  • AJP
  • HTTP

Community Edition 将平台上运行的所有应用程序统一到了一个共享、基于标准的安全框架中,并且该框架基于 Java Authorization Contract for Containers (JACC)。通过集中化用户管理,Community Edition 可以轻松地为您的应用程序建立和维护单独的用户管理 系统。

最新版本的 Community Edition 提供了全新的 Web 层集群和负载均衡功能,以及基于目录的热部署选项和远程部署选项。它还支持增强的 Eclipse 插件工具和全新的管理控制台。Community Edition Eclipse 插件提供了一个简单的开发环境,用于在 Eclipse 框架中创建、部署和调试您的应用程序。J2EE 配置文件将确保这些应用程序可以轻松地在 WebSphere Application Server 产品组合中迁移。

您可以从文档 Web 站点获取关于 Community Edition 特性及功能的更多详细信息。该站点共支持 11 种语言。(有关更多信息,请参见 参考资料。)

如何使用翻译功能创建 JSF 页面

本教程所示的应用程序将向用户提供翻译功能。用户将文本粘贴到一个 ice:textarea 组件中,选择源文本语言(ice:selectOneMenu),选择目标文本语言,单击 ice:commandButton,最后获取经过翻译的文本(如 ice:outputText 所示)。

您需要在 backing bean 中实现应用程序逻辑。

本教程中的应用程序包括一个用于输入文本的文本框、一些按钮和一个输出文本字段。可以轻松地将此逻辑组装成较复杂的应用程序。图 1 展示了基本布局。

图 1. 应用程序的主页面
此屏幕快照显示了教程应用程序在浏览器中的效果,它包括一个很大的 'Text to translate:' 文本输入框,两个用于选择语言的下拉框,当前显示为 'FRENCH' 和 'ENGLISH',以及两个标签分别为 'reset' 和 'translate' 的按钮。
此屏幕快照显示了教程应用程序在浏览器中的效果,它包括一个很大的 'Text to translate:' 文本输入框,两个用于选择语言的下拉框,当前显示为 'FRENCH' 和 'ENGLISH',以及两个标签分别为 'reset' 和 'translate' 的按钮。

在此教程中,您将构建一个名称为 Google Translate 的 ICEfaces 应用程序,并将它部署到一个本地 Community Edition 服务器上。需要一些额外的代码来支持特定的语言,但本示例旨在演示 ICEfaces 和 Google Translate API 的基本组件。

完成后的 ICEfaces Google Translate 应用程序应该具备以下功能:

  1. 用户使用键盘将待翻译文本输入到 ice:inputTextArea 组件中。
  2. 位于 ice:inputTextArea 下方的是一些列表(在 ICEFaces 中称作 ice:selectOneMenu),选择后可以向在 backing bean 中实现的 Google API 翻译功能添加语言参数。
  3. 右上角是两个按钮。第一个按钮是 Reset 按钮,用于刷新 ice:textArea 组件中的旧数据,重置 backing bean 中的某些变量。第二个按钮是 Translate,用于触发执行翻译操作。
  4. 执行翻译之后,结果将通过 ice:outputText 显示在页面上。翻译后的文本还会通过 ICEFaces Highlight 效果高亮显示。

图 2 展示了此过程:

图 2. Translate 教程应用程序实际效果
此屏幕快照显示了教程应用程序在浏览器中的效果,它包括一个很大的 'Text to translate:' 文本输入框,两个用于选择语言的下拉框,当前显示为 'FRENCH' 和 'ENGLISH',以及两个标签分别为 'reset' 和 'translate' 的按钮。‘Text to translate’ 框中显示的是待翻译的法语,而 ‘translated text’ 框中显示的是翻译后的英语。
此屏幕快照显示了教程应用程序在浏览器中的效果,它包括一个很大的 'Text to translate:' 文本输入框,两个用于选择语言的下拉框,当前显示为 'FRENCH' 和 'ENGLISH',以及两个标签分别为 'reset' 和 'translate' 的按钮。‘Text to translate’ 框中显示的是待翻译的法语,而 ‘translated text’ 框中显示的是翻译后的英语。

本教程中的三个步骤可以归纳为图 3 所示的目标结构。在阅读本教程时,我们假定您熟悉如何为 ICEfaces 配置环境,以确保您的环境经过适当配置,可以在 J2EE 应用服务器上部署和执行 ICEfaces 应用程序。有关详细信息,请参见与您环境相关的文件,并参阅 ICEfaces 文档(参见 参考资料)。

图 3. 项目浏览器中的 ICEFacesAndGoogleTranslate 应用程序
显示 ICEFacesAndGoogleTranslate 子目录的目标树
显示 ICEFacesAndGoogleTranslate 子目录的目标树

步骤 1. 创建 JSF 应用程序

第一步是使用 stock JSF 组件创建一个常规 JavaServer Faces (JSF) 版本的 Google Translate Web 应用程序。所有相关文件都存储在 WebContent 目录中。

首先,Google Translate 应用程序 的顶部需要一个 panelGroup 组件,用于提供 panelDivider,它将页面分为两个部分。第一个部分包括:

  • 一个 outputText 组件,作用类似于标签
  • 一个 inputTextArea 组件,用于供用户输入文本
  • 两个 selectOneMenu UI 控件,用于选择原始和目标语言
  • 一个 graphicImage 组件,用于设置一个箭头

第二部分包括:

  • 两个 outputText 组件(一个类似于标签,另一个用于显示经过翻译的文本)
  • 两个 commandButton UI 控件。一个用于重置,另一个用于翻译

清单 1 显示了 main.jspx page 的代码。

清单 1. main.jspx 页面
<?xml version="1.0" encoding="UTF-8" ?>
<jsp:root version="1.2" xmlns:jsp="http://java.sun.com/JSP/Page"
	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:directive.page contentType="text/html;charset=UTF-8"
		pageEncoding="UTF-8" />
<f:view>
	<ice:outputDeclaration doctypeRoot="HTML"
		doctypePublic="-//W3C//DTD HTML 4.01 Transitional//EN"
		doctypeSystem="http://www.w3.org/TR/html4/loose.dtd" />
	<html>
	<head>
	<title><ice:outputText value="Translate Tutorial" /></title>
	<ice:outputStyle href="./xmlhttp/css/xp/xp.css" />
	</head>
	<body>
	<ice:outputText value="Welcome to Translate Tutorial" />
	<ice:form partialSubmit="true">
		<ice:messages />
	<ice:panelGroup id="pnlGrp" >
	<ice:panelDivider id="pnlDiv" orientation="vertical"
		style="width:100%;">
		<f:facet name="first">
			<ice:panelGrid id="firstPartTrsltPnlGrp" columns="1"
						style="padding: 10px;width: 100%" >
			<ice:outputText id="outTxtTrnslt" value="Text to translate:"
						style="line-height:2em;"  />
			<ice:inputTextarea id="inputTextTrnslt" style="width:100%"
						cols="20" rows="5" partialSubmit="true"
						value="#{translate.text}" >
			</ice:inputTextarea>
			<ice:panelGroup id="menues" style="width:100%" >
			<ice:selectOneMenu id="slcOnMenuOrigLang"
				   value="#{translate.selectedOriginalLanguage}"  
                           valueChangeListener="#{translate.originalLangChanged}">
					<f:selectItems  
                                   value="#{translate.ORIGINAL_LANGUAGES}" />
			</ice:selectOneMenu>
			<ice:graphicImage id="imgArrowRight"
						url="/images/arr_ani_01e.gif">
			</ice:graphicImage>
			<ice:selectOneMenu id="slcOnMenuTrasltLang" 
                          value="#{translate.selectedTranslatedLanguage}" 
                          valueChangeListener="#{translate.translateLangChanged}">
			   <f:selectItems value="#{translate.TRANSLATION_LANGUAGES}"  />
			</ice:selectOneMenu>
			</ice:panelGroup>
			</ice:panelGrid>
		</f:facet>
      	<f:facet name="second">
			<ice:panelGroup id="secPartPblGrp" style="padding: 10px;">
				<ice:outputText id="trnsltTxt" value="Translated text"
								style="line-height:2em" />
				<ice:panelGrid id="scndPartTrnsltTxtPnlGrd" columns="1">
						<ice:outputText id="outPtTxtScndPrt"
						      value="#{translate.outputText}"  
                                         effect="#{translate.textEffect}">
						</ice:outputText>
				<ice:panelGrid id="pnlGrdButtonsSecondPart" columns="2">
					<ice:commandButton id="btnResetScndPart" 
                                       value="reset"
     				         actionListener="#{translate.resetAll}" />
					<ice:commandButton id="btnTranslitScndPart" 
                                      value="translate"
	                               actionListener="#{translate.updateText}" />
				</ice:panelGrid>
				</ice:panelGrid>
			</ice:panelGroup>
		</f:facet>
	</ice:panelDivider>
	</ice:panelGroup>
	</ice:form>
	</body>
	</html>
</f:view>
</jsp:root>

大多数组件都通过 JSF 表达式语言绑定动态绑定到了 backing JavaBeans,如清单 2 所示。

清单 2. 绑定到 backing JavaBeans 的组件
value="#{translate.outputText}"
value="#{translate.selectedOriginalLanguage}"
valueChangeListener="#{translate.originalLangChanged}"
value="#{translate.ORIGINAL_LANGUAGES}"
value="#{translate.selectedTranslatedLanguage}" 
valueChangeListener="#{translate.translateLangChanged}"
value="#{translate.TRANSLATION_LANGUAGES}"
value="#{translate.outputText}"
effect="#{translate.textEffect}"
actionListener="#{translate.resetAll}"
actionListener="#{translate.updateText}"

步骤 2. 创建 backing JavaBean (GoogleTranslate.java)

com.ibm.translate.GoogleTranslate 类是 main.jspx 页面的 backing bean。该 bean 存储选择的当前状态以及所有的 Google Translate 信息。

清单 3 显示了 GoogleTranslate.java 类的代码。

清单 3. GoogleTranslate.java
public class GoogleTranslate {
private Hashtable languages = new Hashtable();
private Hashtable langLabels = new Hashtable();
private Effect textEffect;
protected SelectItem[] ORIGINAL_LANGUAGES;
protected SelectItem[] TRANSLATION_LANGUAGES;

public void updateText(ActionEvent event) throws 
Exception{
	if(this.getText().length() > 1 ){
		this.setOutputText(translate(getText()));
	}
}
	
public void resetAll(ActionEvent event){
	this.setText("");
	this.setOutputText("");
}

public String translate(String input) throws Exception{
	String out = "";
	if(input != null){
		out = Translate.translate(this.getText(), 
                     getSelectedOriginalLanguage(), 
                     getSelectedTranslatedLanguage());
		invokeTextEffect();
	}
	return out;
}

public SelectItem[] getORIGINAL_LANGUAGES() {
	if(ORIGINAL_LANGUAGES == null){
		this.setLanguages();
		this.setLangLabels();
		Enumeration en = this.languages.keys();
		Enumeration enLbls = this.langLabels.keys();

		ORIGINAL_LANGUAGES = new 
                              SelectItem[languages.size()];
	for (int i = 0; i < languages.size(); i++) {
		ORIGINAL_LANGUAGES[i] = new SelectItem(
         (String)this.langLabels.get(enLbls.nextElement()),                  
         (String) this.languages.get(en.nextElement()));
	}
	}
	return ORIGINAL_LANGUAGES;
}

public SelectItem[] getTRANSLATION_LANGUAGES() {
	if(TRANSLATION_LANGUAGES == null){
		this.setLanguages();
		this.setLangLabels();
		Enumeration en = this.languages.keys();
		Enumeration enLbls = this.langLabels.keys();
		TRANSLATION_LANGUAGES = new 
                              SelectItem[languages.size()];
	for (int i = 0; i < languages.size(); i++) {
        TRANSLATION_LANGUAGES[i] = new SelectItem(
        (String) this.langLabels.get(enLbls.nextElement()),  
        (String) this.languages.get(en.nextElement()));
		}
	}
	return TRANSLATION_LANGUAGES;
}

public void setLanguages() {
	this.languages.put(Language.ARABIC, "ARABIC");
	this.languages.put(Language.CHINESE_SIMPLIFIED, 
                                "CHINESE_SIMPLIFIED");
	this.languages.put(Language.CHINESE_TRADITIONAL, 
                                "CHINESE_TRADITIONAL");
	this.languages.put(Language.DUTCH, "DUTCH");
	this.languages.put(Language.ENGLISH, "ENGLISH");
	this.languages.put(Language.FRENCH, "FRENCH");
	this.languages.put(Language.GERMAN, "GERMAN");
	this.languages.put(Language.GREEK, "GREEK");
	this.languages.put(Language.ITALIAN, "ITALIAN");
	this.languages.put(Language.JAPANESE, "JAPANESE");
	this.languages.put(Language.KOREAN, "KOREAN");
	this.languages.put(Language.PORTUGESE, "PORTUGESE");
	this.languages.put(Language.RUSSIAN, "RUSSIAN");
	this.languages.put(Language.SPANISH, "SPANISH");
}

public void setLangLabels() {
	this.langLabels.put(new Integer(0), 
                                     Language.PORTUGESE);
	this.langLabels.put(new Integer(1),Language.KOREAN);
	this.langLabels.put(new Integer(2), 
                                        Language.JAPANESE);
	this.langLabels.put(new Integer(3), Language.SPANISH);
	this.langLabels.put(new Integer(4), Language.GERMAN);
	this.langLabels.put(new Integer(5), Language.FRENCH);
	this.langLabels.put(new Integer(6), Language.ITALIAN);
	this.langLabels.put(new Integer(7), 
                              Language.CHINESE_SIMPLIFIED);
	this.langLabels.put(new Integer(8), Language.ARABIC);
	this.langLabels.put(new Integer(9), Language.RUSSIAN);
	this.langLabels.put(new Integer(10),Language.GREEK);
	this.langLabels.put(new Integer(11), 
                                         Language.ENGLISH);
	this.langLabels.put(new Integer(12), Language.DUTCH);
	this.langLabels.put(new Integer(13), 
                             Language.CHINESE_TRADITIONAL);
	}
 }
}

您可以下载 GoolgeTranslate 示例的完整代码(参见 下载)。

现在,我们将分析上述代码。

在 backing bean 的开始部分,您定义了两个 SelectItem 数组。

SelectItem 表示与 UISelectManyUISelectOne 组件相关的受支持项目列表中的单一项目。在本例中,它是一个 ice:selectOneMenu 组件。您需要注意这个类中的两个方法。第一个方法是 setLabel(String label),它用于将此项目的标签设置为对于用户可见。第二个方法是 setValue(Object value),它用于在用户选择某个项目时设置传递给模型的项目的值。

对于 GoogleTranslate 类的各个成员,您需要分别生成它们的 getters 和 setters。Eclipse 提供了一个函数来完成此任务。选择字段、类型或类型中的文本,并使用 Source 菜单或 Context 菜单中的 “Generate Getters and Setters” 功能打开相应窗口。“Generate Getters and Setters” 窗口将显示所选类型的所有字段的 getters 和 setters。这些方法将根据类型的字段进行分组。getter 和 setter 方法的名称源于字段名称。当您按下 OK 时,系统将创建所有选中的 getters 和 setters。

在示例代码中,我创建了两个散列表。如前所述,selectOneMenu 组件使用了一个 SelectItem 数组,语言散列表利用该数组设置 ORIGINAL_LANGUAGES 或者 TRANSLATION_LANGUAGES 的值。

langLabels 散列表用于设置 SelectItem 数组的标签。

用户选择某种语言时,相应参数将传递给 Google API 的 translate 函数。

注意:还可以采用另一种方法。除了使用两个散列表,我还可以使用一个包含键和值的字典,并将其存储为 String[]。为此,我需要自己实现这个数据结构。

此处的示例将使用 Highlight 效果,当某些信息更改或提交后便会启用。我将高亮显示 inputText 的 backing bean 值。inputText 组件中提交的文本将高亮显示在一个窗格中。

步骤 3. 创建 web.xml 和 faces-config.xml 文件

web.xml 文件为构成 Web 应用程序的 Web 组件提供了配置和部署信息。这些信息必须位于 Web 应用程序目录层次结构的 WEB-INF 目录中。

清单 4 显示了 web.xml 文件。

faces-config.xml 文件是 JavaServer Faces 配置文件。该文件列出了 bean 资源和导航规则。清单 5 显示了 faces-config.xml 文件的代码。

清单 5. faces-config.xml 文件
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE faces-config PUBLIC
    "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
    "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<faces-config>
	<managed-bean>
		<managed-bean-name>translate</managed-bean-name>
		<managed-bean-class>
                                    com.ibm.translate.GoogleTranslate
               </managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>
	</managed-bean>
</faces-config>

结束语

本教程简述了如何使用 Google 的 Translate API 来构建简单翻译组件。将代码汇编到项目中之后,您应该能够像任何 Web 应用程序一样执行和部署它。在此基础上,您可以轻松地翻译粘贴的文本,或者为 Web 应用程序中的信息提供即时翻译。请继续探索无限可能。如有 任何疑问或建议,请随时联系我们。


下载资源


相关主题


评论

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development, Java technology
ArticleID=441826
ArticleTitle=ICEfaces 和 Google Translate
publish-date=10292009