什么是Web服务?
Web服务是使用万维网公开应用程序功能的一种方式。 它通过使用开放协议来做到这一点,因此任何可以访问Web的使用应用程序也可以访问Web服务。
典型的Web服务交互由使用者(使用Web服务的远程应用程序)向服务发送XML消息组成。 然后,该服务解析消息并以XML格式发送回响应。 消费者然后解析响应,并以某种方式使用从服务中检索到的信息。
通常,Web服务中使用的XML语言是SOAP。 SOAP最初是简单对象访问协议(Simple Object Access Protocol)的首字母缩写,但由于某种原因,情况已不再如此。 该协议包括三个部分:信封,数据类型规则以及定义操作请求和响应的方法。
Web服务是用另一个XML文档(称为Web服务描述语言(WSDL))定义的。 WSDL指定使用Web服务公开的操作,操作使用的数据类型定义,用于与Web服务进行通信的协议以及Web服务本身的位置。
Web服务的优势在于,它们使使用不同编程语言编写并部署在不同平台上的应用程序可以通过Internet进行广泛的通信。
什么是Ajax?
Ajax是Web开发人员用来实现富客户端演示的最新前沿技术之一。 它通过调用新请求而不中断当前视图来实现此目的。 返回XML文档,然后将其作为当前演示文稿中的子页面显示给用户。 简而言之,Ajax为您提供了服务器端动态内容的好处,同时仍然看起来像客户端动态内容。
Ajax通常通过使用XMLHttpRequest DOM API来完成其计费,在Ajax出现之前,Web开发人员很少使用它。 请求本身可以是GET
或POST
品种之一。
与其他任何请求一样,将返回响应,这可能是错误。 如果响应不是错误的,则使用响应的实际文本来更新当前视图。
记得伏尔泰(Voltaire)的一句著名的声明(即“神圣罗马帝国既不是神圣的,也不是罗马的,也不是帝国”),对各种Ajax实现的深入研究使人们意识到Ajax不需要JavaScript代码,不需要XML,并且不需要是异步的。 除去所有内容后,首字母缩写词中剩下的唯一部分是连词(and)。 但是首字母缩写听起来很酷,因此行业决定保留它。
Ajax和Web服务如何结合在一起
这样想:丰富的客户端体验以及Internet上任何位置均可访问的服务。 是的,那很酷。
您已经看到,Ajax在后台执行了一个请求,并且通常将响应(或响应的一部分)发回到Web页面上,而没有整个页面的刷新。 现在,尽管该请求可以是简单的HTTP请求,但也可以是发送到公开Web服务的SOAP消息。 然后,Ajax例程JavaScript端可以解析响应(也为SOAP格式),并提取返回给应用程序并呈现给用户的必要数据。
真的就是这么简单。
fishinhole.com的业务需求
fishinhole.com的董事会希望您使其他Web应用程序更容易访问该公司的清单。 他们认为,如果其他网站,包括运动钓鱼论坛,博客,甚至竞争对手的钓具零售商都可以轻松访问fishinhole.com的库存清单,那么其销售额将增加23.7%。
您抵制诱惑去思考它们如何达到23.7%的数字,而是专注于如何将清单公开给其他Web应用程序。 不需要很长时间就可以得出创建Web服务所需的结论。 Web服务使调用方消费者可以根据诱饵类型提交对诱饵清单的请求。 当前可用的诱饵类型为Casting
, Trolling
和Other
。 您的Web服务根据使用者提供的诱饵类型返回诱饵列表。
您还意识到,目前,您的公司已经脱离了Other
类型的诱惑。 您必须在Web服务中优雅地处理该问题。
部署简单的Web服务
您使用PHP创建简单的Web服务。 PHP与NuSOAP一起,是我见过的用于快速创建Web服务的最简单的方法之一。
首先,确保你抢的NuSOAP(见相关信息 ),并把所有PHP文件在你PHP Web服务将被部署在同一目录下。
安装NuSOAP之后,就该开始编写实际的Web服务了。 清单1包含整个内容。
清单1. webservice.php
<?php
require_once('nusoap.php');
$server = new soap_server;
$server->register('hello');
$server->register('retrieveByType');
function hello($name) {
return 'Hello, ' . $name;
}
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.php')
行。 此行使PHP网页可以使用nusoap.php中定义的类。 您可能想知道为什么与NuSOAP相关联的所有其他PHP文件都是必需的。 好吧,事实是nusoap.php依赖于这些文件的方式与页面依赖nusoap.php的方式几乎相同。
下一行实例化了soap_server
对象。 毫不奇怪,这使您能够创建使用SOAP协议的Web服务。
下一行注册了retrieveByType
函数,以便将其作为Web服务操作公开。 如果您进一步看一下代码,就会看到有一个定义的函数称为retrieveByType
。 那么为什么需要这一步呢? 因为如果您不注册该函数,则它是一个简单PHP函数,仅可用于此PHP页面或包含此函数的其他PHP页面。 因此,此行通知soap_server
对象您正在将此功能作为Web服务使用者可用的操作公开。
下一段代码实际上实现了retrieveByType
方法。 这是一个简单PHP函数,它接受一个参数: type
,可以是trolling
, casting
或other
。 如您所知,fishinhole.com的客户可以使用三种诱饵类型。
retrieveByType
方法返回一个数组。 该数组包含特定于所请求类型的诱饵列表。 目前,有三种不同的诱饵类型可用于trolling
而三种不同的诱饵类型可用于casting
。 请注意,这里有一个“包罗万象”的内容,其中包括“ Other
和任何无法识别的类型。 对于这些,Web服务仅返回“ None Found!
作为数组的唯一元素。
当访问Web服务时,将执行最后两行。 第一行检查是否有任何POST
数据。 如果不是,则将POST
数据设置为空字符串。 第二行使用POST
的数据执行Web服务。 POST
数据包含SOAP消息。 当您检查消费者时,您将看到更多有关此的信息。
将此页面另存为webservice.php,并将其放在安装NuSOAP的目录中。 显然,您需要将此页面放置在可以处理PHP文件的位置。 如今,大多数托管解决方案都支持PHP,因此,如果您没有方便PHP处理器,就可以轻松找到一个。
现在,通过访问以下URL快速测试Web服务:http://yourhost/yourdirectory/webservice.php。 显然,您需要将放置文件的实际主机和目录分别yourdirectory
为yourhost
和yourdirectory
。
您获得的响应应该是SOAP响应(请参见清单2)。 如果不是,则您的Web服务无法正常工作。
清单2. SOAP响应
<?xml version="1.0" encoding="ISO-8859-1" ?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode xsi:type="xsd:string">SOAP-ENV:Client</faultcode>
<faultactor xsi:type="xsd:string" />
<faultstring xsi:type="xsd:string">method '' not defined in service</faultstring>
<detail xsi:type="xsd:string" />
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
编写访问Web服务的页面
从实际访问Web服务JavaScript代码开始,如清单3所示。
清单3. invokeService()
JavaScript函数
function invokeService(type) {
soapMessage = '<?xml version="1.0" encoding="ISO-8859-1"?>';
soapMessage+='<SOAP-ENV:Envelope SOAP-ENV:encodingStyle=""';
soapMessage+=' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"';
soapMessage+=' xmlns:xsd="http://www.w3.org/2001/XMLSchema"';
soapMessage+=' xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">';
soapMessage+=' <SOAP-ENV:Body> <ns1:retrieveByType 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);
}
该函数称为invokeService
并接受一个参数: type
。 不用说,这对应于Web服务操作接受的type
参数( retrieveByType
)。 换句话说, type
参数是一个由casting
, trolling
或other
组成的字符串。
该函数的前几行汇编SOAP消息。 提供SOAP的详尽概述已经远远超出了本文的范围。 但是,XML的某些部分相当直观。 请注意,XML元素之一直接对应于操作名称( retrieveByType
)。 该元素的子元素根据webservice.php文件( type
)中指定的参数名称来命名。 该元素的值是传递给此JavaScript函数的字符串参数,也称为type
。
接下来的几行创建了一个跨浏览器兼容的请求对象。 这是用于访问Web服务的对象。
建立请求对象后,该函数将设置回调函数,在此示例中为populateDiv()
函数。 此功能可在网页上显示返回的库存清单。
然后该函数设置标题。 在此特别感兴趣的是,您正在建立与SOAP兼容的内容类型: text/xml
。 另外,请注意url
变量的使用。 创建自己的网页时,需要将该变量设置为Web服务使用的URL。 它看起来像这样:http://www.myhost/myservicedir/webservice.php。
最后,您可以使用请求对象发送SOAP消息,并在服务不响应的情况下建立超时。
接下来,看一下响应Ajax调用并显示清单JavaScript代码,如清单4所示。
清单4. populateDiv()
JavaScript函数
function populateDiv(){
try {
if(httpRequest.readyState==4) {
if(httpRequest.status==200) {
clearTimeout(valTimeout);
var text = httpRequest.responseText;
if (window.DOMParser) {
parser=new DOMParser();
xmlDoc=parser.parseFromString(text,"text/xml");
} else {
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.loadXML(text);
}
var html = "";
for (i=0;i<xmlDoc.getElementsByTagName("item").length;i++) {
html += "<br/>" +
xmlDoc.getElementsByTagName("item")[i].childNodes[0].nodeValue;
}
var resultDiv=document.getElementById("resultDiv");
resultDiv.innerHTML = html;
}
}
} catch(e) {
alert("Error!"+e.description);
}
}
使用Ajax的任何人都应该熟悉前几行。 回想一下,每次请求对象发生状态更改时都会调用此函数。 当请求返回有效响应(200码)时,这里特别有趣。
返回有效响应后,您将清除超时并获取响应文本。 请记住,响应文本实际上是SOAP响应,因此它是XML格式。 这意味着您需要使用JavaScript编程语言来解析XML以获取重要信息。
这将带您进入接下来的几行。 这些行实例化了可与跨浏览器兼容的XML文档对象,该对象可由JavaScript编程语言解析。 由于SOAP响应是XML文档,因此可以像解析任何其他XML文档一样对其进行解析。
接下来,创建一些HTML。 您从一个空HTML字符串开始。 然后,为item
元素解析SOAP响应。 记住,Web服务返回一个数组。 因此,很可能有一个以上的item
元素。 for
循环本质上说“对于每个item
元素,请执行以下操作”。
“跟随”如下:JavaScript代码获取item
元素的第一个子元素。 在这种情况下,只有一个孩子,这是一个简单的字符串。 然后,它提取该子项的值,该子项是清单中的一项。 为美观起见,我在库存商品前添加了<br/>
标签。 这样,列表中的每个项目都会显示在其自己的行上。 最后,整行都连接到现有HTML,因此当for
循环完成时,您将获得完整的列表。
HTML完成后,就可以将其放在页面上了。 在这种情况下,名为resultDiv
的div
元素的内容将被您刚刚创建HTML覆盖。 结果是当用户从页面的下拉框中选择一种新类型时出现在屏幕上的清单项目列表。
说到HTML,请看实际Web页面所需HTML,如清单5所示。
清单5.客户端HTML
<body>
<div style="position:relative;left:0px;background-color:blue;margin:0px;">
<h2 align="center"><font color="#ffffff">FishinHole.com Web Service</font></h2></div>
<table align="center" cellpadding="6px" cellspacing="6px" width="400" border="0">
<tr>
<td width="80" valign="center"><font color="black">
Lure Type:</font></td>
<td>
<select name="lureType" id="lureType" onchange="changeTypes()">
<option value="">-SELECT-</option>
<option value="trolling">Trolling</option>
<option value="casting">Casting</option>
<option value="other">Other</option>
</select>
</td>
<td width="150"> </td>
<tr>
<td colspan="3">
<div id="resultDiv"></div>
</td>
</tr>
</table>
</body>
这里没有什么特别复杂的。 您有一个简单的下拉框,其中包含三种诱饵类型:拖曳,投射和其他。 我使用onchange
属性,以便当用户选择新的诱饵类型时,将自动执行调用Ajax请求JavaScript代码。
另请注意,存在resultDiv
div元素。 这是清单列表出现的位置。
测试中
将您刚创建HTML页面放在任何可以解释HTML和JavaScript代码的平台上。 如果您使用Microsoft®Windows®操作系统,则可以将其放在硬盘驱动器上。
接下来,只需访问网页。 您应该在屏幕中间看到一个下拉菜单。 现在,所选项目应为-SELECT- 。 只需将其更改为Trolling即可 。 等待几秒钟,您应该会在屏幕上看到三个项目的清单清单。 恭喜,您的测试成功了!
如果遇到问题,请检查以确保相应地设置了url
变量。 同样,JavaScript代码可能会在弹出窗口中报告异常以及说明。 这为您提供了有关错误之处的线索。
结论
Web服务是将操作公开给可以访问Internet的人们的有力手段。 Ajax是一种通过更改显示而不刷新页面来为Web应用程序用户提供丰富体验的方法。 您可以将两者一起使用来创建功能强大的Web应用程序,该应用程序可以模拟分布式对象应用程序并提供专业的界面。
翻译自: https://www.ibm.com/developerworks/web/library/wa-aj-webservices/index.html