茫茫網海中的冷日 - 對這文章發表回應
茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1729107 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_60D_00042.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

對這文章發表回應

發表限制: 非會員 可以發表

發表者: 冷日 發表時間: 2010/10/18 12:58:57
實戰WebService II: SOAP篇(基於php)

概述(SOAP和XML-PRC比較)

在Web服務發展的初期,XML格式化消息的第一個主要用途是,應用於XML-RPC協議,其中RPC代表遠程過程調用。在XML遠程過程調用 (XML-RPC)中,客戶端發送一條特定消息,該消息中必須包括名稱、運行服務的程序以及輸入參數。

XML-RPC只能使用有限的數據類型種類和一些簡單的數據結構。人們認為這個協議還不夠強大,於是就出現了SOAP——其最初的定義是簡單對像訪問協議。之後,大家逐漸意識到SOAP其實並不簡單,而且也不需要必須使用面向對像語言,所以,現在人們只是沿用SOAP這個名稱而已。

XML-RPC只有簡單的數據類型集,取而代之,SOAP是通過利用XML Schema的不斷發展來定義數據類型的。同時,SOAP也能夠利用XML 命名空間,這是XML-RPC所不需要的。如此一來,SOAP消息的開頭部分就可以是任何類型的XML命名空間聲明,其代價是在系統之間增加了更多的複雜性和不兼容性。

隨著計算機行業的覺醒,人們發現了基於XML的Web服務的商業潛力,於是,各家公司開始不斷地發掘想法、觀點、論據以及標準化嘗試。W3C曾經設法以「Web服務活動」的名義來組織成果展,其中也包括實際做出SOAP的XML協議工作組(XML Protocol Working Group)。與Web服務有關的標準化成果(從某種程度上說與SOAP相關或者依賴於SOAP)的數量已經倍增了到了令人驚訝的程度。

最初,SOAP是作為XML-RPC的擴展而發展起來的,它主要強調的是,通過從WSDL文件中所獲得的方法和變量名來進行遠程過程調用。現在,通過不斷進步,人們發現了更多的使用SOAP的方式,而不僅僅是採用「文件」方式——基本上是使用一個SOAP信封來傳送XML格式化文件。無論如何,要掌握SOAP,瞭解WSDL所扮演的角色是最根本的。

SOAP數據包結構解析

SOAP的消息被稱為一個SOAP Envelope,包括SOAP Header和SOAP Body。其中,SOAP Header可以方便的插入各種其它消息來擴充Web Service的功能,比如Security(採用證書訪問Web Service),SOAP Body則是具體的消息正文,也就是Marshall後的信息。

