1. 程式人生 > >SOAP例項入門(轉)

SOAP例項入門(轉)

SOAP的HelloWord例項- -

1.1  前言

2005-3-2公司開會並分給我一個任務:寫一個程式從福建移動的BOSS系統取出一些相關資料。我得到的資料只有一個“福建移動BOSS與業務增值平臺介面規範V1.2.2(新).doc”,這個規範頁數不多,一下就瀏覽完了。但之後依然不知所措,感覺到了一條河邊,河前有一條大道(就是這份文件)能讓我直達目的地,但卻找不到過河的橋。這份文件只給出了資料的格式編碼規範,但沒有告訴你用什麼技術,怎麼去取這些資料,甚至連一個數據格式的XML例子檔案也沒有。

裡面只有這樣幾句話:“交易訊息(包括請求和應答)是以XML格式表達的,包括兩個部分:Message Header(訊息頭)與Service Content(交易業務內容)。”  “介面協議使用HTTP協議,落地方為發起方提供訪問的URL,發起方使用HTTP POST方法傳送請求報文並得到應答報文,發起方作為落地方的HTTP客戶端,落地方作為發起方的HTTP伺服器。因此,各個參與方需要同時實現HTTP客戶端以及伺服器的功能。”

這裡面有兩個關鍵字:XML、HTTP,再加上老大說用SOAP,我想這個BOSS系統和外界的資訊交換技術也是基於SOAP實現的吧。於是我上網搜尋了一些資料,始有此文。

注:Boss Connector就是這個專案的名稱

1.2  SOAP簡介

企業系統內部各個系統之間的資訊交換一直是一個難題,在過去有DCOM、CORBA等解決方案,但都不是很完美,不是太複雜就是有缺陷。現在則較流行SOAP(全稱:Simple Object Access Protocol,簡單物件訪問協議)。

SOAP和Web Service和Apache SOAP這些新概念(應該也不算新了)常搞的人頭昏。我是這麼理解的,Web service(也稱Web服務)是一個大的概念範疇,它表現了一種設計思想。SOAP是Web service的一個重要組成部份,如果把Web service比喻成Internet,那麼SOAP就可以比喻成TCP/IP。SOAP是一種協議而非具體產品,微軟也有自己的SOAP實現產品,而Java下比較流行的SOAP實現產品就是Apache SOAP,不過它的下一個版本已經改名成AXIS了。

SOAP是通過XML檔案來做為資料轉輸的的載體,走HTTP的線路,一般企業的防火牆都開放HTTP的80埠,所以SOAP不會被防火牆阻斷,這算是SOAP的一個優點。

資訊轉輸的雙方都要求支援SOAP服務,因為XML檔案發過去,則對方需要有SOAP服務來接收,然後對方會有反饋也是XML檔案,這時你也需要安裝SOAP服務來接收,如下圖所示:

XML檔案

 

XML檔案轉輸到SOAP中,SOAP服務還會有一些內部處理,它具體的處理過程就暫時不管這麼多了,下面先來寫一個HelloWorld例項感受一下先。

1.3  下載

一共要下載四個軟體包,它們都是開源免費的。其中,前兩個是Apache的,後兩個是SUN網站,如下所示:

具體怎麼下載就不說了,說說要注意的事項:儘量用IE的“目標另存為”的來下載,有些用FlashGet是無法下載的。下載之前先不要關閉網頁。

下載後的版本是:JAF1.0.2 + JavaMail 1.3.2 + SOAP2.3.1 + Xerces1.4.4,如下圖所示。

下載後將它們分別解壓縮。其中,soap包有些怪異,第一次解壓得到的是一個沒有副檔名的檔案soap-bin-2.3.1,要將這個檔案加一個ZIP或JAR字尾名,然後再解壓一次。

1.4  安裝及編寫HelloWorld例項(CVS:V0001版)

本機安裝環境:WindowsXP + JDK1.4.2_06 + Tomcat5.0.28 + SOAP2.3.1

1.4.1  複製JAR檔案

1、安裝JDK和Tomcat。這樣的文章網上遍地都是,本文不再細述。它們的安裝也很簡單:安裝JDK基本是一直單擊“下一步”,裝完後我沒有設定任何環境變數,就也可以用了;Tomcat也基本是單擊“下一步”就能安裝完成。

2、分別在這四個包的解壓目錄中找到:xerces.jar、soap.jar、mail.jar、activation.jar(jaf的),將它們複製到Tomcat的“Tomcat 5.0/common/lib”目錄下,這個目錄是Tomcat的預設包目錄,在這個目錄中的所有包在Tomcat啟動時都會被自動載入。

3、將c:/jdk/lib/路徑下的tools.jar也複製到Tomcat的“Tomcat 5.0/common/lib”目錄下。

注:在顯示SOAP的管理頁面需要用到這個包,設定classpath指向c:/jdk/lib/tools.jar是沒有用的,我也從來沒有將tools.jar包加入到classpath中,也沒有設定JDK_HOME,也沒有將c:/jdk/bin加入到path路徑中,基本我安裝JDK時什麼都沒有做。

