IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  XML | Java technology | Open source  >

将 XForms 与 Google Web Toolkit 相结合,第 1 部分: 介绍 GWT 的 JavaScript Native Interface

为未来的摇滚巨星创建 Web 应用程序

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

讨论


级别: 中级

Michael Galpin (mike.sr@gmail.com), 开发人员, Ludi Labs

2007 年 10 月 25 日

本系列文章介绍如何结合使用 Google Web Toolkit (GWT) 和 XForms 创建动态 Web 应用程序,分为四部分。第 1 部分采用自下到上的办法说明结合使用 GWT 和 XFoms 中存在的问题。介绍了这两种技术的基础知识,考察了能够让两者和平共处的相同之处。这是同时使用 GWT 和 XForms 开发 Web 应用程序的基础。

简介

Google Web Tookit (GWT) 已经成为一种非常受欢迎的开发 Ajax 应用程序的方法。它可以让 Java 开发人员利用已有的 Java™ 知识迅速创建 Ajax 应用程序,而不需要去学习 JavaScript。XForms 代表了 HTML 标准的新发展,通过简单的指令就能创建复杂的、动态的行为。GWT 和 XForms 都非常强大,足以单独解决很多问题。那么为什么还要将两者结合起来呢?这恰恰也是本系列文章所要说明的。

本系列文章中,我们将建立一个简单的 Web 应用程序管理摇滚明星和他们的相册。我们将同时使用 GWT 和 XForms,最后您就能够把这两种技术完全融合在一起了。第 1 部分中将通过一些简单的例子来介绍这些技术。对于 GWT 我们使用它自带的 KitchenSink 这个例子。这个例子曾经被用于展示 GWT 的多种 UI 小部件。





回页首


前提条件

本文使用 GWT 1.4 和 Mozilla XForms 插件 0.8(相关链接请参阅 参考资料 部分)。这个 Mozilla XForms 可用于任何基于 Mozilla 的 Web 浏览器,如 Firefox 和 Seamonkey。使用 GWT 需要了解 Java 技术和一些 Web 技术如 HTML、CSS。文中还用到了大量 JavaScript 代码。XForms 采用模型-视图-控制器范型,因此熟悉 MVC 就足够了。原来接触过 XForms 和 GWT 当然很好,但不是必需的。





回页首


XForms

现在创建 Web 应用程序,目标很可能是创建支持 Ajax 的 Web 应用程序。您可能遇到过各种各样的 Ajax,比如能够异步添加和修改数据的 Ajax。如果说在 Ajax 这个词还没有发明之前已经有很多人想到过这些形式,您可能会奇怪。用 Ajax 完成的很多常见的功能也能用 XForms 实现。

XForms 这种标准化的技术将成为下一代 HTML 规范的核心。XForms 的关键在于将数据和数据的物理视图分离开来。听起来是否有些耳熟?通过分离数据,就可通过任何形式的 HTML 呈现出来。还可以与 form 元素相结合,从而实现输入数据和编辑已有数据的无缝衔接。

人们使用 Ajax 来解决很多相同的问题。在 Ajax 中需要保持数据和表示(HTML)的分离。通常会创建 JavaScript 对象来表示这些数据。XForms 提供了一种更加标准化的方法。它用 XML 保存实例数据。我们来看一个例子。





回页首


XML 实例数据

XForms 采用熟悉的模型-视图-控制器范型。因此 XForm 背后的数据包含在 XForm 模型中。清单 1 给出了一个例子。


清单 1. XForms 模型
                
        <xf:model id="my-model" xmlns="http://www.w3.org/1999/xhtml" 
 xmlns:xf="http://www.w3.org/2002/xforms">
 <xf:instance id="my-data" src="my-data.xml" xmlns=""/>
 <xf:bind calculate="sum(../Item/Amount)" nodeset="/Data/Total"/>
 <xf:submission action="my-data.xml" id="update-from-local-file" 
 instance="my-data" method="get" replace="instance"/>
 <xf:submission action="my-data.xml" id="view-xml-instance" 
 method="get"/>
 <xf:submission action="my-data.xml" id="saveToServer" 
 method="put"/>
 </xf:model>

这里有几点需要注意。首先是 XForms 模型中包含的 XForms 实例。实例是模型所代表的真正的数据。可以指定实例的来源。与 JavaScript 和 CSS 引用其他资源很相似。如果指定 source 属性,浏览器就会发出单独的 HTTP 请求来加载这些数据。当然也可直接包含实例数据。其次,模型和实例都有 ID。后面将看到,这恰恰是它们能够用于其他技术的关键。

第三,要注意不同的 XForm-submission 声明。这里列举的大动作和基本 HTML 表单中的相似。都是表单数据需要提交到的 URL。要注意 method 属性。它也类似于 HTML 表单中的 method 属性。它说明提交使用什么样的 HTTP 请求。这就是整个模型。下面再看看 XForms 中的视图。





回页首


XForms 视图

