一、概述
SOAP 原意為 Simple Object Access Protocol (簡易物件存取通訊協定 (SOAP)),是一個用於分布式環境的、輕量級的、基於 XML 進行資訊交換的通訊協定( SOAP is an XML based protocol used to exchange information throughout a distributed environment )。
以下是 w3c 網站上的定義:
SOAP Version 1.2 (SOAP) is a lightweight protocol intended for exchanging structured information in a decentralized, distributed environment. It uses XML technologies to define an extensible messaging framework providing a message construct that can be exchanged over a variety of underlying protocols. The framework has been designed to be independent of any particular programming model and other implementation specific semantics.
可以認為 SOAP 是 XML-RPC 的進階版本,二者基於相同的原理:利用 HTTP + XML 封裝進行 RPC 調用。
SOAP 最初由 MS 發起研究,用以解決 MTS/COM 資源消耗大,不夠輕巧等問題,後逐漸被 IBM 等巨頭接納並加入研究,現已提交 W3C ,成為 Web Service 應用傳輸通訊協定。對於輕量級、可擴充 Web Service 應用協議的需求促成了 SOAP 的廣泛應用,也間接促進了 XML 的流行。關於相關曆史的更多資訊,見 http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/SOAPSpecificationIndexPage.mspx 或 http://www-128.ibm.com/developerworks/cn/webservices/ws-ref1/index.html 。
二、 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 返回給用戶端。
以下是一個典型的 SOAP 資料包:
< s:Envelope xmlns:s = "http://www.w3.org/2003/05/soap-envelope ">
< s:Header >
< m:transaction xmlns:m = "soap-transaction " s:mustUnderstand = "true ">
< transactionID > 1234</ transactionID >
</ m:transaction >
</ s:Header >
< s:Body >
< n:purchaseOrder xmlns:n = "urn:OrderService ">
< from >
< person > Christopher Robin</ person >
< dept > Accounting</ dept >
</ from >
< to >
< person > Pooh Bear</ person >
< dept > Honey</ dept >
</ to >
< order >
< quantity > 1</ quantity >
< item > Pooh Stick</ item >
</ order >
</ n:purchaseOrder >
</ s:Body >
</ s:Envelope >
其中包含了一些 SOAP 規範定義的標籤,同時也可以包含一些具體應用相關的標籤。
Note:
如果你是一個普通的應用開發人員,以上介紹已經足夠了,因為相應的 SOAP 應用平台會負責完成相應 SOAP 資料包的打包和解析;如果你是一個 SOAP 應用平台的實現者,關於 SOAP 基礎理論的更多介紹可參考《 Programming Web Services with SOAP 》一書或 SOAP Specification ( http://www.w3.org/TR/soap12-part0/ )。
三、安裝 Apache Axis
Apache Axis 本身也是一個 Web Project ,它內建了對 SOAP 的編碼、解析,並為 Client 提供了一些使用 SOAP Service 的 API ,同時,為 Web Service 的發布提供管理,並對 Client 提交的處理請求作出響應。對於基於 Axis 的應用而言,我們可以將注意力完全放在具體 Service 和 Client 的設計上,而無需考慮中間的傳輸過程(對於 Client 而言,還需要使用一些 Axis 提供的訪問 SOAP 服務的特定 API ),這一點是與 XML RPC 不同的地方。
Apache Axis 可以從 http://ws.apache.org/axis/ 下載,當前的最新版本是 1.4 。
安裝 Axis 的過程很簡單:
1 、解壓 Axis 到任意目錄下;
2 、拷貝 Axis 目錄下的 webapps/axis 目錄到 %TOMCAT_HOME%/webapps 下;
3 、為了便於編譯和測試程式,添加環境變數 :
AXIS_HOME Axis 的解壓目錄
AXIS_LIB %AXIS_HOME%/lib
AXISCLASSPATH %AXIS_LIB%/axis.jar;%AXIS_LIB%/commons-discovery-0.2.jar;%AXIS_LIB%/commons-logging-1.0.4.jar;%AXIS_LIB%/jaxrpc.jar;%AXIS_LIB%/saaj.jar;%AXIS_LIB%/log4j-1.2.8.jar
完成上述工作後,啟動 Tomcat ,並用 IE 開啟: http://localhost:8080/axis/ ,點擊其中的 Validation 、 List 兩個連結,如果沒有報告任何錯誤,則說明 Axis 安裝成功。
關於 Apache Axis 安裝的更多資訊可以參考官方文檔: http://ws.apache.org/axis/java/install.pdf 。
四、舉例
有了上面對 SOAP 的基本理解,下面我們體驗一下 Apache Axis 1.4 提供的 SOAP 服務。
以下面 EchoService 為例:
public class EchoService {
public String echoString(String name) {
return name;
}
}
其對應的 Client 程式如下所示:
package demo.soap;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace .QName;
public class EchoClient {
public static void main(String [] args) {
try {
String endpoint = "http://localhost:8080/axis/EchoService.jws" ;
// Create Service and Call object to set up a SOAP RPC
Service service = new Service();
Call call = (Call)service.createCall();
// Tells which service and method will be invoked
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new QName("echoString" ));
// Invoke method with required parameters
String ret = (String)call.invoke(new Object[] { "Hello!" });
System.out.println("Sent 'Hello!', got '" + ret + "'" );
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
對於 Client 程式而言,對 Axis Service 進行訪問的基本方法是:
1 、建立 Service 及 Call 對象;
2 、設定 Call 對象屬性,如訪問點(標明將訪問哪個 Axis Service )及方法名等;
3 、傳入參數數組,調用 Call 對象的 invoke 方法。
可使用如下命令編譯 EchoClient.java :
javac -cp %AXISCLASSPATH% EchoClient.java
在 Axis 中,存在兩種發布 SOAP Service 的方法。
方法一:
將來源程式 EchoService.java 拷貝到 %TOMCAT_HOME%/webapps/axis 下,並將其尾碼改為 .jws 即可。
第一種方法非常的簡單,但是第一種發布方法存在幾個重要的限制:
1 、不能指定 package ;
2 、需要有 Service 的源碼;
因此常常不能滿足我們的需要。
方法二:
第二種發布 Axis Service 的方法需通過配置來完成。
以下面的 HelloService 為例(與前面的 EchoService 基本沒有什麼區別,但其中使用了 package ):
package demo.soap;
public class HelloService {
public String sayHello() {
return "Hello World!" ;
}
}
要發布上面的 Service ,需編寫如下的設定檔:
< deployment xmlns = "http://xml.apache.org/axis/wsdd/ " xmlns:java = "http://xml.apache.org/axis/wsdd/providers/java ">
< service name = "HelloService " provider = "java:RPC ">
< parameter name = "className " value = "demo.soap.HelloService "/>
< parameter name = "allowedMethods " value = "* "/>
</ service >
</ deployment >
將上述內容儲存為 %TOMCAT_HOME%/webapps/axis/WEB-INF/deploy.txt ,並在其所在目錄下執行:
java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.txt
產生 server-config.wsdd 檔案,開啟該檔案看一下,可以看到 HelloService 的相關資訊已被添加到該檔案,此外,還包括一些預設的配置資訊以及 AdminService 、 Version 兩個基礎服務。
以下是 HelloService 的 Client 程式的相關代碼:
package demo.soap;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class HelloClient {
public static void main(String [] args) throws Exception {
String endpoint = "http://localhost:" + "8080" + "/axis/services/HelloService" ; // Attention: A little difference
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName("sayHello" );
String res = (String)call.invoke(new Object[] {});
System.out.println(res);
}
}
與前面的 EchoClient 的區別僅在於訪問點稍有不同。
發布後如何刪除對應的 Service 呢?要刪除上面發布的 HelloService 服務,只需在 %TOMCAT_HOME%/webapps/axis/WEB-INF 目錄下添加如下的 undeploy.txt 描述檔案,其內容如下:
< undeployment xmlns = "http://xml.apache.org/axis/wsdd/ ">
< service name = "HelloService "/>
</ undeployment >
然後執行:
java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.txt
以更新 server-config.wsdd 檔案。
重新整理一下頁面:
http://localhost:8080/axis/servlet/AxisServlet
將看到前面發行的對應的 Service 已被刪除。
如果以後還要發布新的 Service ,你可以選擇直接更新上面產生的 server-config.wsdd 檔案,或者重複上面的步驟。
Note :除了發布自己的 Web Service 到 Axis ,你也可以將 Axis 整合到自己的 Web Application ,具體方法見 http://ws.apache.org/axis/java/install.pdf 。
五、 Google Web API
在繼續下面的討論之前,先娛樂一下,談談 Google Web API 。
為了便於程式員體驗 Google 的搜尋服務,或者將 Google 的搜尋服務整合到自己的應用中, Google 於 2002 發布了 Google Web API ,可以讓世界各地的 Java 、 .NET 、 Perl 、 Python 等程式員,免費地通過 Google 提供的 SOAP 開發介面以 Web Services 的方式,對 Google 下達尋找指令,並且可以將結果使用於自己的程式或網頁中。(不過使用上也有限制,它一天只允許未付費的程式員尋找 1000 次。要使用前,必須先向 Google 註冊帳號,取得一個 32 位長度的 license key ,每次呼叫查詢時,必須帶入這個 license key 。)
通過使用 Google Web API ,能夠從 Google 那兒以結構化資料的形式( xml 格式)取得檢索結果,所帶來的最大好處就是你可以根據你自己的意願和設計,把這些檢索結果顯示你自己的頁面上。這個頁面上可顯示自己的 logo 或一些其它的內容,就象自己編寫的頁面一樣,而不必非要把 Google 的 logo 顯示在頁面的頂部和底部。一句話,你可以控制 Google 的檢索了,讓 Google 為你的網站服務。(參考 5 )
以下是使用 Proxy 串連 Google SOAP 服務的例子:
java -cp googleapi.jar -Dhttp.proxyHost=xxx(proxy_host_ip/name) -Dhttp.proxyPort=xxx(proxy_port) com.google.soap.search.GoogleAPIDemo xxx(license_key) search billdavid
其輸出大致如下:
Parameters:
Client key = o917zHlQFHIr2+qMGPUYflB+j89LLbcX
Directive = search
Args = billdavid
Google Search Results:
======================
{
TM = 0.694308
Q = "billdavid"
CT = ""
TT = ""
CATs =
{
<EMPTY>
}
Start Index = 1
End Index = 10
Estimated Total Results Number = 1280
Document Filtering = true
Estimate Correct = false
Rs =
{
[
URL = "http://forums.vandyke.com/member.php?u=2050"
Title = "VanDyke Software Forums - View Profile: <b>billdavid</b>"
Snippet = "This is a discussion forum for users and evaluators of VanDyke Soft
ware products."
Directory Category = {SE="", FVN=""}
Directory Title = ""
Summary = ""
Cached Size = "16k"
Related information present = true
Host Name = ""
],
[
URL = "http://forums.vandyke.com/showthread.php?t=1393"
Title = "Will you add two new features to SecureCRT? - VanDyke Software Forums
"
Snippet = "<b>billdavid billdavid</b> is offline. Registered User. Join Date:
Apr 2006 <b>...</b><br> Originally Posted by <b>billdavid</b>. I think the foll
owing features are very useful: <b>...</b>"
Directory Category = {SE="", FVN=""}
Directory Title = ""
Summary = ""
Cached Size = "30k"
Related information present = true
Host Name = "forums.vandyke.com"
],
[
URL = "http://www.beliefnet.com/user/profile_view.asp?userID=424089&popUp=1"
Title = "Beliefnet Member Profile"
Snippet = "Member Name: <b>billdavid</b>. Member since: 2/24/2003. Location: s
ebring, florida , us.<br> Sex: Male. Age: 53. Occupation: Other. Organizations
and Affiliations: <b>...</b>"
Directory Category = {SE="", FVN=""}
Directory Title = ""
Summary = ""
Cached Size = "8k"
Related information present = true
Host Name = ""
],
(下略 ... )
以下是通過 ethereal 抓到的本機發出的 Google Search 資料包:
POST http://api.google.com/search/beta2 HTTP/1.0
Host: api.google.com
Content-Type: text/xml; charset=utf-8
Content-Length: 864
SOAPAction: "urn:GoogleSearchAction"
<? xml version = '1.0 ' encoding = 'UTF-8 '?>
< SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://schemas.xmlsoap.org/soap/envelope/ " xmlns:xsi = "http://www.w3.org/1999/XMLSchema-instance " xmlns:xsd = "http://www.w3.org/1999/XMLSchema ">
< SOAP-ENV:Body >
< ns1:doGoogleSearch xmlns:ns1 = "urn:GoogleSearch " SOAP-ENV:encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/ ">
< key xsi:type = "xsd:string "> xxx…xxx </ key >
< q xsi:type = "xsd:string "> billdavid</ q >
< start xsi:type = "xsd:int "> 0</ start >
< maxResults xsi:type = "xsd:int "> 10</ maxResults >
< filter xsi:type = "xsd:boolean "> true</ filter >
< restrict xsi:type = "xsd:string "></ restrict >
< safeSearch xsi:type = "xsd:boolean "> false</ safeSearch >
< lr xsi:type = "xsd:string "></ lr >
< ie xsi:type = "xsd:string "> UTF-8</ ie >
< oe xsi:type = "xsd:string "> UTF-8</ oe >
</ ns1:doGoogleSearch >
</ SOAP-ENV:Body >
</ SOAP-ENV:Envelope >
com.google.soap.search.GoogleAPIDemo.java 的原始碼可以在 googleapi 的壓縮包中找到,其中示範了大部分基本 Google Web API 的用法,關於 Google Web API 的更多資訊見參考 4 。
六、 Axis2
隨著 Web Services 技術的演化, Apache Web Services 中介軟體也在不斷髮展,從第一代的 Apache SOAP ,第二代的 Axis ,逐漸發展成為第三代 Web Service 中介軟體 Axis2 。與 Axis 相比, Axis2 採用了效能更為優越的 XML 解析技術,採用面向組件的架構設計,從而具有更好的靈活性和可擴充性,並可支援非同步通訊需求等。參考 6 、 7 給出了利用 Axis2 進行 Web Service 開發的詳細步驟。
參考:
1. 勞虎, SOAP 與 Web services , http://2tigers.net/html/tiger_column/article3.html
2. 孟岩, Web Service : WebOS 中的 Function Call , http://www.mengyan.org/blog/archives/2006/06/09/125.html
3. Axis 學習筆記, http://www.javaresearch.org/article/showarticle.jsp?column=5&thread=29576
4. Google, Google SOAP Search API, http://www.google.com/apis/
5. Patrick Chanezon, Patch For Google APIs to handle proxy settings, http://www.chanezon.com/pat/google_proxy_patch.html
6. Hilton ,關於 Google API 的學習, http://hedong.3322.org/archives/000274.html
7. Gopalakrishnan U 、 Shreevidya Rao ,通過 Axis2 開發 Web 服務, http://www-128.ibm.com/developerworks/cn/webservices/ws-webaxis1/index.html
8. joyeta , Apache Axis2(java web service) 備忘記, http://blog.matrix.org.cn/page/joeyta?entry=apache_axis2_java_web_service
http://www.javaeye.com/wiki/topic/408971
JavaSE6.0 Web Service學習筆記
http://www.javaeye.com/topic/166314?page=1
web service架構---axis學習筆記
http://www.javaeye.com/topic/250240
使用Axis建立Web Service服務
http://www.javaeye.com/topic/417433
在axis中通過wsdd檔案發布和卸載webservice
http://www.javaeye.com/topic/56552
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/findhappy7/archive/2009/08/18/4457891.aspx