監(jiān)理公司管理系統(tǒng) | 工程企業(yè)管理系統(tǒng) | OA系統(tǒng) | ERP系統(tǒng) | 造價咨詢管理系統(tǒng) | 工程設計管理系統(tǒng) | 甲方項目管理系統(tǒng) | 簽約案例 | 客戶案例 | 在線試用
X 關閉

使用.Net, Java或者MS SOAP Toolkit 創(chuàng)建Web服務

申請免費試用、咨詢電話:400-8352-114

AMTeam.org

使用.Net, Java或者MS SOAP Toolkit 創(chuàng)建Web服務

本文將介紹如何使用下列三種語言中的任一種建立web服務以及客戶端程序:.NET,MS SOAP Tookkit和Java.但是本文的主旨還是要告訴你如何使用上面提到的語言來建立web服務的客戶端程序.

在不久以前.NET被發(fā)布了而且我們中的許多人開始急著編寫ASP.NET web站點,C#程序或是Web Services.我當時真的驚訝于人們能夠使用.NET相對容易的編寫web服務.我以前曾用MS SOAP Toolkit和Apache SOAP for Java編寫過一些web服務.然后有人要求我用不同的語言為這些web服務編寫客戶端程序.這被事實證明了是不容易的.雖然SOAP現(xiàn)在已經(jīng)成為標準,但是web服務的不同實現(xiàn)情況有時使得與其它SOAP的互聯(lián)性很差,如果不是不可能的話.

我的例子程序是只有一個方法--addNumbers的非常簡單的web服務.你可能已經(jīng)猜出來了,它能夠?qū)蓚€數(shù)字相加然后返回結(jié)果.這個程序的名字叫Hello2其源代碼附在本文上.

STK 服務和客戶端

首先讓我們使用MS SOAP Toolkit,ASP 監(jiān)聽程序和一個ISAPI監(jiān)聽程序來編寫一個Web 服務.

Visual Basic類中的addNumbers方法是:

Public Function addNumbers(ByVal NumberOne As Double, ByVal NumberTwo As Double) As Double

addNumbers = NumberOne + NumberTwo

End Function

用WSDLGen.exe向?qū)Я梢陨蒊SAPI監(jiān)聽器,ASP監(jiān)聽器或是同時產(chǎn)生兩者(當然也可以分開產(chǎn)生).我的選擇是同時產(chǎn)生ASP和ISAPI監(jiān)聽器,所以我將我的WSDL文件分別命名Hello2ASP.WSDL 和Hello2Isapi.WSDL.
現(xiàn)在燃我們?yōu)檫@個Hello2 web服務寫一些客戶端.

STK 客戶端

第一個客戶端是一個Visual Basic客戶端程序,使用SOAP Toolkit中高層的API.創(chuàng)建一個VB工程并添加一個窗體和按鈕.下面的代碼在按鈕被點擊的時候執(zhí)行.

Private Sub cmdDoTest_Click()

Const WS_URL = "
http://localhost/Hello2/Hello2Isapi.WSDL"

Dim objHello2ISapi As SoapClient

Dim nResult As Double, NumberOne As Double, NumberTwo As Double

On Error GoTo catch_err

Set objHello2ISapi = New SoapClient

Call objHello2ISapi.mssoapinit(WS_URL)

NumberOne = 10

NumberTwo = 25

nResult = objHello2ISapi.addNumbers(NumberOne, NumberTwo)

MsgBox nResult

cleanup:

Set objHello2ISapi = Nothing

Exit Sub

catch_err:

MsgBox Err.Description

Resume cleanup

End Sub

你可以發(fā)現(xiàn)客戶端非常簡單而且沒有什么疑難.所有建立SOAP請求消息和解析返回的SOAP消息的過程被隱藏了,程序員無法看見.WS_URL是服務的URL.SOAP Toolkit中高層的API需要一個WSDL文件所以這個URL指向一個這樣的WSDL文件.你提供哪一個并不重要,雖然使用ISAPI監(jiān)聽器的性能要好一些.

Java客戶端

我們?yōu)镠ello2服務程序編寫的第二個客戶端程序是一個Java程序.我對這個程序使用了Apache SOAP 2.1.你可以免費從
http://xml.apache.org/soap/index.html下載.

ASP監(jiān)聽器所使用的Java類程序如下:

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;

