WebService_java編寫Webservice_Axis2_1.6

 最近給某省國家電網寫一套系統,因爲內部數據庫單向隔離裝置不支持ODBC, 原來c#寫的webservice 和.net ,iis就須要換成java這一套。。。javascript

下面是用Axis2 寫的webservice 的例子html


Axis2是一套嶄新的WebService引擎,該版本是對Axis1.x從新設計的產物。Axis2不只支持SOAP1.1和SOAP1.2,還集成了很是流行的REST WebService,同時還支持Spring、JSON等技術。這些都將在後面的系列教程中講解。在本文中主要介紹瞭如何使用Axis2開發一個不須要任何配置文件的WebService,並在客戶端使用Java和C#調用這個WebService。java

1、Axis2的下載和安裝程序員

   讀者能夠從以下的網址下載Axis2的最新版本:web

   http://ws.apache.org/axis2/數據庫

   在本文使用了目前Axis2的最新版本1.4.1。讀者能夠下載以下兩個zip包:apache

   axis2-1.4.1-bin.zip編程

   axis2-1.4.1-war.zipc#

   其中axis2-1.4.1-bin.zip文件中包含了Axis2中全部的jar文件, axis2-1.4.1-war.zip文件用於將WebService發佈到Web容器中。windows

   將axis2-1.4.1-war.zip文件解壓到相應的目錄,將目錄中的axis2.war文件放到<Tomcat安裝目錄>\webapps目錄中(本文使用的Tomcat的版本是6.x),並啓動Tomcat。

   在瀏覽器地址欄中輸入以下的URL:

   http://localhost:8080/axis2/

   若是在瀏覽器中顯示出如圖1所示的頁面,則表示Axis2安裝成功。



圖1



2、編寫和發佈WebService

  對於用Java實現的服務程序給人的印象就是須要進行大量的配置,不過這一點在Axis2中將被終結。在Axis2中不須要進行任何的配置,就能夠直接將一個簡單的POJO發佈成WebService。其中POJO中全部的public方法將被髮布成WebService方法。

   下面咱們來實現一個簡單的POJO,代碼以下:

public class SimpleService
{
    public String getGreeting(String name)
    {
        return "你好 " + name;
    }    
    public int getPrice()
    {
        return new java.util.Random().nextInt(1000);
    }    
}

   在SimpleService類中有兩個方法,因爲這兩個方法都是public方法,所以,它們都將做爲WebService方法被髮布。

   編譯SimpleService類後,將SimpleService.class文件放到<Tomcat安裝目錄>\webapps\axis2\WEB-INF\pojo目錄中(若是沒有pojo目錄,則創建該目錄)。如今咱們已經成功將SimpleService類發佈成了WebService。在瀏覽器地址欄中輸入以下的URL:

http://localhost:8080/axis2/services/listServices

   這時當前頁面將顯示全部在Axis2中發佈的WebService,如圖2所示。



圖2



   在瀏覽器地址欄中輸入以下的兩個URL來分別測試getGreeting和getPrice方法:

http://localhost:8080/axis2/services/SimpleService/getGreeting?name=bill

http://localhost:8080/axis2/services/SimpleService/getPrice

    圖3和圖4分別顯示了getGreeting和getPrice方法的測試結果。

 

圖3  getGreeting方法的測試結果


 

圖4  getPrice方法的測試結果



   在編寫、發佈和測試0配置的WebService時應注意以下幾點:

   1. POJO類不能使用package關鍵字聲明包。

   2. Axis2在默認狀況下能夠熱發佈WebService,也就是說,將WebService的.class文件複製到pojo目錄中時,Tomcat不須要從新啓動就能夠自動發佈WebService。若是想取消Axis2的熱發佈功能,能夠打開<Tomcat安裝目錄>\webapps\axis2\WEB-INF\conf\axis2.xml,找到以下的配置代碼:

<parameter name="hotdeployment">true</parameter>

   將true改成false便可。要注意的是,Axis2在默認狀況下雖然是熱發佈,但並非熱更新,也就是說,一旦成功發佈了WebService,再想更新該WebService,就必須重啓Tomcat。這對於開發人員調試WebService很是不方便,所以,在開發WebService時,能夠將Axis2設爲熱更新。在axis2.xml文件中找到<parametername="hotupdate">false</parameter>,將false改成true便可。

   3. 在瀏覽器中測試WebService時,若是WebService方法有參數,須要使用URL的請求參數來指定該WebService方法參數的值,請求參數名與方法參數名要一致,例如,要測試getGreeting方法,請求參數名應爲name,如上面的URL所示。

   4. 發佈WebService的pojo目錄只是默認的,若是讀者想在其餘的目錄發佈WebService,能夠打開axis2.xml文件,並在<axisconfig>元素中添加以下的子元素:

    <deployer extension=".class" directory="my" class="org.apache.axis2.deployment.POJODeployer"/>

   上面的配置容許在<Tomcat安裝目錄>\webapps\axis2\WEB-INF\my目錄中發佈WebService。例如,將本例中的SimpleService.class複製到my目錄中也能夠成功發佈(但要刪除pojo目錄中的SimpleService.class,不然WebService會重名)。

3、 用Java實現調用WebService的客戶端程序

   WebService是爲程序服務的,只在瀏覽器中訪問WebService是沒有意義的。所以,在本節使用Java實現了一個控制檯程序來調用上一節發佈的WebService。調用WebService的客戶端代碼以下:

package client;

import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

public class RPCClient
{
    public static void main(String[] args) throws Exception  
    {
        //  使用RPC方式調用WebService        
        RPCServiceClient serviceClient = new RPCServiceClient();
        Options options = serviceClient.getOptions();
        //  指定調用WebServiceURL
        EndpointReference targetEPR = new EndpointReference(
                "http://localhost:8080/axis2/services/SimpleService");
        options.setTo(targetEPR);
        //  指定getGreeting方法的參數值
        Object[] opAddEntryArgs = new Object[] {"超人"};
        //  指定getGreeting方法返回值的數據類型的Class對象
        Class[] classes = new Class[] {String.class};
        //  指定要調用的getGreeting方法及WSDL文件的命名空間
        QName opAddEntry = new QName("http://ws.apache.org/axis2", "getGreeting");
        //  調用getGreeting方法並輸出該方法的返回值
        System.out.println(serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs, classes)[0]);
        //  下面是調用getPrice方法的代碼,這些代碼與調用getGreeting方法的代碼相似
        classes = new Class[] {int.class};
        opAddEntry = new QName("http://ws.apache.org/axis2", "getPrice");
        System.out.println(serviceClient.invokeBlocking(opAddEntry, new Object[]{}, classes)[0]);
    } 
}

運行上面的程序後,將在控制檯輸出以下的信息:

 