SOAP調用的時候,也就是向一個URL(比如 http://api.google.com/search/beta2 )發送HTTP Post報文(根據SOAP規範,HTTP Get報文也可被支持),調用方法的名字在HTTP Request Header SOAP-Action中給出,接下來就是SOAP Envelope了。服務端接到請求,執行計算,將返回結果Marshall成XML,用HTTP返回給客戶端。

以下[是移動MISC接入]Wap1.6業務訂購數據包樣例
MISC1.6的業務訂購關係同步的請求包
<?xml version="1.0" encoding="utf-8" ?>
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Header>
    <TransactionID xmlns="http://10.1.2.122/misc/dsmp.xsd">
00110100037392</TransactionID>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <SyncOrderRelationReq xmlns="http://10.1.2.122/misc/dsmp.xsd">
      <Version>1.5.0</Version>
      <MsgType>SyncOrderRelationReq</MsgType>
      <Send_Address>
        <DeviceType>0</DeviceType>
        <DeviceID>0011</DeviceID>
      </Send_Address>
      <Dest_Address>
        <DeviceType>400</DeviceType>
        <DeviceID>0</DeviceID>
      </Dest_Address>
      <FeeUser_ID>
        <UserIDType>2</UserIDType>
        <MSISDN />
        <PseudoCode>00116000000286</PseudoCode>
      </FeeUser_ID>
      <DestUser_ID>
        <UserIDType>2</UserIDType>
        <MSISDN />
        <PseudoCode>00116000000286</PseudoCode>
      </DestUser_ID>
      <LinkID>SP</LinkID>
      <ActionID>1</ActionID>
      <ActionReasonID>1</ActionReasonID>
      <SPID>919102</SPID>
      <SPServiceID>0000000064</SPServiceID>
      <AccessMode>2</AccessMode>
      <FeatureStr />
    </SyncOrderRelationReq>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

MISC1.6的業務訂購關係同步的響應包:

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
         xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Header>
    <TransactionID xmlns="http://www.monternet.com/dsmp/schemas/">
00110100037392</TransactionID>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <SyncOrderRelationResp xmlns="http://www.monternet.com/dsmp/schemas/">
      <Version>1.5.0</Version>
      <MsgType>SyncOrderRelationResp</MsgType>
      <hRet>0</hRet>
    </SyncOrderRelationResp>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>


實戰SOAPI

現在做SOAP開發一般有三種方式選擇
* PEAR自帶的soap擴展,
* PHP自帶的SOAP擴展,
* NuSOAP(純PHP,似乎已經過時)
註:還有WSO2.org(關於WSO2.org可以考慮嘗試一下)

PHP 5 中新增了內置的 SOAP 擴展,我們稱之為 ext/soap。它是作為 PHP 的一部分提供的,因此不需要下載、安裝和管理單獨的包。這是第一個用 C 而不是 PHP 為 PHP 編寫的 SOAP 實現,因此作者聲稱它的速度要快得多。

因為新的擴展是 PHP 的完整組成部分之一,相關文檔包含在 PHP 手冊的 Function Reference 部分(php_soap.dll)。

SOAP 參考是以一個重要的免責聲明開始的:

警告:該擴展是試驗性的(EXPERIMENTAL)。本擴展的行為,包括關於本擴展的函數名和其他內容,在以後的 PHP 版本中隨時可能改變,不另行通知。使用該擴展的風險自負。

警告看起來有點讓人擔心,但實際上這個擴展似乎得到了很好的支持。和任何新代碼一樣,該擴展也存在缺陷,但是報告的問題通常很快就能得到修正。在 PHP 站點上可以看到缺陷列表。我們估計,在將來的 PHP 版本中,該擴展將從試驗性功能轉為主流功能

一個訪問.NET WEB服務的客戶端例子

<?php

$objSoapClient = new SoapClient("http://www.webservicemart.com/uszip.asmx?WSDL");

$param=array("ZipCode"=>'12209');
$out=$objSoapClient->ValidateZip($param);
$data=$out->ValidateZipResult;
echo $data;
?>

運行後輸出

<result code="200"><item zip="12209" state="NY"
latitude ="42.64081" longitude ="-73.7856"/></result>

在實驗的過程當中,使用了一個抓包工具Wireshark來分析報文。Wireshark很不錯,在Filter處設置ip.addr == 208.109.78.12(208.109.78.12 是 www.webservicemart.com 的IP),然後啟動監控,可以分析上述調用過程中HTTP包是什麼樣的。

實戰SOAPII
用PHP建立SOAP服務

建立soap_server.php(虛擬路徑為:http://172.16.0.24/php/soap/soap_server.php)

<?php
/**
* A simple math utility class
* @author John Coggeshall john@zend.com
 */
class math {
  /**
   * Add two integers together
  *
  * @param integer $a The first integer of the addition
  * @param integer $b The second integer of the addition
  * @return integer The sum of the provided integers
   */
  public function add($a, $b) {
    return $a + $b;
  }

 /**
  * Subtract two integers from each other
  *
  * @param integer $a The first integer of the subtraction
  * @param integer $b The second integer of the subtraction
  * @return integer The difference of the provided integers
  */
  public function sub($a, $b) {
    return $a - $b;
  }

 /**
  * Div two integers from each other
  *
  * @param integer $a The first integer of the subtraction
  * @param integer $b The second integer of the subtraction
  * @return double The difference of the provided integers
  */
  public function div($a, $b) {
    if($b == 0) {
      throw new SoapFault(-1, "Cannot divide by zero!");
    }
    return $a / $b;
  }
}
  $server = new SoapServer('math.wsdl', array('soap_version' => SOAP_1_2));
  $server->setClass("math");
  $server->handle();

?>


注意幾點:

1.math類是即將公開的webservice.
2.注$server→setClass,不是$server→addClass

用PHP客戶端訪問剛建立SOAP服務

<?php
  //$client = new SoapClient('http://localhost/php/soap/math.wsdl');
  $client = new SoapClient("http://localhost/php/soap/soap_server.php?WSDL");
  try {
    $result = $client->div(8, 2); // will cause a Soap Fault if divide by zero
    print "The answer is: $result";
  } catch(SoapFault $e) {
    print "Sorry an error was caught executing your request: {$e->getMessage()}";
  }
?>

本質上,http://localhost/php/soap/soap_server.php?WSDL就是要訪問到註釋行所指的wsdl描述文件,所以這個WSDL文件必須事先生成。而對於其他語言如Java則可以動態生成。我目前的學習發現對於php自帶的SOAP擴展要求這個WSDL文件必須事先生成好。

可以用ZendStudio生成靜態的WSDL文件,此時用到math類的phpdoc作為生成WSDL的元數據。 用ZendStudio生成wsdl文件時,必須正確說明web服務目標地址,片斷如下:

...
	<service name="mathService">
		<port name="mathPort" binding="typens:mathBinding">
			<soap:address location="http://localhost/php/soap/soap_server.php"/>
		</port>
	</service>
....


特別注意:我發現調用php webserver的方法和調用.net web服務的方法不一樣。 調用.net service方法必須傳入命名參數;而調用php web服務方法,一定不能傳入命名參數,只能按順序傳入,為什麼?這一點尤其要注意


原文出處:实战WebService II: SOAP篇(基于php) - 百草园 - JavaEye技术网站
內容圖示
url email imgsrc image code quote
樣本
bold italic underline linethrough   












 [詳情...]
validation picture

注意事項:
預覽不需輸入認證碼,僅真正發送文章時才會檢查驗證碼。
認證碼有效期10分鐘,若輸入資料超過10分鐘,請您備份內容後,重新整理本頁並貼回您的內容,再輸入驗證碼送出。

選項

Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|