4、將soap解壓目錄的webapps目錄下的soap.war檔案,複製到Tomcat的“Tomcat 5.0/webapps”目錄下,這個目錄是Tomcat的WEB應用所在目錄,soap.war是SOAP的網站,如下圖所示:

5、重啟Tomcat服務。這時Tomcat會將“Tomcat 5.0/common/lib”目錄下新加入的包載入到記憶體中。

1.4.2  編寫SOAP程式

編寫SOAP程式分三大步:

l           編寫伺服器端的程式,此程式和普通程式沒有什麼區別

l           配置SOAP,將相關請求指向到伺服器端的程式

l           編寫客戶端的程式,客戶端的程式帶有很深的SOAP的烙印,裡面會用到很多SOAP包的類和方法。

由於我習慣用Eclipse來寫程式,以後專案也是用Eclipse來開發,所以這裡的SOAP程式也是用Eclipse來寫的。當然你也可以用記事本+JDK也編寫SOAP程式。

1、配置mysoap專案的庫引用。

將下圖所示的四個JAR包加入到專案的庫引用中。關於庫引用的設定,這裡是用“使用者庫”的方式,具體操作可以參閱這篇文章:http://blog.csdn.net/glchengang/archive/2005/02/17/291522.aspx  。在完成庫引用之後,Eclipse編寫的SOAP程式時才能使用soap相關的類。

2、建立一個新的java專案mysoap,在專案裡建立一個包“cn.com.chengang.soap.hello”,然後在包中建立兩個Java檔案,如下圖所示:

(1)HelloWorldService.java是伺服器端的程式,其程式碼如下。這個程式中只有一個方法,和其他Java程式沒有什麼差別,該方法也也很簡單就是返回一個HelloWorld字串

package cn.com.chengang.soap.hello;

public class HelloWorldService {

    public String getMessage() {

        return "Hello World!";

    }

}

(2)HelloWorldClient.java是客戶端的訪問程式,其程式碼如下:

package cn.com.chengang.soap.hello;

import java.net.URL;

import org.apache.soap.Constants;

import org.apache.soap.Fault;

import org.apache.soap.rpc.Call;

import org.apache.soap.rpc.Parameter;

import org.apache.soap.rpc.Response;

public class HelloWorldClient {

    public static void main(String args[]) throws Exception {

        String endPoint = "http://localhost:8080/soap/servlet/rpcrouter";

        Call call = new Call();//建立一個RPC Call

        call.setTargetObjectURI("urn:HelloWorldService");//遠端的服務名

        call.setMethodName("getMessage");//訪問方法

        call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); //設定編碼風格

        URL url = new URL(endPoint); //SOAP服務的網址

         //開始傳送RPC請求,並返回伺服器端的應答

        Response resp = call.invoke(url, "");

        //檢查應答報文中是否有錯

//有錯就打印出錯資訊,沒錯就列印到正確的返回值HelloWorld

        if (resp.generatedFault()) {

            Fault fault = resp.getFault();

            System.out.println("The Following Error Occured: ");

            System.out.println("  Fault Code = " + fault.getFaultCode());

            System.out.println("  Fault String =" + fault.getFaultString());

        } else {

            Parameter result = resp.getReturnValue();

            System.out.println(result.getValue());

        }

    }

}

這個程式的用到了很多SOAP的類。注意:如果是兩臺電腦的話,那麼HelloWorldService.java和HelloWorldClient.java是分別獨立安裝在兩臺電腦上的,HelloWorldClient中的程式程式碼就是通過SOAP服務來呼叫HelloWorldService中的getMessage方法。

4、將HelloWorldService.java的編譯檔案HelloWorldService.class複製到Tomcat中,操作步驟如下:

(1)在“導航器”檢視的bin目錄下找到HelloWorldService.class檔案。

(2)在“Tomcat 5.0/common/classes/”路徑下新建一個“cn/com/chengang/soap/hello”目錄結構,這個目錄結構要和HelloWorldService.class的所在包名一樣的。然後將HelloWorldService.class檔案複製到此目錄下,如下圖所示。

注:還有一種方法是比較普遍使用的,就是將所有伺服器端的class檔案打成一個JAR包,然後將這個JAR包放在“Tomcat 5.0/common/lib”目錄下。

5、重啟Tomcat。

這一步不要忘記了,只有重啟Tomcat才能將common下新加入的JAR包或class檔案載入到記憶體中。

1.4.3  釋出SOAP伺服器端的程式:HelloWorldService.java

有多種方法可讓HelloWorldService這個程式註冊到SOAP服務中,本文介紹的是編寫XML檔案來註冊SOAP服務的方法

(1)HelleWorld.xml檔案。此檔案可以放置到任何地方,它和HelloWorldService.java的位置沒有必然的關係。

<?xml version="1.0"?>