你好 超人
443

   在編寫客戶端代碼時應注意以下幾點:

   1. 客戶端代碼須要引用不少Axis2的jar包,若是讀者不太清楚要引用哪一個jar包,能夠在Eclipse的工程中引用Axis2發行包的lib目錄中的全部jar包。

   2. 在本例中使用了RPCServiceClient類的invokeBlocking方法調用了WebService中的方法。invokeBlocking方法有三個參數,其中第一個參數的類型是QName對象,表示要調用的方法名;第二個參數表示要調用的WebService方法的參數值,參數類型爲Object[];第三個參數表示WebService方法的返回值類型的Class對象,參數類型爲Class[]。當方法沒有參數時,invokeBlocking方法的第二個參數值不能是null,而要使用new Object[]{}。

   3. 若是被調用的WebService方法沒有返回值,應使用RPCServiceClient類的invokeRobust方法,該方法只有兩個參數,它們的含義與invokeBlocking方法的前兩個參數的含義相同。

   4. 在建立QName對象時,QName類的構造方法的第一個參數表示WSDL文件的命名空間名,也就是<wsdl:definitions>元素的targetNamespace屬性值,下面是SimpleService類生成的WSDL文件的代碼片斷:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd"
xmlns:ns
="http://ws.apache.org/axis2" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:http
="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mime
="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12
="http://schemas.xmlsoap.org/wsdl/soap12/"
targetNamespace
="http://ws.apache.org/axis2"
>
    <wsdl:types>
         
    </wsdl:types>
     
</wsdl:definitions>

4、用wsdl2java簡化客戶端的編寫

   也許有不少讀者會說「有沒有搞錯啊,只調用兩個WebService方法用要寫這麼多代碼,太麻煩了」。

   不過幸虧Axis2提供了一個wsdl2java.bat命令能夠根據WSDL文件自動產生調用WebService的代碼。wsdl2java.bat命令能夠在<Axis2安裝目錄>"bin目錄中找到。在使用wsdl2java.bat命令以前須要設置AXIS2_HOME環境變量,該變量值是<Axis2安裝目錄>。

   在Windows控制檯輸出以下的命令行來生成調用WebService的代碼:

%AXIS2_HOME%\bin\wsdl2java-uri http://localhost:8080/axis2/services/SimpleService?wsdl -p client -s -ostub

   其中-url參數指定了wsdl文件的路徑,能夠是本地路徑,也能夠是網絡路徑。-p參數指定了生成的Java類的包名,-o參數指定了生成的一系列文件保存的根目錄。在執行完上面的命令後,讀者就會發如今當前目錄下多了個stub目錄,在."stub"src"client目錄能夠找到一個SimpleServiceStub.java文件,該文件複雜調用WebService,讀者能夠在程序中直接使用這個類,代碼以下:

package client;

import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

public class StubClient
{
    public static void main(String[] args) throws Exception  
    {
        SimpleServiceStub stub = new SimpleServiceStub();
        SimpleServiceStub.GetGreeting gg = new SimpleServiceStub.GetGreeting();
        gg.setName("比爾");
        System.out.println( stub.getGreeting(gg).get_return());
        System.out.println(stub.getPrice().get_return());
    } 
}

   上面的代碼大大簡化了調用WebService的步驟,並使代碼更加簡潔。但要注意的是,wsdl2java.bat命令生成的Stub類將WebService方法的參數都封裝在了相應的類中,類名爲方法名,例如,getGreeting方法的參數都封裝在了GetGreeting類中,要想調用getGreeting方法,必須先建立GetGreeting類的對象實例。

5、使用C#調用WebService

   從理論上說,WebService能夠被任何支持SOAP協議的語言調用。在Visual Studio中使用C#調用WebService是在全部語言中最容易實現的(VB.net的調用方法相似,也一樣很簡單)。

   新建一個VisualStudio工程,並在引用Web服務的對話框中輸入以下的URL,並輸入Web引用名爲「WebService」:

   http://localhost:8080/axis2/services/SimpleService?wsdl

   而後引用Web服務的對話框就會顯示該WebService中的全部的方法,如圖5所示。



圖5


   在完成上面的工做後,只須要以下三行C#代碼就能夠調用getGreeting和getPrice方法,並顯示這兩個方法的返回值:

WebService.SimpleService simpleService = new WSC.WebService.SimpleService();
MessageBox.Show( simpleService.getGreeting("比爾"));
MessageBox.Show(simpleService.getPrice().@return.ToString());

   在.net解析WSDL文件時直接將getGreeting方法的參數映射爲String類型,所以,能夠直接進行傳值。
    從上面的調用過程能夠看出,添加Web引用的過程就至關於在Java中調用wsdl2java.bat自動生成stub類的過程。只是在調用stub類時與C#有必定的區別,但從整體上來講,都大大簡化了調用WebService的過程。

 

1.  什麼是webservice
從表面上看,Webservice 就是一個應用程序,它向外界暴露出一個可以經過Web進行調用的API。這就是說,你可以用編程的方法經過Web來調用這個應用程序。
對Webservice 更精確的解釋: Web services是創建可互操做的分佈式應用程序的新平臺。做爲一個Windows程序員,你可能已經用COM或DCOM創建過基於組件的分佈式應用程序。COM是一個很是好的組件技術,可是咱們也很容易舉出COM並不能知足要求的狀況。Web service平臺是一套標準,它定義了應用程序如何在Web上實現互操做性。你能夠用任何你喜歡的語言,在任何你喜歡的平臺上寫Web service ,只要咱們能夠經過Web service標準對這些服務進行查詢和訪問。
無論你的Webservice是用什麼工具,什麼語言寫出來的,只要你用SOAP協議經過HTTP來調用它,整體結構都應以下圖所示。一般,你用你本身喜歡的語言(如VB 6或者VB.NET)來構建你的Web service,而後用SOAP Toolkit或者.NET的內建支持來把它暴露給Web客戶。因而,任何語言,任何平臺上的客戶均可以閱讀其WSDL文檔,以調用這個Web service。客戶根據WSDL描述文檔,會生成一個SOAP請求消息。Web service都是放在Web服務器 (如IIS) 後面的,客戶生成的SOAP請求會被嵌入在一個HTTP POST請求中,發送到Web服務器來。Web服務器再把這些請求轉發給Web service請求處理器。對VB 6程序來講,Web service請求處理器是一個與SOAP Toolkit組件協同工做的ASP頁面或ISAPI extension。而對VB.NET程序來講,Web service請求處理器則是一個.NET Framework自帶的ISAPI extension。請求處理器的做用在於,解析收到的SOAP請求,調用Web service,而後再生成相應的SOAP應答。Web服務器獲得SOAP應答後,會再經過HTTP應答的方式把它送回到客戶端。

2.  基本概念
SOAP 
Web service建好之後,其餘人就會去調用它。簡單對象訪問協議(SOAP)提供了標準的遠程過程調用( RPC)方法來調用Web service。SOAP規範定義了SOAP消息的格式,以及怎樣經過HTTP協議來使用SOAP。SOAP也是基於XML和XSD的,XML是SOAP的數據編碼方式。客戶端和服務端之間的方法調用請求和結果返回值都放在這些消息裏。
       XML和XSD
