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

使用.Net, Java或者M(jìn)S SOAP Toolkit 創(chuàng)建Web服務(wù)

申請(qǐng)免費(fèi)試用、咨詢(xún)電話:400-8352-114

AMTeam.org

使用.Net, Java或者M(jìn)S SOAP Toolkit 創(chuàng)建Web服務(wù)

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

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

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

STK 服務(wù)和客戶(hù)端

首先讓我們使用MS SOAP Toolkit,ASP 監(jiān)聽(tīng)程序和一個(gè)ISAPI監(jiān)聽(tīng)程序來(lái)編寫(xiě)一個(gè)Web 服務(wù).

Visual Basic類(lèi)中的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)聽(tīng)器,ASP監(jiān)聽(tīng)器或是同時(shí)產(chǎn)生兩者(當(dāng)然也可以分開(kāi)產(chǎn)生).我的選擇是同時(shí)產(chǎn)生ASP和ISAPI監(jiān)聽(tīng)器,所以我將我的WSDL文件分別命名Hello2ASP.WSDL 和Hello2Isapi.WSDL.
現(xiàn)在燃我們?yōu)檫@個(gè)Hello2 web服務(wù)寫(xiě)一些客戶(hù)端.

STK 客戶(hù)端

第一個(gè)客戶(hù)端是一個(gè)Visual Basic客戶(hù)端程序,使用SOAP Toolkit中高層的API.創(chuàng)建一個(gè)VB工程并添加一個(gè)窗體和按鈕.下面的代碼在按鈕被點(diǎn)擊的時(shí)候執(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)客戶(hù)端非常簡(jiǎn)單而且沒(méi)有什么疑難.所有建立SOAP請(qǐng)求消息和解析返回的SOAP消息的過(guò)程被隱藏了,程序員無(wú)法看見(jiàn).WS_URL是服務(wù)的URL.SOAP Toolkit中高層的API需要一個(gè)WSDL文件所以這個(gè)URL指向一個(gè)這樣的WSDL文件.你提供哪一個(gè)并不重要,雖然使用ISAPI監(jiān)聽(tīng)器的性能要好一些.

Java客戶(hù)端

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

ASP監(jiān)聽(tīng)器所使用的Java類(lèi)程序如下:

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());

}

}

}

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

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

.NET客戶(hù)端

現(xiàn)在是時(shí)候?yàn)槲覀兊腍ello2 web服務(wù)寫(xiě)一個(gè).NET客戶(hù)端了.必須為我們的服務(wù)用 .NET Framework Beta 2 的WSD.exe工具來(lái)生成一個(gè)代理類(lèi).運(yùn)行下面的命令.

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

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

csc.exe /t:library Hello2Isapi.cs

可以編寫(xiě).NET客戶(hù)端了,它使用代理類(lèi)來(lái)訪問(wèn)Hello2 web服務(wù).下面是C#客戶(hù)端的代碼.

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編譯客戶(hù)端然后和Hello2IsapiClient一起運(yùn)行它.

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

用Apache SOAP編寫(xiě)Java服務(wù)器端和客戶(hù)端

讓我們繼續(xù)用Apache SOAP來(lái)編寫(xiě)Java語(yǔ)言的同樣的web 服務(wù).下面是服務(wù)器端:

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;

}

}

我將我的服務(wù)取名為MyService并將它添加到samples包里.這樣你就不必在Tomcat服務(wù)器里添加上下文.只需要用下面的啟用描述文件將這個(gè)服務(wù)添加到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>

我不會(huì)在這里解釋如何將Apache SOAP設(shè)置成Tomcat因?yàn)樵贏pache SOAP文件里有足夠的指導(dǎo).

Apache SOAP客戶(hù)端

我們可以為這個(gè)服務(wù)編寫(xiě)客戶(hù)端了.第一個(gè)是用Java寫(xiě)的.下面是源代碼:

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);

// 啟動(dòng)調(diào)用過(guò)程

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);

}

}

如你所見(jiàn),代碼是非常直觀的.應(yīng)該沒(méi)有什么問(wèn)題因?yàn)槲覀兪褂昧讼嗤腟OAP庫(kù).一個(gè)STK客戶(hù)端的代碼如下:

STK Client

在高層次的和低層次的客戶(hù)端程序里都存在錯(cuò)誤因?yàn)樵贏pache SOAP for Java里需要xsi:類(lèi)型.

.NET客戶(hù)端

因?yàn)橥瑯拥膯?wèn)題.NET客戶(hù)端也不會(huì)正常工作.

.NET服務(wù)和客戶(hù)端

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

使用.NET編寫(xiě)一個(gè)web服務(wù)是很簡(jiǎn)單的而且可以用幾種方法完成.我選擇在ASMX文件里用C#編寫(xiě)我的web服務(wù)程序.下面是文件的內(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文件的好處是不需要進(jìn)行編譯,所以可以很快的使用這個(gè)程序.將文件放到IIS下的一個(gè)虛擬路徑里.你可以用IE和http://localhost/testdotnetws/myservice.asmx .NET 客戶(hù)端來(lái)測(cè)試這個(gè)服務(wù)程序.為這個(gè)服務(wù)編寫(xiě)一個(gè)客戶(hù)端與我們前面寫(xiě)的.NET程序類(lèi)似.在生成代理文件的時(shí)候?qū)SDL文件設(shè)置成http://localhost/testdotnetws/myservice.asmx?WSDL.這也是.NET framework用命令行產(chǎn)生WSDL文件的方式.

STK客戶(hù)端

使用高層次的API會(huì)更快一些但是有一些問(wèn)題我無(wú)法解決所以我使用了低層次的API.客戶(hù)端程序并不復(fù)雜.唯一的技巧是使.NET服務(wù)對(duì)RPC形式的調(diào)用可用.感謝Christian Weyer幫我解決了這個(gè)問(wèn)題.看一看web服務(wù)程序的代碼并注意我們方法的System.Web.Services.Protocols.SoapRpcMethodAttribute屬性.沒(méi)有這個(gè)屬性的話,.NET中程序?qū)υ挼娜笔☆?lèi)型就是消息了.

Java客戶(hù)端

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

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

編譯運(yùn)行

我希望這次對(duì)web服務(wù)世界的簡(jiǎn)短歷程能夠幫助你們那些致力于web服務(wù)開(kāi)發(fā)的人.

祝你的SOAP過(guò)程快樂(lè)!

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

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

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

咨詢(xún):400-8352-114

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

QQ在線咨詢(xún)