Web Servicess 是一种通过 Hypertext Transfer Protocol (HTTP) 访问的基于 Web 的应用编程接口(API)。在主机端,特定的操作是使用 Extensible Markup Language (XML) 定义的,即 Web Servicess Description Language (WSDL)。客户端和主机之间的信息交换的标准也称为 Simple Object Access Protocol,或 SOAP。(事实上,Web Servicess 有很多缩写词。)
在实践中,Web Servicess 利用了一个集中访问点进行信息交换。顾名思义,它们提供了一种服务供所有客户端使用。例如,Web Servicess 可用于获取最新头条新闻、在线图书商店的最新列表或者某个特定地理位置的捕渔报告。另外,这些信息经常通过网站进行发布,如专业新闻创作或个人博客。
Dojo 是一个开放源码 JavaScript 用户界面(UI)工具套件,它促进了 JavaScript 应用的快速部署。它是一系列加快和简化 JavaScript 代码编写的 JavaScript 库。
Dojo 框架的其中一个主要的组件是 Dojo Base。这个部分的 Dojo 库负责处理复杂的事件处理、Asynchronous JavaScript + XML (Ajax) 调用、Cascading Style Sheets (CSS) 查询、效果等等。
Dojo Base 之上是一个名为 Dijit 的小部件 — Dojo 的其中最流行的特性。这是一系列可重用的组件,您可以直接拖放到您自己的应用中。为了定制您的应用的外观和体验,您只需要对大多数小部件进行简单的配置。
FishinHole.com 的董事会已经确定了通过一个 Web Services 显示公司的产品目录(并实现目录可搜索),从而更广泛地将产品通过 Web 推广出去,这样公司便可以占据相应的竞争优势。董事会要求您创建这个 Web Services 并创建一个原型来说明通过简单 Web 页面访问它的方式 — 明天之前完成。
由于这个公司已经使用 PHP 实现了在线显示目录,所以它也会使用 PHP 来处理 Web Services。有一个名为 NuSOAP 的 PHP 库可以简化使用 PHP 进行 Web Services 的快速开发过程,它支持大多数据的 SOAP 1.1 规范,也能够生成符合 WSDL 1.1 规范的文档。
现在考虑一下客户端的需求:这个 Web Services 其实 “非常简单”。它调用一个可以运行在本地个人电脑而不需要使用 PHP 翻译器(或其它相关技术)的 Web Services。然后有一个简单的带有 JavaScript 代码的 Hypertext Markup Language (HTML) 页面可以生成所需要的结果。虽然您一开始生成的结果是非常简单的,但是 Dojo 支持扩展,它能够在将来实现一些花俏的用户界面特性。由于您使用了 Dojo,那么您也可以选择使用它来处理 XML,从而保持开发的一致性。
这样一个您使用了 PHP 和 NuSOAP 编码的 Web Services 会返回一个基于公司所销售的鱼饵类型的列表。在这个非常简单的例子中,鱼饵的类型只有三种:拖钓型、投掷型和其他。
清单 1 显示了这个简单的使用 PHP 和 NuSOAP 编写的符合 SOAP 的 Web Services。
清单 1. 一个使用 PHP 编写的简单 Web Services
<?php
require_once('nusoap.php');
$server = new soap_server;
$server->register('retrieveByType');
function retrieveByType($type) {
if ($type == 'trolling') {
$arr[0] = 'Donzai Deep Swimmer 5 1/4 inch';
$arr[1] = 'Yosubi Squid-like 4 inch';
$arr[2] = 'Fortunata Imperial High Action';
} else if ($type == 'casting') {
$arr[0] = 'Silver Spring Mirrors Size 00';
$arr[1] = 'Gold Spring Mirrors Size 0';
$arr[2] = 'Mini Minnow Blue';
} else {
$arr[0] = 'None found!';
}
return $arr;
}
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>
|
第一行代码(require_once 所在的行)引用了所需要的 NuSOAP
库。要使用这个库,您必须先下载。参考资料 中有关于下载 NuSOAP
的更多信息。
下一行代码初始化了一个名为 $server 的 PHP 对象。这个对象的类型是
soap_server,它是在 NuSOAP PHP
库中定义的。当客户端调用其中一个服务操作时,这个对象将处理这个操作并返回结果。
下一行代码将一个函数注册为一个 Web Services
操作。在这里,您只有一个操作,因此也只有一个函数。根据本例的要求,这个操作的名称和函数的名称是一样的(但这是一个非常好的实践做法,因为它可以避免混淆)。当您调用名为
retrieveByType 的 SOAP 操作时,相同名称的 PHP 函数就会被调用。
接下来是上面提到的 PHP 函数的实现。注意这个函数只接受一个参数:type。type
将会与以下两个字符串之一进行比较:trolling 或
casting。如果这两个字符串中有任意一个与参数相匹配,那么函数就会返回相应的鱼饵数组。如果不匹配,那么就会返回字符串
None found!。
倒数第二行代码显示 Web Services 是如何处理操作调用的。您可以看到,参与这个调用的 Web Services
将会由 POST(与
GET 相对应)触发。这类似于一般 Web
应用中所使用的表单提交方式。这一行代码也会专门处理 null 值,它将 null 值转换为一个空字符串以避免后面的处理出现问题。
最后,这个服务器对象调用它的 service 函数。这个函数接受以
POST 方式提交的数据,然后返回正确的响应给客户端。
这样您就完成了这个 Web Services 的开发。将这个文件命名为 webservice.php,并将它保存在您使用的主机上。
因为您使用 Dojo 来处理和解析您新的 Web Services 返回的 XML,所以您必须在您的客户端代码的开头引用 Dojo 库(如 清单 2 所示)。
清单 2. 引用 Dojo 库
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js" type="text/javascript"></script> |
上面的代码位于您的 HTML 页面的 head 元素内。以这种方式引用
Dojo,您就不需要下载库文件,因为它已经存在 Web 上了。可惜,如果所引用的网站宕机了,那么您的应用也会宕机。幸好,Google
很少会发生宕机。
清单 3 显示了这个 Web Services 在 HTML 页面上是如何编程调用的。
清单 3.
invokeService() 函数
function invokeService(type) {
soapMessage = '<?xml version="1.0" encoding="ISO-8859-1"?>';
soapMessage+='<SOAP-ENV:Envelope SOAP-ENV:";
soapMessage+=;encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"';
soapMessage+=' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"';
soapMessage+=' xmlns:xsd="http://www.w3.org/2001/XMLSchema"';
soapMessage+=' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
soapMessage+=' xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"';
soapMessage+=' xmlns:si="http://soapinterop.org/xsd">';
soapMessage+=' <SOAP-ENV:Body> <ns1:retrieveByType ';
soapMessage+='xmlns:ns1="http://fishinhole.com">';
soapMessage+=' <type xsi:type="xsd:string">' + type + '</type>';
soapMessage+=' </ns1:retrieveByType> </SOAP-ENV:Body> </SOAP-ENV:Envelope>';
if(window.XMLHttpRequest) {
httpRequest=new XMLHttpRequest();
} else if (window.ActiveXObject) {
httpRequest=new ActiveXObject("Microsoft.XMLHTTP");
}
httpRequest.open("POST",url,true);
if (httpRequest.overrideMimeType) {
httpRequest.overrideMimeType("text/xml");
}
httpRequest.onreadystatechange=populateDiv;
httpRequest.setRequestHeader("Man", url + " HTTP/1.1")
httpRequest.setRequestHeader("MessageType", "CALL");
httpRequest.setRequestHeader("Content-Type", "text/xml");
httpRequest.send(soapMessage);
valTimeout=setTimeout("timeout(httpRequest);",120000);
}
|
虽然看起来编码量不少,但是这个清单的内容对于熟悉 Ajax 的开发人员来说是很简单的。
首先,一个符合 SOAP 规范的消息被构造成一个字符串。这个消息的大部分代码都是直接编写的。除了鱼饵类型,它是以下三个字符串之一:trolling,casting
或 other。这些类型看起来很相似,只有 other
特别些(它将用于判断是否返回 None found! 结果)。
在创建了这个 SOAP 消息后,您还需要添加一些额外的代码来保证符合跨浏览器支持。然后,HTTP
请求对象会根据客户端所使用的浏览器类型来初始化。这个对象是 httpRequest。
Web Services 的访问采用的是 POST 方法;这可以在 httpRequest
函数处理 httpRequest 时看出。您之前的编码预期会出现这个结果。您选择部署 Web Services
的位置将决定 url 输入参数的值(它的格式类似于 http://www.myhost.com/webservice.php)。
httpRequest 对象的 onreadystatechange
函数的调用对于本页面的功能实现非常重要。它被设置为 populateDiv,这是
Web Services 响应返回时作为回调函数的 JavaScript 函数的名称。
接下来几行代码的作用是设置具体的头信息。在这之后,Web Services 会在 send
函数被调用时正式调用。注意这个函数的输入参数是之前所创建的 SOAP 消息。
清单 4 显示的是 JavaScript 函数 populateDiv。
清单 4.
populateDiv 函数
function populateDiv(){
try {
if(httpRequest.readyState==4) {
if(httpRequest.status==200) {
clearTimeout(valTimeout);
var text = httpRequest.responseText;
var dom = dojox.xml.parser.parse(text);
var docNode = dom.documentElement;
var html = "";
var returnElement = docNode.childNodes[0].childNodes[0].childNodes[0];
for (var i = 0; i < returnElement.childNodes.length; i++) {
html +="<br/>" +
dojox.xml.parser.textContent(returnElement.childNodes[i]);
}
var resultDiv=document.getElementById("resultDiv");
resultDiv.innerHTML = html;
}
}
} catch(e) {
alert("Error!"+e.description);
}
}
|
注意,因为您同时处理请求/响应机制和 XML 解析,所以使用 try/catch 编写整个函数。您可能希望捕捉所遇到的所有异常,然后输出这些异常以便调试。
这时,这里会执行几个检查。如果接收到一个响应,那么请求对象会注册为就绪状态 4。如果响应有效,那么它会注册状态为 200。
一旦接收到一个有效的响应,那么超时变量就会被清除,这意味着您不需要担心您的 Web Services 会超时。
接下来,代码将获取这个响应的实际内容 — 采用 XML 格式并且很可能与之前编写的响应非常相似。该内容拥有一个包含基于所选择的鱼饵类型的文本响应的元素。
最后,Dojo 会被调用来解析所返回的 SOAP 消息,然后在下一行代码中处理文档的根元素。
然后您会看到 NuSOAP Web Services 返回了一个或多个 item
元素。这些元素位于响应的第 4 层深度位置(即设置 returnElement
对象的那一行)。在某种程序上,您查看的是根元素的第 4 级子元素。为了查看这些元素,您需要遍历第 3
级子元素的所有子元素(这个元素名为 return,它反映了 JavaScript
对象的名称)。
遍历所有的第 4 级子元素,只提取这个元素的文本部分(这里是鱼饵的描述信息),并且在这个文本部分之前添加一个
<br/> 标签,从而在每一个鱼饵名称后面加一个空行来进行分隔。
最后,获取 DIV 元素,它是用于显示响应的。然后所构建的 HTML
会填充到这个 DIV 中,这样它就能即时显示响应内容。
一旦您部署好客户端和 Web Services 代码,就可以测试您的原型代码。
这个客户端可以直接在您的本地计算机上运行。任何 Web 浏览器(如 Microsoft® Windows® Internet Explorer 或 Mozilla Firefox)都可以处理本地 HTML 文件,即使它使用了 JavaScript 代码。
当网页显示时,它会显示一个简单的下拉菜单,您可以选择一个鱼饵类型。如果您选择了Trolling,那么结果马上会显示在下拉菜单下面。再选择 Casting,那么结果会发生变化。如果您选择Other,那么您会看到 None found!。
董事会在催促您完成工作;您必须按期创建一个 “非常简单” 的 Web Services。
更重要的是,您使用几种非常简单的技术(PHP、NuSOAP 和 Dojo)展示了一种可行的方法。通过这个方法,您展示了您的能力,也展示了如何快速有效地实现应用整合。最后,您使用这种方法消除 Web Services 实现的复杂性。
或许您很快就可以得到晋升。
| 描述 | 名字 | 大小 | 下载方法 |
|---|---|---|---|
| 本文所使用的 PHP Web Services 文件 | webservice.php | 1KB | HTTP |
| 客户端 HTML/JavaScript 代码 | client.html | 2KB | HTTP |
学习
-
阅读最佳的
NuSOAP 介绍。
-
学习 w3schools.com 上的
SOAP 教程。
-
developerWorks Web development
专区:通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。
-
developerWorks Ajax 资源中心:这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。
-
developerWorks Web 2.0 资源中心,这是有关 Web 2.0 相关信息的一站式中心,包括大量 Web 2.0 技术文章、教程、下载和相关技术资源。您还可以通过 Web 2.0 新手入门 栏目,迅速了解 Web 2.0 的相关概念。
- developerWorks 技术活动和网络广播:随时关注 developerWorks 技术活动和网络广播。
获得产品和技术
-
浏览 Dojo Toolkit。
-
获取 NuSOAP 库。
讨论
-
现在创建您自己的
developerWorks 社区个人档案 并设置一个关于 Dojo 或 Web Services 的
关注清单。随时关注
developerWorks 社区 的更新。
-
查找其他对
Web Services 或
Dojo
感兴趣的 developerWorks 会员。
-
Web 开发人员,请
在 Web 开发群组中共享您的经验和知识。
-
共享您的知识:
加入我们的其中一个关注于 Web 主题的 developerWorks 群组。
-
Roland Barcia 撰写的关于
Web 2.0 和中间件 的博客。
-
关注 developerWorks 会员
所共享的关于 Web 的书签。
-
快速解答:请访问
Web 2.0 Apps 论坛。