PHP5中使用Web服务访问J2EE应用程序(2)
发表于:2007-06-21来源:作者:点击数:
标签:
PHP Weather 客户机 这一节将建立我们自己的 PHP Weather 客户机。这里提供了一些代码片段,建议下载完整的客户机和 WSDL 文件。 用于表示 Weather Service 的 ext/soap 类是 SoapClient。正如我们介绍 Weather Forecast 应用程序时所讨论的,我们知道应用
PHP Weather 客户机
这一节将建立我们自己的 PHP Weather 客户机。这里提供了一些代码片段,建议下载完整的客户机和 WSDL 文件。
用于表示 Weather Service 的 ext/soap 类是 SoapClient。正如我们介绍 Weather Forecast 应用程序时所讨论的,我们知道应用服务器在 http://host:port/ItsoWebServer2RouterWeb/wsdl/itso/session/WeatherForecastEJB.wsdl 中提供了 WSDL。我们使用的是默认端口,并且在作为服务器的计算机上工作,这样就可以通过查找 WSDL 文件创建第一个 SoapClient:
clearcase/" target="_blank" >cc66 width="90%" align=center bgColor=#dadacf border=1>
<?php $soapClient = new SoapClient("http://localhost:9080/" . "ItsoWebService2RouterWeb/wsdl/itso/session/WeatherForecastEJB.wsdl"); ?> | 注意,因为 ext/soap 是内置的,所以,在引用 SoapClient 之前,不需要任何 include 或 require 语句。
现在已经实例化了客户机,还要联系 Weather 服务,并调用它的 getForecast 操作。在 WSDL 模式下使用 SoapClient 时,ext/soap 有一种很好的特性,即可以直接引用远程操作,就像它是 SoapClient 自身的函数一样。但是在建立输入参数时需要一点技巧。ext/soap 可以提供从 WSDL 中发现的操作和参数的数组:
$functions = $soapClient->__getFunctions(); print_r($functions); $types = $soapClient->__getTypes(); print_r($types); | 只需要显示与 getForecast 相关的结果,并重新格式化这些结果,以方便阅读,于是我们看到以下代码:
getForecastResponse getForecast(getForecast $parameters)
struct getForecast { dateTime startDate; int days; }
struct getForecastResponse { Weather getForecastReturn; }
struct Weather { string condition; dateTime date; string windDirection; int windSpeed; int temperatureCelsius; boolean dbflag; } | ext/soap 实际上并没有为我们定义 getForecast 类,我们必须创建该操作所需要的输入参数数组:
$getForecastParam = array('startDate' =>time(), 'days' => 3); | 然后像 SoapClient 的方法那样调用该操作:
$forecastResponse = $soapClient->getForecast($getForecastParam); | 最后我们得到了返回的 getForecastResponse 对象,它本身是一个 Weather 对象数组,然后在表格中显示结果:
echo "<table border=1 cellpadding=5>"; echo "<tr><th>Date</th><th>Condition</th><th>Temperature</th><th>Wind</th></tr>"; $weatherArray = $forecastResponse->getForecastReturn; foreach ($weatherArray as $weather) { echo "<tr>", "<td>",strftime("%a. %b %d, %Y", strtotime($weather->date)),"</td>", "<td>$weather->condition</td>", "<td>$weather->temperatureCelsius</td>", "<td>$weather->windDirection $weather->windSpeed</td>", "</tr>"; } echo "</table>"; | PHP 客户机与 Java 客户机的输出相同,于是我们知道圣诞节期间 San Jose 不会下雪……
图 3. PHP WeatherClient | 观察 SOAP 流
我们成功地与 Weather 服务取得了联系,并显示了结果。但是如果出现错误,得不到预期的结果,该怎么办?ext/soap 可以显示客户机与服务器之间交换的 SOAP 消息,能够帮助我们确定问题所在。
只有使用 trace 选项创建 SoapClient 时,才要使用跟踪功能。我们在 options 数组参数中设置 trace 选项,将该参数传递给 SoapClient 构造函数。我们将构造函数的使用改为:
$soapClient = new SoapClient("http://localhost:9080/" . "ItsoWebService2RouterWeb/wsdl/itso/session/WeatherForecastEJB.wsdl", array('trace' => 1)); | 并在调用 goForecast 之后调用 trace 方法:
echo "Request : ", htmlspecialchars($soapClient->__getLastRequest()), " "; echo "Response : ", htmlspecialchars($soapClient->__getLastResponse()), " "; | 一定要使用 htmlspecialchars 内置函数对 trace 输出进行编码,因为它将 SOAP xml 分界符转换成特殊字符,如 <,这样可以避免浏览器将其解释成标记。
下面是某个请求的 trace 输出:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://session.itso"> <SOAP-ENV:Body> <ns1:getForecast> <ns1:startDate>2004-11-30T13:41:59</ns1:startDate> <ns1:days>0</ns1:days> </ns1:getForecast> </SOAP-ENV:Body> </SOAP-ENV:Envelope> | 对应的应答是:
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <getForecastResponse xmlns="http://session.itso"> <getForecastReturn xmlns:ns-239399687="http://mapping.itso"> <ns-239399687:condition>sunny</ns-239399687:condition> <ns-239399687:date>2004-11-30T00:00:00.000Z</ns-239399687:date> <ns-239399687:windDirection>W</ns-239399687:windDirection> <ns-239399687:windSpeed>18</ns-239399687:windSpeed> <ns-239399687:temperatureCelsius>6</ns-239399687:temperatureCelsius> <ns-239399687:dbflag>1</ns-239399687:dbflag> </getForecastReturn> </getForecastResponse> </soapenv:Body> </soapenv:Envelope> | 如果在开启跟踪功能的情况下运行客户机来收集这些输出,那么需要将 days 参数设置为 0,只有这样做,SOAP 应答才会输出较少的行。但是我们遇到了没有预料到的行为。我们本来期望 getForecastResponse 和以前一样是一个 Weather 对象数组,但是它应该只有一个元素,而不是 4 个元素。然而,它被转换成了一个简单的 Weather 对象,我们必须根据这种行为进行编码,就像您在最终的示例 PHP 客户机代码中看到的那样。这与 Java 客户机的行为有所不同,在客户机行为中,getForecast 总是返回 Weather 对象数组,无论服务器响应中有多少个 Weather 对象。SoapClient::_getTypes() 输出并没有为我们理解这种差异提供足够的细节,因此我们要求助于 WSDL 文档来了解完整的接口规范。
|
原文转自:http://www.ltesting.net