可擴展的標記語言(XML)是Web service平臺中表示數據的基本格式。除了易於創建和易於分析外,XML主要的優勢在於它既是平臺無關的,又是廠商無關的。無關性是比技術優越性更重要的。XML解決了數據表示的問題,但它沒有定義一套標準的數據類型,更沒有說怎麼去擴展這套數據類型。例如,整形數到底表明什麼?16位,32位,仍是64位?這些細節對實現互操做性都是很重要的。W3C制定的XMLSchema(XSD)就是專門解決這個問題的一套標準。它定義了一套標準的數據類型,並給出了一種語言來擴展這套數據類型。Web service平臺就是用XSD來做爲其數據類型系統的。當用某種語言(如VB.NET或C#)來構造一個Web service時,爲了符合Web service標準,全部使用的數據類型都必須被轉換爲XSD類型。
       WSDL(Web Services Description Language)
用於描述服務端所提供服務的XML格式。WSDL文件裏,描述了服務端提供的服務,提供的調用方法,以及調用時所要遵循的格式,好比調用參數和返回值的格式等等。WSDL 很像COM編程裏的IDL(Interface Description Language),是服務器與客戶端之間的契約,雙方必須按契約嚴格行事才能實現功能。
   WSML(Web Services Meta Language)
用於描述WSDL裏提供的方法與實現該方法的COM對象之間的映射關係。該文件是Microsoft的實現中特有的,不是SOAP標準的一部分。通常狀況下,該文件只在服務端存在。

3.Webservice的技術特色
長項一: 跨防火牆的通訊
若是應用程序有成千上萬的用戶,並且分佈在世界各地,那麼客戶端和服務器之間的通訊將是一個棘手的問
題。由於客戶端和服務器之間一般會有防火牆或者代理服務器。在這種狀況下,使用DCOM就不是那麼簡單,一般也不便於把客戶端程序發佈到數量如此龐大的每個用戶手中。傳統的作法是,選擇用瀏覽器做爲客戶端,寫下一大堆ASP頁面,把應用程序的中間層暴露給最終用戶。這樣作的結果是開發難度大,程序很難維護。
舉個例子,在應用程序里加入一個新頁面,必須先創建好用戶界面(Web頁面),並在這個頁面後面,包含相應商業邏輯的中間層組件,還要再創建至少一個ASP頁面,用來接受用戶輸入的信息,調用中間層組件,把結果格式化爲HTML形式,最後還要把「結果頁」送回瀏覽器。要是客戶端代碼再也不如此依賴於HTML表單,客戶端的編程就簡單多了。
若是中間層組件換成WebService的話,就能夠從用戶界面直接調用中間層組件,從而省掉創建ASP頁面的那一步。要調用Web Service,能夠直接使用Microsoft SOAP Toolkit或.NET這樣的SOAP客戶端,也可使用本身開發的SOAP客戶端,而後把它和應用程序鏈接起來。不只縮短了開發週期,還減小了代碼複雜度,並可以加強應用程序的可維護性。同時,應用程序也再也不須要在每次調用中間層組件時,都跳轉到相應的「結果頁」。
從經驗來看,在一個用戶界面和中間層有較多交互的應用程序中,使用Web Service這種結構,能夠節省花在用戶界面編程上20%的開發時間。另外,這樣一個由Web Service組成的中間層,徹底能夠在應用程序集成或其它場合下重用。最後,經過Web Service把應用程序的邏輯和數據「暴露」出來,還可讓其它平臺上的客戶重用這些應用程序。
長項二: 應用程序集成
企業級的應用程序開發者都知道,企業裏常常都要把用不一樣語言寫成的、在不一樣平臺上運行的各類程序集成起來,而這種集成將花費很大的開發力量。應用程序常常須要從運行在IBM主機上的程序中獲取數據;或者把數據發送到主機或UNIX應用程序中去。即便在同一個平臺上,不一樣軟件廠商生產的各類軟件也經常須要集成起來。經過Web Service,應用程序能夠用標準的方法把功能和數據「暴露」出來,供其它應用程序使用。
例如,有一個訂單登陸程序,用於登陸從客戶來的新訂單,包括客戶信息、發貨地址、數量、價格和付款方式等內容;還有一個訂單執行程序,用於實際貨物發送的管理。這兩個程序來自不一樣軟件廠商。一份新訂單進來以後,訂單登陸程序須要通知訂單執行程序發送貨物。經過在訂單執行程序上面增長一層Web Service,訂單執行程序能夠把「Add Order」函數「暴露」出來。這樣,每當有新訂單到來時,訂單登陸程序就能夠調用這個函數來發送貨物了。
長項三:B2B的集成
用WebService集成應用程序,可使公司內部的商務處理更加自動化。但當交易跨越供應商和客戶、突破公司的界限時會怎麼樣呢?跨公司的商務交易集成一般叫作B2B集成。
Web Service是B2B集成成功的關鍵。經過Web Service,公司能夠把關鍵的商務應用「暴露」給指定的供應商和客戶。例如,把電子下單系統和電子發票系統「暴露」出來,客戶就能夠以電子的方式發送訂單,供應商則能夠以電子的方式發送原料採購發票。固然,這並非一個新的概念, EDI(電子文檔交換)早就是這樣了。可是,Web Service的實現要比EDI簡單得多,並且Web Service運行在Internet上,在世界任何地方均可輕易實現,其運行成本就相對較低。不過,Web Service並不像EDI那樣,是文檔交換或B2B集成的完整解決方案。Web Service只是B2B集成的一個關鍵部分,還須要許多其它的部分才能實現集成。
用WebService來實現B2B集成的最大好處在於能夠輕易實現互操做性。只要把商務邏輯「暴露」出來,成爲Web Service,就可讓任何指定的合做夥伴調用這些商務邏輯,而無論他們的系統在什麼平臺上運行,使用什麼開發語言。這樣就大大減小了花在B2B集成上的時間和成本,讓許多本來沒法承受EDI的中小企業也能實現B2B集成。

長項四: 軟件和數據重用
軟件重用是一個很大的主題,重用的形式不少,重用的程度有大有小。最基本的形式是源代碼模塊或者類一級的重用,另外一種形式是二進制形式的組件重用。

當前,像表格控件或用戶界面控件這樣的可重用軟件組件,在市場上都佔有很大的份額。但這類軟件的重用有一個很大的限制,就是重用僅限於代碼,數據不能重用。緣由在於,發佈組件甚至源代碼都比較容易,但要發佈數據就沒那麼容易,除非是不會常常變化的靜態數據。
Web Service在容許重用代碼的同時,能夠重用代碼背後的數據。使用Web Service,不再必像之前那樣,要先從第三方購買、安裝軟件組件,再從應用程序中調用這些組件;只須要直接調用遠端的Web Service就能夠了。舉個例子,要在應用程序中確認用戶輸入的地址,只需把這個地址直接發送給相應的Web Service,這個Web Service 就會幫你查閱街道地址、城市、省區和郵政編碼等信息,確認這個地址是否在相應的郵政編碼區域。Web Service 的提供商能夠按時間或使用次數來對這項服務進行收費。這樣的服務要經過組件重用來實現是不可能的,那樣的話你必須下載並安裝好包含街道地址、城市、省區和郵政編碼等信息的數據庫,並且這個數據庫仍是不能實時更新的。
另外一種軟件重用的狀況是,把好幾個應用程序的功能集成起來。例如,要創建一個局域網上的門戶站點應用,讓用戶既能夠查詢聯邦快遞包裹,查看股市行情,又能夠管理本身的日程安排,還能夠在線購買電影票。如今Web上有不少應用程序供應商,都在其應用中實現了這些功能。一旦他們把這些功能都經過Web Service 「暴露」出來,就能夠很是容易地把全部這些功能都集成到你的門戶站點中,爲用戶提供一個統一的、友好的界面。
未來,許多應用程序都會利用Web Service,把當前基於組件的應用程序結構擴展爲組件/Web Service 的混合結構,能夠在應用程序中使用第三方的Web Service 提供的功能,也能夠把本身的應用程序功能經過Web Service 提供給別人。兩種狀況下,均可以重用代碼和代碼背後的數據。

4.如何調用webservice
4.0 webservice的調用過程
    客戶端:取得服務端的服務描述文件WSDL,解析該文件的內容,瞭解服務端的服務信息,以及調用方式。根據須要,生成恰當的SOAP請求消息(指定調用的方法,已經調用的參數),發往服務端。等待服務端返回的SOAP迴應消息,解析獲得返回值。
服務端:生成服務描述文件,以供客戶端獲取。接收客戶端發來的SOAP請求消息,解析其中的方法調用和參數格式。根據WSDL和WSML的描述,調用相應的COM對象來完成指定功能,並把返回值放入SOAP迴應消息返回給用戶。
高層接口
    使用高層接口,不須要知道SOAP和XML的任何信息,就能夠生成和使用一個WebService。Soap Toolkit 2.0經過提供兩個COM對象――SoapClient和SoapServer,來完成這些功能。
     在客戶端,只須要生成一個SoapClient實例,並用WSDL做爲參數來調用其中的mssoapinit方法。SoapClient對象會自動解析WSDL文件,並在內部生成全部Web Service的方法和參數信息。以後,你就能夠像調用IDispatch接口裏的方法同樣,調用裏面全部的方法。在VB或是腳本語言裏,你甚至能夠直接在SoapClient對象名後面直接加上.方法(參數…)進行調用。
低層接口
    要使用低層接口,你必須對SOAP和XML有所瞭解。你能夠對SOAP的處理過程進行控制,特別是要作特殊處理的時候。
在客戶端,首先要建立一個HttpConnector對象,負責HTTP鏈接。設定Connector的一些頭部信息,好比EndPoinURL和SoapAction等。若是網絡鏈接須要使用代理服務器,那也要在這裏設定相關的信息。接着建立SoapSerializer對象,用於生成Soap消息。按照WSDL裏定義,把全部參數按順序序列化,獲得一個完整的SOAP請求消息。該Soap消息,做爲Payload經過HttpConnector被髮送到服務端。最後,生成一個SoapReader對象,負責讀取服務端返回的SOAP消息,取得其中的返回值。

4.1使用PowerBuilder調用
    適用版本8.0 需下載Bulletin Web Services Toolkit 4.1
4.2使用java調用
須要下載apachesoap。下載地址:http://xml.apache.org/soap/index.html
導入:
import org.apache.soap.*;
import org.apache.soap.rpc.*;
例程:
import java.io.*;
import java.util.*;
import java.net.*;
import org.w3c.dom.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
import org.apache.soap.transport.http.SOAPHTTPConnection;

publicclass testClient {

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

       URL url = new URL ("http://192.168.0.4/yundan/service1.wsdl");
//改爲你的地址
        SOAPMappingRegistry smr = newSOAPMappingRegistry ();
        StringDeserializer sd = newStringDeserializer ();
        smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName ("", "Result"), null,null, sd);

       // 建立傳輸路徑和參數
        SOAPHTTPConnection st = newSOAPHTTPConnection();

       // 建立調用
        Call call = new Call ();
        call.setSOAPTransport(st);
        call.setSOAPMappingRegistry (smr);

       call.setTargetObjectURI ("http://tempuri.org/message/");
        call.setMethodName("addNumbers");
        call.setEncodingStyleURI("http://schemas.xmlsoap.org/soap/encoding/");

       Vector params = new Vector();
        params.addElement(newParameter("NumberOne", Double.class, "10", null));
        params.addElement(new Parameter("NumberTwo",Double.class, "25", null));
        call.setParams(params);

       Response resp = null;

       try {
          resp = call.invoke (url,"http://tempuri.org/action/Hello2.addNumbers");
        }
        catch (SOAPException e) {
        System.err.println("CaughtSOAPException (" + e.getFaultCode () + "): " + e.getMessage ());
        return;
        }

       // 檢查返回值
        if (resp != null &&!resp.generatedFault()) {
        Parameter ret =resp.getReturnValue();
        Object value = ret.getValue();

       System.out.println ("Answer--> " + value);
        }
        else {
            Fault fault= resp.getFault ();
           System.err.println ("Generated fault: ");
           System.out.println (" Fault Code = " + fault.getFaultCode());
           System.out.println (" Fault String = " + fault.getFaultString());
        }
    }
}