模型声明以后,用模型中包含的数据创建视图很简单。XForms 包含很多常见的控件处理模型实例数据。每个控件都能引用模型的实例数据。实例数据用 XML 格式表示,因此用 XPath 很容易导航和引用。XForms 完全支持 XPath 2.0 规范。我们来看几个例子。

处理模型数据最简单的办法就是在浏览器上显示出来。可以使用 output 控件,如清单 2 所示。


清单 2. XForms output
                
<xhtml:div id="sum">
 <xf:output class="item-amount" ref="/Data/Total" 
 xmlns="http://www.w3.org/1999/xhtml">
 </xf:output>
</xhtml:div>

ref 属性就是一个 XPath 表达式。它对模型中的实例数据求值。这里不但有 XForms 控件,而且在 output 控件中使用了 XHTML 表达式,如 div、CSS class 属性。这不是什么技巧,只不过在巧妙地提醒您未来 XForms 将成为 HTML 完整的一部分。

设计 XForms 是为了交换,而不仅仅是显示数据。因此必然有编辑数据的控件。看看清单 3。


清单 3. XForms 中的表单控件
                
<xf:input class="item-amount" ref="Amount" xmlns="http://www.w3.org/1999/xhtml">
 <xf:label>Amount</xf:label>
</xf:input>
<xf:submit submission="saveToServer" xmlns="http://www.w3.org/1999/xhtml">
 <xf:label>Save</xf:label>
</xf:submit>

清单 3 中的例子创建了一个带标签的 input 字段和 Submit 按钮。两者都和模型绑定在一起。输入字段绑定到实例数据。从 HTML 元素的角度来看,该输入字段预先填充了数据模型中绑定的值。

提交控件也就成了 HTML Submit 按钮。但它也是绑定到模型的。它引用了模型中的 submission 元素。该元素指定了一个表单动作。因而,提交控件将创建一个 HTML Submit 按钮,单击该按钮就会按照模型的提交规范向 URL 发出 HTTP post 请求。什么发送给该 URL 呢?当然是 XML 数据。数据绑定到输入控件,用户输入的新数据在 HTTP POST 到服务器之前将自动传递给模型。

目前一般而言,HTML 表单的提交就是导航到那个 POST 的动作 URL。这是典型的 “Web 1.0” 方式,幸运的是对于 XForms 来说并非如此。在 XForms 应用程序中,提交仅仅是传递到服务器的数据。和导航没有关系。这是清晰划分模型(数据以及对数据的操作,如提交给服务器)和视图的一部分。

结果还要等时间的考验。这难道不是典型的 Ajax 应用程序吗?可能需要无数行 JavaScript 代码才能将数据绑定到表单、捕捉表单的提交、异步发送数据到服务器然后重绘显示数据的部分视图。这些都压缩到 XForms 实现中去了。仅仅用 XForms 就能完成大量的工作,但这绝不是一种栅栏围起来的封闭技术。它很容易和基本的客户端技术交互:HTML DOM 和 JavaScript。





回页首


XForms 和 JavaScript

通过 XForms,应用程序数据可以用模型表示,绑定到不同的视图。这些开发服务器端代码时常用的方法,由于 Ajax 在客户端也变得越来越常见。XForms 是一种客户端技术,因此使用浏览器的原生语言 JavaScript 很容易访问它并不奇怪。

XForms 的强大功能完全可以通过在同一页面上执行的 JavaScript 访问。实际上,所有的 XForms 成分,包括模型和视图都属于建立的 HTML DOM。这正是下一代 HTML 规范的核心。因而就像访问 HTML div 一样,可用熟悉的 getElementById() 格式来访问。清单 4 给出了使用 JavaScript 访问 XForms 模型的一个例子。


清单 4. 通过 JavaScript 访问 XForms 模型
                
var model = document.getElementById("my-model");
var instance = model.getInstanceDocument("my-data");
var dataElement = instance.getElementsByTagName("Data")[0];
var itemElements = dataElement.getElementsByTagName("Item");
var cnt = itemElements.length;
var descripElement = itemElements[0].getElementsByTagName("Description")[0];
descripElement.childNodes[0].nodeValue = "";
var amtElement = itemElements[0].getElementsByTagName("Amount")[0];
amtElement.childNodes[0].nodeValue = "0";
model.rebuild();
model.recalculate();
model.refresh();

通过 清单 4 可以看到,能够把 XForms 模型作为 DOM 的一部分来访问。得到的是标准的 JavaScript 对象。它有专门的方法,如 getInstanceDocument()。然后就可以访问 XML 实例数据了。这是真正的 XML DOM 对象,可以像其他任何 XML DOM 对象一样导航和修改。





回页首


GWT

GWT 是 2006 年的 JavaOne 上提出的。当时已经得到了 Java 技术开发人员的广泛接受。利用已有的知识再加上对 HTML 和 CSS 的基本了解,Java 技术开发人员就能快速创建支持 Ajax 的 Web 应用程序。显然这是一种合适的快速原型开发工具,但实践证明也适用于生产环境。比如,Google 自己的将 Web 应用程序和 Web API 融为一体的在线集成开发环境 Mashup Editor,就是用 GWT 开发的。