public class testClient {

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

URL url = new URL ("http://localhost/Hello2/Hello2.asp");

SOAPMappingRegistry smr = new SOAPMappingRegistry ();

StringDeserializer sd = new StringDeserializer ();

smr.mapTypes (Constants.NS_URI_SOAP_ENC, new QName ("", "Result"), null, null, sd);

// 創(chuàng)建傳輸路徑和參數(shù)

SOAPHTTPConnection st = new SOAPHTTPConnection();

// 創(chuàng)建調(diào)用

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(new Parameter("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("Caught SOAPException (" + 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());

}

}

}

正如你所看見的url變量指向ASP監(jiān)聽器.要將Java客戶端指向ISAPI監(jiān)聽器只需要做如下修改:

URL url = new URL ("
http://localhost/Hello2/Hello2Isapi.wsdl");

.NET客戶端

現(xiàn)在是時候為我們的Hello2 web服務寫一個.NET客戶端了.必須為我們的服務用 .NET Framework Beta 2 的WSD.exe工具來生成一個代理類.運行下面的命令.

wsdl http://localhost/Hello2/Hello2Isapi.wsdl

它將生成文件Hello2Isapi.cs.這是一個用C#(它是缺省的語言)寫成的.NET代理類.你可以查到wsdl.exe的參數(shù)來生成用VB.NET或者其它語言寫成的代理.現(xiàn)在用下面的命令編譯代理

csc.exe /t:library Hello2Isapi.cs

可以編寫.NET客戶端了,它使用代理類來訪問Hello2 web服務.下面是C#客戶端的代碼.

using System;

public class Hello2ISapiClient {

public static void Main() {

Hello2Isapi srv = new Hello2Isapi();

double res = 0, num1 = 10, num2 = 25;

res = srv.addNumbers(num1, num2);

Console.WriteLine("{0}+{1}={2}", num1, num2, res);

}

}

用Hello2IsapiClient.cs /reference:Hello2Isapi.dll編譯客戶端然后和Hello2IsapiClient一起運行它.

現(xiàn)在我們有了一個MS SOAP Toolkit web服務程序和三個客戶端,分別用:SOAP Toolkit, Java 和.NET 寫成.

用Apache SOAP編寫Java服務器端和客戶端

讓我們繼續(xù)用Apache SOAP來編寫Java語言的同樣的web 服務.下面是服務器端:

package samples.MyService;

import java.util.*;

import org.w3c.dom.*;

import org.apache.soap.util.xml.*;

public class MyService {

public double addNumbers(double num1, double num2) {

return num1+num2;

}

}

我將我的服務取名為MyService并將它添加到samples包里.這樣你就不必在Tomcat服務器里添加上下文.只需要用下面的啟用描述文件將這個服務添加到SOAP里:

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

<isd:provider type="java" scope="Application" methods="addNumbers">

<isd:java class="samples.MyService.MyService" static="false"/>

</isd:provider>

</isd:service>

我不會在這里解釋如何將Apache SOAP設置成Tomcat因為在Apache SOAP文件里有足夠的指導.

Apache SOAP客戶端

我們可以為這個服務編寫客戶端了.第一個是用Java寫的.下面是源代碼:

package samples.MyService;

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.*;

public class client {

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

if (args.length != 3

&& (args.length != 4 || !args[0].startsWith("-")))

{

System.err.println("Usage:");

System.err.println(" java " + client.class.getName() +

" [-encodingStyleURI] SOAP-router-URL nameToLookup");

System.exit (1);

}

// 處理參數(shù)

int offset = 4 - args.length;

String encodingStyleURI = args.length == 4

? args[0].substring(1)

: Constants.NS_URI_SOAP_ENC;

URL url = new URL(args[1 - offset]);

Double num1 = new Double(args[2 - offset]),

num2 = new Double(args[3 - offset]);

SOAPMappingRegistry smr = new SOAPMappingRegistry();

BeanSerializer beanSer = new BeanSerializer();

System.out.println(encodingStyleURI);

System.out.println(url);

System.out.println(num1);

System.out.println(num2);

// 建立調(diào)用

Call call = new Call();

call.setSOAPMappingRegistry(smr);

call.setTargetObjectURI("urn:MyService");

call.setMethodName("addNumbers");

call.setEncodingStyleURI(encodingStyleURI);

Vector params = new Vector();

params.addElement(new Parameter("num1", Double.class, num1, null));

params.addElement(new Parameter("num2", Double.class, num2, null));

call.setParams(params);

// 啟動調(diào)用過程

Response resp;

long nErrors = 0;

Calendar cal = Calendar.getInstance();

Date startTime = cal.getTime(), endTime;

try {

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

}

catch (SOAPException e) {

System.out.println("i=" + i);

System.err.println("Caught SOAPException (" +

e.getFaultCode() + "): " +

e.getMessage());

return;

}

// 檢查返回值

if (!resp.generatedFault()) {

Parameter ret = resp.getReturnValue();

Object value = ret.getValue();

//System.out.println(value != null ? "n" + value : "I don't know.");
}

else {

Fault fault = resp.getFault();

System.err.println("Generated fault: ");

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

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

}

cal = Calendar.getInstance();

endTime = cal.getTime();

System.out.println("Start time="+startTime);

System.out.println("End time="+endTime);

System.out.println ("Errors=" + nErrors);

}

}

如你所見,代碼是非常直觀的.應該沒有什么問題因為我們使用了相同的SOAP庫.一個STK客戶端的代碼如下:

STK Client

在高層次的和低層次的客戶端程序里都存在錯誤因為在Apache SOAP for Java里需要xsi:類型.

.NET客戶端

因為同樣的問題.NET客戶端也不會正常工作.

.NET服務和客戶端

.NET Framework Beta 2 是最新的技術而且在Bata 2版本到最終版本發(fā)布可能還會有改動.在Beta2發(fā)布的時候主要的改變已經(jīng)完成了.微軟已經(jīng)警告開發(fā)者有可能發(fā)生改動,所以這也就不奇怪了.

使用.NET編寫一個web服務是很簡單的而且可以用幾種方法完成.我選擇在ASMX文件里用C#編寫我的web服務程序.下面是文件的內(nèi)容.

using System;

using System.Web.Services;

[WebService(Namespace="http://www.catalin.com/webservices/")]

public class MyService: WebService {

[ WebMethod(Description="return the sum of two numbers")]

[System.Web.Services.Protocols.SoapRpcMethodAttribute(

"
http://www.catalin.com/webservices/addNumbers",

RequestNamespace="
http://www.catalin.com/webservices/",

ResponseNamespace="
http://www.catalin.com/webservices/")]

public double addNumbers(double numberOne, double numberTwo) {

return numberOne + numberTwo;

}

}

使用ASMX文件的好處是不需要進行編譯,所以可以很快的使用這個程序.將文件放到IIS下的一個虛擬路徑里.你可以用IE和http://localhost/testdotnetws/myservice.asmx .NET 客戶端來測試這個服務程序.為這個服務編寫一個客戶端與我們前面寫的.NET程序類似.在生成代理文件的時候?qū)SDL文件設置成http://localhost/testdotnetws/myservice.asmx?WSDL.這也是.NET framework用命令行產(chǎn)生WSDL文件的方式.

STK客戶端

使用高層次的API會更快一些但是有一些問題我無法解決所以我使用了低層次的API.客戶端程序并不復雜.唯一的技巧是使.NET服務對RPC形式的調(diào)用可用.感謝Christian Weyer幫我解決了這個問題.看一看web服務程序的代碼并注意我們方法的System.Web.Services.Protocols.SoapRpcMethodAttribute屬性.沒有這個屬性的話,.NET中程序?qū)υ挼娜笔☆愋途褪窍⒘?

Java客戶端

在java客戶端中你需要將url改成如下所示:

URL url = new URL ("http://localhost/aspnet_test/myservice/myservice.asmx");

編譯運行

我希望這次對web服務世界的簡短歷程能夠幫助你們那些致力于web服務開發(fā)的人.

祝你的SOAP過程快樂!

發(fā)布:2007-03-24 18:00    編輯:泛普軟件 · xiaona    [打印此頁]    [關閉]
相關文章:
上海OA系統(tǒng)
聯(lián)系方式

成都公司:成都市成華區(qū)建設南路160號1層9號

重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務大廈18樓

咨詢:400-8352-114

加微信,免費獲取試用系統(tǒng)

QQ在線咨詢