4.3 在asp中使用Jscript調用
需下載msSoapToolkit20.exe
引用:MSSOAP.SoapClient
    例程:
    <%@ LANGUAGE = JScript %>
<HTML>
<HEAD>
<TITLE>webservice演示</TITLE>
</HEAD>
<BODY>
    <%
         var WSDL_URL ="http://server0/yundan/webservice1.asmx?WSDL"
           var a, b, res
           var soapclient
            a = 12
            b =13   
        soapclient =Server.CreateObject("MSSOAP.SoapClient")
       soapclient.ClientProperty("ServerHTTPRequest") = true
‘在ASP中運行 須要設置ServerHTTPRequest選項
soapclient.mssoapinit("http://192.168.0.4/yundan/Service1.WSDL","Service1","Service1Soap","")
        res = soapclient.test(2,3)
%>
<h3>webservice 演示</h3>
<B>Result:</B> <%=res%><P><P>
</BODY>
</HTML>
4. 4在asp中使用vbscript調用
需下載msSoapToolkit20.exe
引用:MSSOAP.SoapClient
    例程:
<%@ LANGUAGE = VBScript %>
<HTML>
<HEAD>
<TITLE>webservie演示</TITLE>
</HEAD>
<BODY>
<%
Dim soapclient
Const WSDL_URL = "http://192.168.0.4/yundan/service1.wsdl"
    set soapclient =Server.CreateObject("MSSOAP.SoapClient")
    soapclient.ClientProperty("ServerHTTPRequest") =True
    soapclient.mssoapinit