<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment" id="urn:HelloWorldService">

    <isd:provider type="java" scope="Request" methods="getMessage">

        <isd:java class="cn.com.chengang.soap.hello.HelloWorldService" static="false"/>

    </isd:provider>

</isd:service>

程式碼說明:

l           urn:HelloWorldService是服務名,它要求系統唯一。這裡是取成和類名相同,你也可以取其他名稱。

l           getMessage是提供的服務方法,也就是類HelloWorldService的方法名

l           <isd:java class=要求填入全類名(包名+類名)

(2)設定兩個環境變數。之所以要設定這兩個變數是因為接下來的釋出命令的需要。

TOMCAT_HOME  =  E:/Program Files/Apache Software Foundation/Tomcat 5.0

classpath  =  %TOMCAT_HOME%/common/lib/soap.jar;%TOMCAT_HOME%/common/lib
/mail.jar;%TOMCAT_HOME%/common/lib/activation.jar;%TOMCAT_HOME%/common/lib/xerces.jar

(3)進入DOS視窗,並定位到HelloWorld.xml所在的目錄,然後執行如下命令(一行)。如果執行正確,則應該沒有任何顯示;如果命令錯誤則會輸出錯誤資訊。

java  org.apache.soap.server.ServiceManagerClient http://127.0.0.1:8080/soap/servlet/rpcrouter  deploy  HelloWorld.xml

另外,再介紹其他兩個常用的命令:

顯示已經註冊的SOAP服務:

java org.apache.soap.server.ServiceManagerClient http://127.0.0.1:8080/soap/servlet/rpcrouter list

取消釋出:

java org.apache.soap.server.ServiceManagerClient http://127.0.0.1:8080/soap/servlet/rpcrouter undelpoy "urn:HelloWorldService"

 命令的執行過程如下:(我把xml檔案放在e:/soaptest目錄下,該目錄就這一個檔案)

你也可以進入SOAP網站的去看看是否註冊成功了。

1.4.4  執行客戶端

在Eclipse中,將HelloWorldClient.java象一個普通Java應用程式那樣執行,得到如下結果:

可見客戶端程式HelloWorldClient通過SOAP服務呼叫了HelloWorldService的getMessage方法,並得到了一個返回結果。

在這裡我們並沒有編寫傳輸的XML檔案(前面的XML是註冊服務用的,不是一回事),這是因為SOAP包已經為我們自動完成了生成XML並傳輸到伺服器的過程。

1.5  帶引數的方法呼叫(CVS:V0002版)

上面的HelloWorld的例項中,getMessage方法是沒有引數的,這一節我們來加一個引數。

(1)將HelloWorldService.java修改如下:

package cn.com.chengang.soap.hello;

public class HelloWorldService {

    public String getMessage() {

        return "Hello World!";

    }

    public String getMessage(String str) {

        return "Hello World! " + str;

    }

    public String getMessage(String str1, String str2) {

        return "Hello World! " + str1 + "&" + str2;

    }

}

(2)將HelloWorldService.class複製到Tomcat的“Tomcat 5.0/common/classes/cn/com/chengang/soap/hello”目錄下,覆蓋原來的HelloWorldService.class。

(3)重啟Tomcat服務。

(4)修改HelloWorldClient程式如下(紅字部份是新加的):

package cn.com.chengang.soap.hello;

import java.net.URL;

import java.util.Vector;

import org.apache.soap.Constants;

import org.apache.soap.Fault;

import org.apache.soap.rpc.Call;

import org.apache.soap.rpc.Parameter;

import org.apache.soap.rpc.Response;

public class HelloWorldClient {

    public static void main(String args[]) throws Exception {

        String endPoint = "http://localhost:8080/soap/servlet/rpcrouter";

        Call call = new Call();//建立一個RPC Call

        call.setTargetObjectURI("urn:HelloWorldService");//遠端的服務名

        call.setMethodName("getMessage");//訪問方法

        call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); //設定編碼風格

        Vector params = new Vector();

        Parameter p1 = new Parameter("name", String.class, "陳剛", null);

        Parameter p2 = new Parameter("name2", String.class, "陳勇", null);

        params.addElement(p1);

        params.addElement(p2);

        call.setParams(params);

        URL url = new URL(endPoint); //SOAP服務的網址

        //開始傳送RPC請求,並返回伺服器端的應答

        Response resp = call.invoke(url, "");

        //檢查應答報文中是否有錯

        //有錯就打印出錯資訊,沒錯就列印到正確的返回值HelloWorld

        if (resp.generatedFault()) {

            Fault fault = resp.getFault();

            System.out.println("The Following Error Occured: ");

            System.out.println("  Fault Code = " + fault.getFaultCode());

            System.out.println("  Fault String =" + fault.getFaultString());

        } else {

            Parameter result = resp.getReturnValue();

            System.out.println(result.getValue());

        }

    }

}

(6)在Eclipse中執行HelloWorldClient,得到如下效果

參考資料