GWT 的很多强大功能来源于将 Java 代码编译成 JavaScript 的能力。Java 技术开发人员可以用熟悉的事件驱动编程直接与服务器端模型连接在一起。多数 Java 开发人员乐于不用自己编写 JavaScript 代码。他们享受到了强类型语言的好处,同时又能使用标准工具(如 Eclipse)调试支持 Ajax 的 Web 应用程序。

如果愿意编写 JavaScript 代码,GWT 能提供更多的功能。最重要的是,JavaScript 是连接 GWT 世界的关键。如果需要非 GWT 程序和 GWT 程序交互,或者相反,那么 JavaScript 就是唯一的办法。

所幸的是,GWT 很容易和其他技术交互。它打开了自身底层 JavaScript 的盖子,允许开发人员直接在 GWT 类中编写 JavaScript 代码。就是说,通过 GWT 的 JavaScript Native Interface (JSNI) 可以在编写 Java 类的同时编写 JavaScript 代码。





回页首


JSNI

GWT 文档(请参阅 参考资料)介绍了 JSNI 的一些应用。单纯用 JSNI 就能实现客户端方法。JSNI 可以封装已有的 JavaScript,非常适合将已有的应用程序迁移到 GWT。使用 JSNI 可以访问客户端 Java 代码(编译成了 JavaScript),反之亦然。关键在于用 JavaScript 能够实现的功能,用 GWT 和 JSNI 都能实现,不需要 Java 表示。我们来看一些例子。

JSNI 的例子

为了说明 JANI 可以做什么,我们先从 GWT 自带的一个例子入手。这个例子是 KitchenSink。它展示了 GWT 中的 UI 元素。也非常适合试验 JSNI,因为只有客户端代码,不需要和服务器通信。

我们将定义一个用 JavaScript 实现的 Java 方法。首先从 JavaScript 所能做的最简单的事情开始,经典的 “Hello world”。Hello world 的 JSNI 版如清单 5 所示。


清单 5. Hello World JSNI
                
private native void blastName() /*-{
 alert("Hello world");
}-*/;

使用这个 JSNI 方法,需要将其添加到 KitchenSink 类,让它在执行 Java 方法 showInfo() 的时候调用 JSNI 方法,如清单 6 所示。


清单 6. 从 Java 调用 JSNI
                
private void showInfo() {
 show(list.find("Intro"), false);
 blastName(); // added JSNI method
}

GWT 对 JavaScript 方法的处理就像是在 Java 平台上编写的一样。简单明了。编译然后在托管模式下运行会看到图 1 所示的结果。


图 1. KitchenSink
KitchenSink

太简单了。现在稍微增加一点难度,让 Java 和 JavaScript 共享数据。

从 JSNI 访问 Java 变量

要让 JSNI 真正有用,必须能够在 Java 和原生 JavaScript 代码之间共享数据。从而能够利用 GWT 和 JavaScript 各自的优点。清单 7 是 “Hello world” 的改进版本。


清单 7. JSNI 和 Java 变量
                
public class KitchenSink implements EntryPoint, HistoryListener {

 private static final Sink.Images images = (Sink.Images) GWT.create(Sink.Images.class);

 protected SinkList list = new SinkList(images);
 private SinkInfo curInfo;
 private Sink curSink;
 private HTML description = new HTML();
 private VerticalPanel panel = new VerticalPanel();
 // new variable to be accessed in JSNI
 private String myVar = "Hello variables"; 

变量 myVar 在 Java 中定义,但是可在 JSNI 方法中访问,如清单 8 所示。


清单 8. 在 JSNI 方法中访问 myVar 变量
                
private native void blastName() /*-{
 var str = 
 this.@com.google.gwt.sample.kitchensink.client.KitchenSink::myVar;
 alert(str);
}-*/;

现在编译新的 KitchenSink 并单击按钮,将看到图 2 所示的结果。


图 2. Hello 变量
hello 变量

现在,您可以轻松地在 Java 和原生 JavaScript 代码之间交换数据。因为您已拥有所有结合使用 GWT 和各种 JavaScript 技术所需的构建技术,如 XForms。





回页首


结束语

分享这篇文章……

digg 提交到 Digg
del.icio.us 发布到 del.icio.us
Slashdot 提交到 Slashdot!

XForms 和 GWT 都为现代 Ajax 应用程序提供了有力的抽象和强大的工具。而且都有和“底层”JavaScript 的联系。不但可以用 JavaScript 补充各自本身已经很丰富的功能,而且提供了将两种技术结合起来的公共基础。现在了解了集成 XForms 和 GWT 的蓝图。第 2 部分将按照这个蓝图开始融合 XForms 和 GWT。



参考资料

学习

获得产品和技术

讨论


关于作者

Michael Galpin 从 1998 年开始从事专业 Java 软件开发。他目前为 Mountain View, Calif. 的一家新兴企业 Ludi Labs 工作。他从 California Institute of Technology 获得了数学学位。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

将您的建议发给我们或者通过参加讨论与其他人分享您的想法.




回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款