http://192.168.0.4:8080/yundan/Service1.WSDL","Service1","Service1Soap",""
Dim res
        res = soapclient.test(23, 34)
%>
<h1>webservie演示</h1>
<B>Result:</B> <%=res%><P><P>
</BODY>
</HTML>

4.5使用C#調用
無需下載任何組件
Visualà項目à新建 windows應用程序。àC#項目
在解決方案資源管理器中添加web引用,輸入wsdl文件所在地址。
將web引用更名.
yundan.(service_name)便可引用
*需引用System.web.services*
例程:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace csharp
{
        public class Form1 :System.Windows.Forms.Form
        {
            privateSystem.Windows.Forms.Label label1;
            privateSystem.Windows.Forms.TextBox textBox1;
            privateSystem.ComponentModel.Container components = null;
            publicForm1()
            {
               InitializeComponent();
            }
            protectedoverride void Dispose( bool disposing )
            {
               if( disposing )
               {
                   if (components != null)
                   {
                       components.Dispose();
                   }
               }
               base.Dispose( disposing );
            }
            #regionWindows Form Designer generated code
            private voidInitializeComponent()
            {
               this.label1 = new System.Windows.Forms.Label();
               this.textBox1 = new System.Windows.Forms.TextBox();
               this.SuspendLayout();
               this.label1.AutoSize = true;
               this.label1.Location = new System.Drawing.Point(88, 48);
               this.label1.Name = "label1";
               this.label1.Size = new System.Drawing.Size(91, 14);
               this.label1.TabIndex = 0;
               this.label1.Text = "Webservice演示";
               this.textBox1.Location = new System.Drawing.Point(88, 128);
               this.textBox1.Name = "textBox1";
               this.textBox1.TabIndex = 1;
               this.textBox1.Text = "textBox1";
               this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
               this.ClientSize = new System.Drawing.Size(292, 273);
               this.Controls.AddRange(new System.Windows.Forms.Control[]
{
               this.textBox1,
               this.label1
});
               this.Name = "Form1";
               this.Text = "C#Webservie演示";
               this.Load += new System.EventHandler(this.Form1_Load);
               this.ResumeLayout(false);
            }
            #endregion
            [STAThread]
            static voidMain()
            {
               Application.Run(new Form1());
            }

           private void Form1_Load(object sender, System.EventArgs e)
            {
               int str;
               你的web引用的名字.Service1cc=new 你的web引用的名字.Service1();
               str=cc.test(123,324);
               textBox1.Text=str.ToString();
            }
        }
}

 

4.6(javascript)

需下載msSoapToolkit20.exe
引用:MSSOAP.SoapClient
    例程:
var WSDL_URL = "http://192.168.0.4/yundan/service1.wsdl"
WScript.echo("Connecting: " + WSDL_URL)
var Calc = WScript.CreateObject("MSSOAP.SoapClient")
Calc.mssoapinit(WSDL_URL, "", "", "")
var Answer
Answer = Calc.test(14,28)
WScript.Echo("14+28=" + Answer)
將其存成domo.js文件,直接雙擊運行。

4.7使用vb.net調用
無需下載任何組件
Visualà項目à新建 windows應用程序。àBasic項目
在解決方案資源管理器中添加web引用,輸入wsdl文件所在地址。
將web引用更名爲yundan.
yundan.(service_name)便可引用
*需引用System.web.services*
例程:
    Public Class Form1
        Inherits System.Windows.Forms.Form
#Region " Windows 窗體設計器生成的代碼 "
    Public Sub New()
        MyBase.New()
        InitializeComponent()
    End Sub
    Protected Overloads Overrides Sub Dispose(ByVal disposing AsBoolean)
        If disposing Then
            If Not(components Is Nothing) Then
               components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub
    Private components As System.ComponentModel.IContainer
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
    <System.Diagnostics.DebuggerStepThrough()> Private SubInitializeComponent()
        Me.Label1 = NewSystem.Windows.Forms.Label()
        Me.TextBox1 = NewSystem.Windows.Forms.TextBox()
        Me.SuspendLayout()
        Me.Label1.AutoSize = True
        Me.Label1.Location = NewSystem.Drawing.Point(96, 40)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = NewSystem.Drawing.Size(91, 14)
        Me.Label1.TabIndex = 0
        Me.Label1.Text = "Webservice演示"
        Me.TextBox1.Location = NewSystem.Drawing.Point(88, 144)
        Me.TextBox1.Name ="TextBox1"
        Me.TextBox1.TabIndex = 1
        Me.TextBox1.Text ="TextBox1"
        Me.AutoScaleBaseSize = NewSystem.Drawing.Size(6, 14)
        Me.ClientSize = NewSystem.Drawing.Size(292, 273)
        Me.Controls.AddRange(NewSystem.Windows.Forms.Control() {Me.TextBox1, Me.Label1})
        Me.Name = "Form1"
        Me.Text = "VB.net webserive演示"
        Me.ResumeLayout(False)
    End Sub
#End Region
    Private Sub Form1_Load(ByVal sender As System.Object, ByVale As System.EventArgs) Handles MyBase.Load
        Dim cc As yundan.Service1 = Newyundan.Service1()
        TextBox1.Text = cc.test(12, 123)
    End Sub
End Class

4.8使用vb6.0調用
需下載msSoapToolkit20.exe
添加引用:MicrosoftSoap Type Library
位置:」C:\ProgramFiles\Common Files\MSSoap\Binaries\ MSSOAP1.dll」
    調用方法:
    Dim cc As New MSSOAPLib.SoapClient
    例程:
    添加一個button控件Command1à添加3個textbox控件,text1,text2,text3à標準EXEà新建工程
    代碼以下:
    Option Explicit
Dim cc As New MSSOAPLib.SoapClient
Private Sub Command1_Click()
cc.mssoapinit "http://192.168.0.4/yundan/Service1.asmx?WSDL"
Me.Text3.Text = cc.test(CInt(Text1.Text), CInt(Text2.Text))
End Sub
4.9使用vbscript調用
需下載msSoapToolkit20.exe
引用:MSSOAP.SoapClient
    例程:
Option Explicit
Const WSDL_URL = "http://192.168.0.4/yundan/service1.wsdl"
WScript.echo "Connecting: " & WSDL_URL
Dim Calc
Set Calc = CreateObject("MSSOAP.SoapClient")
Calc.mssoapinit WSDL_URL
Dim Answer
Answer = Calc.test(14,28)
WScript.Echo "14+28=" & Answer
將其存成domo.vbs文件,直接雙擊運行。

4.10使用vc調用
需下載msSoapToolkit20.exe
    引用
#import "msxml3.dll"
using namespace MSXML2;
#import "C:\Program Files\Common Files\MSSoap\Binaries\mssoap1.dll"exclude("IStream", "ISequentialStream","_LARGE_INTEGER", "_ULARGE_INTEGER","tagSTATSTG", "_FILETIME") raw_interfaces_only
using namespace MSSOAPLib;
例程:
新建工程àMFCAppWizard(exe)[ Mclient]àstep1à基本對話à其餘默認值便可
修改源文件:
< StdAfx.h>
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if!defined(AFX_STDAFX_H__045CD307_9518_4AF1_8CE3_8FFE38D1ACB2__INCLUDED_)
#define AFX_STDAFX_H__045CD307_9518_4AF1_8CE3_8FFE38D1ACB2__INCLUDED_

#if_MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#defineVC_EXTRALEAN        // Exclude rarely-usedstuff from Windows headers

#include<afxwin.h>         // MFC core andstandard components
#include <afxext.h>         //MFC extensions
#include <afxdisp.h>        // MFCAutomation classes
#include <afxdtctl.h>       // MFC supportfor Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>         //MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

 

#import"msxml3.dll"
using namespace MSXML2;

#import"C:\Program Files\Common Files\MSSoap\Binaries\mssoap1.dll"exclude("IStream", "ISequentialStream","_LARGE_INTEGER", "_ULARGE_INTEGER","tagSTATSTG", "_FILETIME") raw_interfaces_only
using namespace MSSOAPLib;


#define MSG(message) \
{ \
    ::MessageBox(NULL,_T(message),NULL,MB_OK |MB_ICONEXCLAMATION| MB_APPLMODAL);\
    goto cleanup; \
}


#define CHECK_HRESULT(hr, message) \
if (FAILED(hr)) \
{ \
    MSG(message); \
}


//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately beforethe previous line.

#endif// !defined(AFX_STDAFX_H__045CD307_9518_4AF1_8CE3_8FFE38D1ACB2__INCLUDED_)
<MClient.h>
// MClient.h : main header file for the MCLIENT application
//

#if!defined(AFX_MCLIENT_H__9A397DA6_5A62_4AEF_BE5E_6C7629322ECC__INCLUDED_)
#define AFX_MCLIENT_H__9A397DA6_5A62_4AEF_BE5E_6C7629322ECC__INCLUDED_

#if_MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef__AFXWIN_H__
    #error include 'stdafx.h' before including this file for PCH
#endif

#include"resource.h"       // main symbols

/////////////////////////////////////////////////////////////////////////////
// CMClientApp:
// See MClient.cpp for the implementation of this class
//

classCMClientApp : public CWinApp
{
public:
    CMClientApp();

//Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMClientApp)
    public:
    virtual BOOL InitInstance();
    /

<MClientDlg.h>
    // MClientDlg.h : header file
//

#if!defined(AFX_MCLIENTDLG_H__C2D8DBC4_30FE_40DD_848C_78D5834CAD07__INCLUDED_)
#define AFX_MCLIENTDLG_H__C2D8DBC4_30FE_40DD_848C_78D5834CAD07__INCLUDED_

#if_MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/////////////////////////////////////////////////////////////////////////////
// CMClientDlg dialog

classCMClientDlg : public CDialog
{
// Construction
public:
    void EnableButtons();
    void DisableButtons();
    void AssignpRef(VARIANT *var1, VARIANT *var2);
    void assignItem(LVITEM *item, UINT mask, int iItem, intiSubItem, LPTSTR pszText, int cchTextMax);
    int UpdateList();
    bool DestroyTree();
    int CheckforURL();
    int ModifyDialog();
    void Execute();
    int nCountParameter();
    HTREEITEM AddtoTree(HTREEITEM hParent, HTREEITEMhInsertAfter, LPTSTR pszData, UINT mask, IUnknown * theInterface);
    CMClientDlg(CWnd* pParent = NULL);    //standard constructor

//Dialog Data
    //{{AFX_DATA(CMClientDlg)
    enum { IDD = IDD_MCLIENT_DIALOG };
    CTreeCtrl    m_TreeCtrl;
    CListCtrl    m_Parameters;
    CString    m_strParameter;
    CString    m_strURL;
    /

<MClientDlg.cpp>
    // MClientDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MClient.h"
#include "MClientDlg.h"
#include "Atlbase.h"

#ifdef_DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMClientDlg dialog

CMClientDlg::CMClientDlg(CWnd*pParent /*=NULL*/)
    : CDialog(CMClientDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CMClientDlg)
    m_strParameter = _T("");
    m_strURL = _T("");
    /

//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::Execute()
//
//  parameters: No Parameters
//
//  description: Pass the parameters and invoke the operation, get theresult and update the
//              parameters and the result value
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::Execute()
{
    USES_CONVERSION;

   DisableButtons();

   HTREEITEM               hItem;
   HTREEITEM               hPort;
   HTREEITEM               hService;

   DISPPARAMS               parms;
   
   VARIANT                   result;
   VARIANT                   vTempVariable;

   CComPtr<ISOAPClient>   pClient            =    NULL;
   HRESULT                hr                =    S_OK;

   BSTR                   bstrPort         =  0;
   BSTR                   bstrService      =  0;
   BSTR                   bstrWSDLFileName =  0;
   BSTR                   bstrWSMLFileName =  0;

   LVITEM                   Item;
   LVITEM                   Item1;

   int                       nNumParameters;
   int                       nCounter;
   int                       nCount;
   
   DISPID                   dispidFn;
   
   WCHAR                   *pstrFunctionName;

   char                    name[1024] ;

   EXCEPINFO              excepinfo;

   VARTYPE                vt              =  VT_EMPTY;

   hItem                   =    m_TreeCtrl.GetSelectedItem();
      dispidFn               =    0;

   excepinfo.wCode              = 1001;
   excepinfo.wReserved          = 0;
   excepinfo.bstrSource          = 0;
    excepinfo.bstrDescription     = 0;
   excepinfo.bstrHelpFile        = 0;
    excepinfo.dwHelpContext      = 0;
    excepinfo.pvReserved         = 0;
    excepinfo.pfnDeferredFillIn   = 0;
   excepinfo.scode              = 0;
   
   VARIANT                variantbstrtemp;
   VARIANT                   *pArg = 0;
   VARIANT                   *pRef = 0;

   smIsInputEnum          IsInput;

   nNumParameters         =   nCountParameter();

   if (nNumParameters != -1)
    {
        pArg = new VARIANT[nNumParameters];
        pRef = new VARIANT[nNumParameters];
    }
    else
        MSG("Could not get parametersfrom parameter list!");

   if ((!pArg) ||  (!pRef))
        MSG("There is no enoughmemory!");


    if (m_TreeCtrl.ItemHasChildren(hItem))
        MSG("Please select anoperation!");

 


    hr    = CoCreateInstance(__uuidof(SoapClient), NULL, CLSCTX_INPROC_SERVER, __uuidof(ISOAPClient),
                           (void **)&pClient);
    CHECK_HRESULT(hr, "Can not create the  object ofthe CLSID_SoapClient");


    if (!pClient)
        MSG("Can not create the object of the CLSID_SoapClient!");


    // we need to have wsdl file and port and service name formssoapinit
       hPort  =m_TreeCtrl.GetParentItem(hItem);
    if (!hPort)
        MSG("Can not get Port!");
   
    bstrPort = m_TreeCtrl.GetItemText(hPort).AllocSysString();
    if (bstrPort == NULL)
        MSG("Can not get PortName!");

   
    hService = m_TreeCtrl.GetParentItem(hPort);
    if (!hService)
        MSG("Can not get Service!");
   
    bstrService =m_TreeCtrl.GetItemText(hService).AllocSysString();
    if (bstrService == NULL)
        MSG("Can not get ServiceName!");


    bstrWSDLFileName =  m_strURL.AllocSysString();
    if (bstrWSDLFileName == NULL)
        MSG("Can not get WSDL fileName!");

   hr =pClient->mssoapinit(bstrWSDLFileName,bstrService,bstrPort,bstrWSMLFileName);
    CHECK_HRESULT(hr, "Soap initiation failed");

   // get the selected functions name
    pstrFunctionName     =   m_TreeCtrl.GetItemText(hItem).AllocSysString();
    if (pstrFunctionName == NULL)
        MSG("Could not get functionName!");

   parms.cArgs               = nNumParameters ;
    parms.cNamedArgs        =0;
    parms.rgdispidNamedArgs = 0;
    //there is a pass by ref, and I  will use pRef asparameter list
   parms.rgvarg           = pRef;

   ::VariantInit(&result);
    ::VariantInit(&vTempVariable);

   nCount = 0;
    // the loop should be 'number of parameters' times
    for (nCounter=0; nCounter <m_Parameters.GetItemCount()  ; nCounter ++)
    {
        // I need to get the value ofparameter and its type
        assignItem(&Item, LVIF_PARAM,nCounter,0,0,0);
        assignItem(&Item1,LVIF_TEXT,nCounter,2,name,sizeof(name));

       if (m_Parameters.GetItem(&Item) == 0)
           MSG("Could not get item!");
        if (m_Parameters.GetItem(&Item1)== 0)
           MSG("Could not get item!");
       
        // we will not fill the argumentswith result
        reinterpret_cast<ISoapMapper*>(Item.lParam)->get_isInput(&IsInput);
        if (IsInput != smOutput)
        {
           ::VariantInit(&pArg[nCount]);
            // I have tofill this array in reverse order bacause the server expects it in reverse order
           ::VariantInit(&pRef[nNumParameters - nCount -1]);

           // I keep the parameter as BSTR
           vTempVariable.vt = VT_BSTR;
           vTempVariable.bstrVal = ::SysAllocString(A2W(Item1.pszText));

           // the conversion for type and value of parameter is done
            // thevalue  with correct type and value is  taken into pArg
           long    ltype;
           
            hr =(reinterpret_cast<ISoapMapper*>(Item.lParam))->get_variantType(&ltype);
           CHECK_HRESULT(hr, "Could not get Variant Type");

           hr =::VariantChangeType(&pArg[nCount],&vTempVariable,VARIANT_NOUSEROVERRIDE,(unsigned short) ltype);
            CHECK_HRESULT(hr,"Can not convert Variant Type! Either no Function selected or Parameter isWrong or Empty");
           
           ::VariantClear(&vTempVariable);
            // assignthe correct parameter to pRef and indicate it is BYREF
            pRef[nNumParameters- nCount -1 ].vt      = pArg[nCount].vt | VT_BYREF;
           AssignpRef(&pRef[nNumParameters - nCount -1],&pArg[nCount]);
            nCount ++;
        }
    }
 
    // get the ID of operation
    hr    = pClient->GetIDsOfNames(IID_NULL, &pstrFunctionName, 1,LOCALE_SYSTEM_DEFAULT, &dispidFn);
    CHECK_HRESULT(hr, "Taking IDs Failed!");

   // calling the operation
    ::VariantClear(&result);

   hr    =  pClient->Invoke(dispidFn, IID_NULL,LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &parms,
                           &result, &excepinfo, 0);
    CHECK_HRESULT(hr, "Function call Failed!");

   ::VariantInit(&variantbstrtemp);

   // update the results

   for(nCounter = 0; nCounter <  m_Parameters.GetItemCount() ; nCounter++)
    {
        if (nCounter < nNumParameters)
        {
            hr =::VariantChangeType(&variantbstrtemp,&pArg[nCounter],VARIANT_NOUSEROVERRIDE,VT_BSTR);
        }
        else
        {
            hr =::VariantChangeType(&variantbstrtemp,&result,VARIANT_NOUSEROVERRIDE,VT_BSTR);
        }

       CHECK_HRESULT(hr, "Variant could not be converted");

       CString Text(variantbstrtemp.bstrVal);
        assignItem(&Item,LVIF_TEXT,nCounter,2,(LPTSTR)(LPCTSTR)Text,::SysStringLen(variantbstrtemp.bstrVal));

       if (m_Parameters.SetItem(&Item) == 0)
           MSG("Could not set Item to list");  
    }

   UpdateData(false);
   
cleanup:
    for(nCounter = 0; nCounter < nNumParameters ; nCounter++)
    {
        ::VariantClear(&pArg[nCounter]);
        ::VariantClear(&pRef[nCounter]);
    }

   ::VariantClear(&result);
    ::VariantClear(&variantbstrtemp);
    ::VariantClear(&vTempVariable);
    ::SysFreeString(bstrPort);
    ::SysFreeString(bstrService);
       ::SysFreeString(bstrWSDLFileName);
   
    if (pArg)
        delete [] pArg;
    if (pRef)
        delete [] pRef;

   EnableButtons();
    return;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnDeleteitemListparam()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for each row of list, it calls the Release
//
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnDeleteitemListparam(NMHDR* pNMHDR, LRESULT* pResult)
{
// We have to release lParam that I filled with object of ISoapMapper
    NMLISTVIEW   *tempVar = (NMLISTVIEW*)pNMHDR;;

   if (reinterpret_cast <IUnknown*>(tempVar->lParam))
        (reinterpret_cast <IUnknown*>(tempVar->lParam))->Release();
   
    *pResult = 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnDeleteitemTree()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for each tree elements, it calls the Release method
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnDeleteitemTree(NMHDR* pNMHDR, LRESULT* pResult)
{
    // We have to release lParam that I filled with object
    NMTREEVIEW   *tempVar = (NMTREEVIEW*)pNMHDR;;
    if (reinterpret_cast<IUnknown*>(tempVar->itemOld.lParam))
        (reinterpret_cast<IUnknown*>(tempVar->itemOld.lParam))->Release();

   *pResult = 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnSelchangedTree()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for selection on tree, it updates the list
//
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
    // if the selected is operation, update the list with itsparameters
    NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)pNMHDR;


    IUnknown *pUnk = reinterpret_cast<IUnknown*>(pNMTreeView->itemNew.lParam);

   if (! pUnk)
        return;

   IWSDLOperation *pOper = 0;

   m_strParameter.Empty();
    UpdateData(false);

   if(SUCCEEDED(pUnk->QueryInterface(__uuidof(IWSDLOperation),reinterpret_cast<void **>(&pOper))))
    {
        if (UpdateList() != 1)
           MSG("Parameter list can not be created!");
    }

   *pResult = 0;

cleanup:
    if (pOper)
        pOper->Release();
   
    return;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnLoad()
//
//  parameters: No Parameters
//
//  description:  takes the service, ports and operations and fillsthe tree
//
//  returns: void
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnLoad()
{
    USES_CONVERSION;

   UpdateData(true);
// chech if wsdl file is given, if not, return
    if (CheckforURL() == -1)
        return;

//delete the tree if exist, if a tree exist and cant be deleted, return
    if (!DestroyTree())
        return;

   HRESULT                           hr                       =    S_OK;

   BSTR                           bstrWSDLFileName        =   0;
   BSTR                           bstrServiceName           =    0;
   BSTR                           bstrPortName           =    0;
   BSTR                           bstrOperationName        =   0;
   int                            flag                   =   1;
   int                            flag_SERVICE           =   0;
   int                            flag_PORT              =   0;
    int                            flag_OPERATION         =   0;

   CComPtr<IEnumWSDLService>       pIEnumWSDLServices;
   CComPtr<IEnumWSDLPorts>           pIEnumWSDLPorts;
    CComPtr<IEnumWSDLOperations>   pIEnumWSDLOps;
    CComPtr<IWSDLOperation>           pIOperation;
   CComPtr<IWSDLReader>           pIWSDLReader;
   CComPtr<IWSDLService>           pIWSDLService;
   CComPtr<IWSDLPort>               pIWSDLPort;

   long                           cFetched;

   HTREEITEM                       hSERVICE;
   HTREEITEM                       hPORT;
   HTREEITEM                       hOPERATION;

   // take the name of wsdl file
    bstrWSDLFileName =  m_strURL.AllocSysString();

   if (bstrWSDLFileName == NULL)
        return;

   hr = CoCreateInstance(__uuidof(WSDLReader), NULL, CLSCTX_INPROC_SERVER,__uuidof(IWSDLReader),
                       (void**)&pIWSDLReader);
    CHECK_HRESULT(hr, "Can not create the  object ofthe CLSID_WSDLReader");

   // loading needs wsdl and wsml files, but I dont know wsml file and I pass""
    hr = pIWSDLReader->Load(bstrWSDLFileName,L"");   
       CHECK_HRESULT(hr, "Loading WSDL andWSML files failed!");

   // get soap service
    hr =pIWSDLReader->GetSoapServices(&pIEnumWSDLServices);
    CHECK_HRESULT(hr, "Can not get Services");

   if (!pIEnumWSDLServices)
        MSG("Can not getServices");

   while((hr = pIEnumWSDLServices->Next(1, &pIWSDLService, &cFetched))== S_OK)
    {
        // at least one time this loopshould go inside; if it does not, the flag wont be updated
        // so we can not continue and shoulddestroy the tree if any part created
        flag_SERVICE  =   1;
        // get service name
        hr =pIWSDLService->get_name(&bstrServiceName);
        CHECK_HRESULT(hr, "Can not getService names");

       // add the name of service in to tree
        // first field is NULL, it meansinsert this as root
        hSERVICE=AddtoTree(NULL,TVI_SORT,W2A(bstrServiceName),TVIF_TEXT,pIWSDLService);
        ::SysFreeString(bstrServiceName);
        if (!hSERVICE)
        {
            flag = 0;
            gotocleanup;
        }

       hr = pIWSDLService->GetSoapPorts(&pIEnumWSDLPorts);
        CHECK_HRESULT(hr, "Can not getPorts");

       if (!pIEnumWSDLPorts)
           MSG("Can not get Ports");

       while((hr = pIEnumWSDLPorts->Next(1,&pIWSDLPort, &cFetched)) ==S_OK)
        {
            // at leastone time this loop should go inside; if it does not, the flag wont be updated
            // so we cannot continue and should destroy the tree if any part created
           flag_PORT  =   1;
             // getport name
            hr =pIWSDLPort->get_name(&bstrPortName);
           CHECK_HRESULT(hr, "Can not get Port names");

           // add to tree but as a child of SERVICE
            hPORT=AddtoTree(hSERVICE,TVI_SORT,W2A(bstrPortName),TVIF_TEXT,pIWSDLPort);
           ::SysFreeString(bstrPortName);
            if (!hPORT)
            {
               flag = 0;
               goto cleanup;
            }

           hr = pIWSDLPort->GetSoapOperations(&pIEnumWSDLOps);
           CHECK_HRESULT(hr, "Can not get Operations");
            if(!pIEnumWSDLOps)
               MSG("Can not get Operations");

           while((hr = pIEnumWSDLOps->Next(1,&pIOperation, &cFetched)) == S_OK)
            {
             // atleast one time this loop should go inside; if it does not, the flag wont beupdated
             // sowe can not continue and should destroy the tree if any part created
               flag_OPERATION  =   1;

               hr = pIOperation->get_name(&bstrOperationName);
               CHECK_HRESULT(hr, "Can not get Operation names");

               hOPERATION= AddtoTree(hPORT,TVI_SORT,W2A(bstrOperationName),TVIF_TEXT,pIOperation);
               ::SysFreeString(bstrOperationName);
               if (!hOPERATION)
               {
                   flag = 0;
                   goto cleanup;
               }
               // we do release by assigning to 0
               pIOperation= 0;
            }
            if(flag_OPERATION == 0)
            {
               flag =0;
               MSG("Could not load  OPERATIONS!");
            }
            //// we dorelease by assigning to 0
            pIWSDLPort =0;
        }
        if (flag_PORT == 0)
        {
            flag =0;
           MSG("Could not load  PORTS!");
        }
        //// we do release by assigning to 0
        pIWSDLService = 0;
    }
   
    if (flag_SERVICE == 0)
    {
        flag =0;
        MSG("Could not load SERVICE!");
    }
    UpdateData(false);

cleanup:
    ::SysFreeString(bstrWSDLFileName);
       ::SysFreeString(bstrServiceName);
    ::SysFreeString(bstrPortName);
    ::SysFreeString(bstrOperationName);


    if (flag == 0)
        DestroyTree();

    return; }

相關文章
相關標籤/搜索