Java_WebService应用举例

Axis2是一套崭新的WebService引擎,该版本是对Axis1.x重新设计的产物。Axis2不仅支持SOAP1.1和SOAP1.2,还集成了非常流行的RESTWebService,同时还支持Spring、JSON等技术。这些都将在后面的系列教程中讲解。在本文中主要介绍了如何使用Axis2开发一个不需要任何配置文件的WebService,并在客户端使用Java和C#调用这个WebService。

一、Axis2的下载和安装

读者可以从如下的网址下载Axis2的最新版本:

http://ws.apache.org/axis2/

在本文使用了目前Axis2的最新版本1.4.1。读者可以下载如下两个zip包:

axis2-1.4.1-bin.zip

axis2-1.4.1-war.zip

其中axis2-1.4.1-bin.zip文件中包含了Axis2中所有的jar文件,axis2-1.4.1-war.zip文件用于将WebService发布到Web容器中。

将axis2-1.4.1-war.zip文件解压到相应的目录,将目录中的axis2.war文件放到<Tomcat安装目录>\webapps目录中(本文使用的Tomcat的版本是6.x),并启动Tomcat。

在浏览器地址栏中输入如下的URL:

http://localhost:8080/axis2/

如果在浏览器中显示出如图1所示的页面,则表示Axis2安装成功。



1

二、编写和发布WebService

对于用Java实现的服务程序给人的印象就是需要进行大量的配置,不过这一点在Axis2中将被终结。在Axis2中不需要进行任何的配置,就可以直接将一个简单的POJO发布成WebService。其中POJO中所有的public方法将被发布成WebService方法。

下面我们来实现一个简单的POJO,代码如下:

publicclassSimpleService
{
publicStringgetGreeting(Stringname)
{
return"你好"+name;
}
publicintgetPrice()
{
returnnewjava.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方法的测试结果。

图3getGreeting方法的测试结果

图4getPrice方法的测试结果

在编写、发布和测试0配置的WebService时应注意如下几点:

1.POJO类不能使用package关键字声明包。

2.Axis2在默认情况下可以热发布WebService,也就是说,将WebService的.class文件复制到pojo目录中时,Tomcat不需要重新启动就可以自动发布WebService。如果想取消Axis2的热发布功能,可以打开<Tomcat安装目录>\webapps\axis2\WEB-INF\conf\axis2.xml,找到如下的配置代码:

<parametername="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>元素中添加如下的子元素:

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

上面的配置允许在<Tomcat安装目录>\webapps\axis2\WEB-INF\my目录中发布WebService。例如,将本例中的SimpleService.class复制到my目录中也可以成功发布(但要删除pojo目录中的SimpleService.class,否则WebService会重名)。

三、用Java实现调用WebService的客户端程序

WebService是为程序服务的,只在浏览器中访问WebService是没有意义的。因此,在本节使用Java实现了一个控制台程序来调用上一节发布的WebService。调用WebService的客户端代码如下:

packageclient;

importjavax.xml.namespace.QName;
importorg.apache.axis2.addressing.EndpointReference;
importorg.apache.axis2.client.Options;
importorg.apache.axis2.rpc.client.RPCServiceClient;

publicclassRPCClient
{
publicstaticvoidmain(String[]args)throwsException
{
//使用RPC方式调用WebService
RPCServiceClientserviceClient=newRPCServiceClient();
Optionsoptions=serviceClient.getOptions();
//指定调用WebServiceURL
EndpointReferencetargetEPR=newEndpointReference(
"http://localhost:8080/axis2/services/SimpleService");
options.setTo(targetEPR);
//指定getGreeting方法的参数值
Object[]opAddEntryArgs=newObject[]{"超人"};
//指定getGreeting方法返回值的数据类型的Class对象
Class[]classes=newClass[]{String.class};
//指定要调用的getGreeting方法及WSDL文件的命名空间
QNameopAddEntry=newQName("http://ws.apache.org/axis2","getGreeting");
//调用getGreeting方法并输出该方法的返回值
System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs,classes)[0]);
//下面是调用getPrice方法的代码,这些代码与调用getGreeting方法的代码类似
classes=newClass[]{int.class};
opAddEntry=newQName("http://ws.apache.org/axis2","getPrice");
System.out.println(serviceClient.invokeBlocking(opAddEntry,newObject[]{},classes)[0]);
}
}

运行上面的程序后,将在控制台输出如下的信息:

你好超人
443

在编写客户端代码时应注意如下几点:

1.客户端代码需要引用很多Axis2的jar包,如果读者不太清楚要引用哪个jar包,可以在Eclipse的工程中引用Axis2发行包的lib目录中的所有jar包。

2.在本例中使用了RPCServiceClient类的invokeBlocking方法调用了WebService中的方法。invokeBlocking方法有三个参数,其中第一个参数的类型是QName对象,表示要调用的方法名;第二个参数表示要调用的WebService方法的参数值,参数类型为Object[];第三个参数表示WebService方法的返回值类型的Class对象,参数类型为Class[]。当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用newObject[]{}。

3.如果被调用的WebService方法没有返回值,应使用RPCServiceClient类的invokeRobust方法,该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同。

4.在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,也就是<wsdl:definitions>元素的targetNamespace属性值,下面是SimpleService类生成的WSDL文件的代码片段:

<?xmlversion="1.0"encoding="UTF-8"?>
<wsdl:definitionsxmlns: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>

四、用wsdl2java简化客户端的编写

也许有很多读者会说“有没有搞错啊,只调用两个WebService方法用要写这么多代码,太麻烦了”。

不过幸好Axis2提供了一个wsdl2java.bat命令可以根据WSDL文件自动产生调用WebService的代码。wsdl2java.bat命令可以在<Axis2安装目录>"bin目录中找到。在使用wsdl2java.bat命令之前需要设置AXIS2_HOME环境变量,该变量值是<Axis2安装目录>。

在Windows控制台输出如下的命令行来生成调用WebService的代码:

%AXIS2_HOME%\bin\wsdl2java-urihttp://localhost:8080/axis2/services/SimpleService?wsdl-pclient-s-ostub

其中-url参数指定了wsdl文件的路径,可以是本地路径,也可以是网络路径。-p参数指定了生成的Java类的包名,-o参数指定了生成的一系列文件保存的根目录。在执行完上面的命令后,读者就会发现在当前目录下多了个stub目录,在."stub"src"client目录可以找到一个SimpleServiceStub.java文件,该文件复杂调用WebService,读者可以在程序中直接使用这个类,代码如下:

packageclient;

importjavax.xml.namespace.QName;
importorg.apache.axis2.addressing.EndpointReference;
importorg.apache.axis2.client.Options;
importorg.apache.axis2.rpc.client.RPCServiceClient;

publicclassStubClient
{
publicstaticvoidmain(String[]args)throwsException
{
SimpleServiceStubstub=newSimpleServiceStub();
SimpleServiceStub.GetGreetinggg=newSimpleServiceStub.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类的对象实例。

五、使用C#调用WebService

从理论上说,WebService可以被任何支持SOAP协议的语言调用。在VisualStudio中使用C#调用WebService是在所有语言中最容易实现的(VB.net的调用方法类似,也同样很简单)。

新建一个VisualStudio工程,并在引用Web服务的对话框中输入如下的URL,并输入Web引用名为“WebService”:

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

然后引用Web服务的对话框就会显示该WebService中的所有的方法,如图5所示。



图5

在完成上面的工作后,只需要如下三行C#代码就可以调用getGreeting和getPrice方法,并显示这两个方法的返回值:

WebService.SimpleServicesimpleService=newWSC.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更精确的解释:Webservices是建立可互操作的分布式应用程序的新平台。作为一个Windows程序员,你可能已经用COMDCOM建立过基于组件的分布式应用程序。COM是一个非常好的组件技术,但是我们也很容易举出COM并不能满足要求的情况。Webservice平台是一套标准,它定义了应用程序如何在Web上实现互操作性。你可以用任何你喜欢的语言,在任何你喜欢的平台上写Webservice,只要我们可以通过Webservice标准对这些服务进行查询和访问。
不管你的Webservice是用什么工具,什么语言写出来的,只要你用SOAP协议通过HTTP来调用它,总体结构都应如下图所示。通常,你用你自己喜欢的语言(VB6或者VB.NET)来构建你的Webservice,然后用SOAPToolkit或者.NET的内建支持来把它暴露给Web客户。于是,任何语言,任何平台上的客户都可以阅读其WSDL文档,以调用这个Webservice。客户根据WSDL描述文档,会生成一个SOAP请求消息。Webservice都是放在Web服务器(IIS)后面的,客户生成的SOAP请求会被嵌入在一个HTTPPOST请求中,发送到Web服务器来。Web服务器再把这些请求转发给Webservice请求处理器。对VB6程序来说,Webservice请求处理器是一个与SOAPToolkit组件协同工作的ASP页面或ISAPIextension。而对VB.NET程序来说,Webservice请求处理器则是一个.NETFramework自带的ISAPIextension。请求处理器的作用在于,解析收到的SOAP请求,调用Webservice,然后再生成相应的SOAP应答。Web服务器得到SOAP应答后,会再通过HTTP应答的方式把它送回到客户端。

2.基本概念
SOAP
Webservice建好以后,其他人就会去调用它。简单对象访问协议(SOAP)提供了标准的远程过程调用(RPC)方法来调用WebserviceSOAP规范定义了SOAP消息的格式,以及怎样通过HTTP协议来使用SOAPSOAP也是基于XMLXSD的,XMLSOAP的数据编码方式。客户端和服务端之间的方法调用请求和结果返回值都放在这些消息里。
XML和XSD
可扩展的标记语言(XML)Webservice平台中表示数据的基本格式。除了易于建立和易于分析外,XML主要的优点在于它既是平台无关的,又是厂商无关的。无关性是比技术优越性更重要的。XML解决了数据表示的问题,但它没有定义一套标准的数据类型,更没有说怎么去扩展这套数据类型。例如,整形数到底代表什么?16位,32位,还是64位?这些细节对实现互操作性都是很重要的。W3C制定的XMLSchema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。Webservice平台就是用XSD来作为其数据类型系统的。当用某种语言(VB.NETC#)来构造一个Webservice时,为了符合Webservice标准,所有使用的数据类型都必须被转换为XSD类型。
WSDL(WebServicesDescriptionLanguage)
用于描述服务端所提供服务的XML格式。WSDL文件里,描述了服务端提供的服务,提供的调用方法,以及调用时所要遵循的格式,比如调用参数和返回值的格式等等。WSDL很像COM编程里的IDL(InterfaceDescriptionLanguage),是服务器与客户端之间的契约,双方必须按契约严格行事才能实现功能。
WSML(WebServicesMetaLanguage)
用于描述WSDL里提供的方法与实现该方法的COM对象之间的映射关系。该文件是Microsoft的实现中特有的,不是SOAP标准的一部分。一般情况下,该文件只在服务端存在。

3.Webservice的技术特点
长项一:跨防火墙的通信
如果应用程序有成千上万的用户,而且分布在世界各地,那么客户端和服务器之间的通信将是一个棘手的问
题。因为客户端和服务器之间通常会有防火墙或者代理服务器。在这种情况下,使用DCOM就不是那么简单,通常也不便于把客户端程序发布到数量如此庞大的每一个用户手中。传统的做法是,选择用浏览器作为客户端,写下一大堆ASP页面,把应用程序的中间层暴露给最终用户。这样做的结果是开发难度大,程序很难维护。
举个例子,在应用程序里加入一个新页面,必须先建立好用户界面(Web页面),并在这个页面后面,包含相应商业逻辑的中间层组件,还要再建立至少一个ASP页面,用来接受用户输入的信息,调用中间层组件,把结果格式化为HTML形式,最后还要把结果页送回浏览器。要是客户端代码不再如此依赖于HTML表单,客户端的编程就简单多了。
如果中间层组件换成WebService的话,就可以从用户界面直接调用中间层组件,从而省掉建立ASP页面的那一步。要调用WebService,可以直接使用MicrosoftSOAPToolkit.NET这样的SOAP客户端,也可以使用自己开发的SOAP客户端,然后把它和应用程序连接起来。不仅缩短了开发周期,还减少了代码复杂度,并能够增强应用程序的可维护性。同时,应用程序也不再需要在每次调用中间层组件时,都跳转到相应的结果页
从经验来看,在一个用户界面和中间层有较多交互的应用程序中,使用WebService这种结构,可以节省花在用户界面编程上20%的开发时间。另外,这样一个由WebService组成的中间层,完全可以在应用程序集成或其它场合下重用。最后,通过WebService把应用程序的逻辑和数据暴露出来,还可以让其它平台上的客户重用这些应用程序。
长项二:应用程序集成
企业级的应用程序开发者都知道,企业里经常都要把用不同语言写成的、在不同平台上运行的各种程序集成起来,而这种集成将花费很大的开发力量。应用程序经常需要从运行在IBM主机上的程序中获取数据;或者把数据发送到主机或UNIX应用程序中去。即使在同一个平台上,不同软件厂商生产的各种软件也常常需要集成起来。通过WebService,应用程序可以用标准的方法把功能和数据暴露出来,供其它应用程序使用。
例如,有一个订单登录程序,用于登录从客户来的新订单,包括客户信息、发货地址、数量、价格和付款方式等内容;还有一个订单执行程序,用于实际货物发送的管理。这两个程序来自不同软件厂商。一份新订单进来之后,订单登录程序需要通知订单执行程序发送货物。通过在订单执行程序上面增加一层WebService,订单执行程序可以把“AddOrder”函数暴露出来。这样,每当有新订单到来时,订单登录程序就可以调用这个函数来发送货物了。
长项三:B2B的集成
WebService集成应用程序,可以使公司内部的商务处理更加自动化。但当交易跨越供应商和客户、突破公司的界限时会怎么样呢?跨公司的商务交易集成通常叫做B2B集成。
WebService是B2B集成成功的关键。通过WebService,公司可以把关键的商务应用暴露给指定的供应商和客户。例如,把电子下单系统和电子发票系统暴露出来,客户就可以以电子的方式发送订单,供应商则可以以电子的方式发送原料采购发票。当然,这并不是一个新的概念,EDI(电子文档交换)早就是这样了。但是,WebService的实现要比EDI简单得多,而且WebService运行在Internet上,在世界任何地方都可轻易实现,其运行成本就相对较低。不过,WebService并不像EDI那样,是文档交换或B2B集成的完整解决方案。WebService只是B2B集成的一个关键部分,还需要许多其它的部分才能实现集成。
WebService来实现B2B集成的最大好处在于可以轻易实现互操作性。只要把商务逻辑暴露出来,成为WebService,就可以让任何指定的合作伙伴调用这些商务逻辑,而不管他们的系统在什么平台上运行,使用什么开发语言。这样就大大减少了花在B2B集成上的时间和成本,让许多原本无法承受EDI的中小企业也能实现B2B集成。

长项四:软件和数据重用
软件重用是一个很大的主题,重用的形式很多,重用的程度有大有小。最基本的形式是源代码模块或者类一级的重用,另一种形式是二进制形式的组件重用。

当前,像表格控件或用户界面控件这样的可重用软件组件,在市场上都占有很大的份额。但这类软件的重用有一个很大的限制,就是重用仅限于代码,数据不能重用。原因在于,发布组件甚至源代码都比较容易,但要发布数据就没那么容易,除非是不会经常变化的静态数据。
WebService在允许重用代码的同时,可以重用代码背后的数据。使用WebService,再也不必像以前那样,要先从第三方购买、安装软件组件,再从应用程序中调用这些组件;只需要直接调用远端的WebService就可以了。举个例子,要在应用程序中确认用户输入的地址,只需把这个地址直接发送给相应的WebService,这个WebService就会帮你查阅街道地址、城市、省区和邮政编码等信息,确认这个地址是否在相应的邮政编码区域。WebService的提供商可以按时间或使用次数来对这项服务进行收费。这样的服务要通过组件重用来实现是不可能的,那样的话你必须下载并安装好包含街道地址、城市、省区和邮政编码等信息的数据库,而且这个数据库还是不能实时更新的。
另一种软件重用的情况是,把好几个应用程序的功能集成起来。例如,要建立一个局域网上的门户站点应用,让用户既可以查询联邦快递包裹,查看股市行情,又可以管理自己的日程安排,还可以在线购买电影票。现在Web上有很多应用程序供应商,都在其应用中实现了这些功能。一旦他们把这些功能都通过WebService“暴露出来,就可以非常容易地把所有这些功能都集成到你的门户站点中,为用户提供一个统一的、友好的界面。
将来,许多应用程序都会利用WebService,把当前基于组件的应用程序结构扩展为组件/WebService的混合结构,可以在应用程序中使用第三方的WebService提供的功能,也可以把自己的应用程序功能通过WebService提供给别人。两种情况下,都可以重用代码和代码背后的数据。

4.如何调用webservice
4.0webservice的调用过程
客户端:取得服务端的服务描述文件WSDL,解析该文件的内容,了解服务端的服务信息,以及调用方式。根据需要,生成恰当的SOAP请求消息(指定调用的方法,已经调用的参数),发往服务端。等待服务端返回的SOAP回应消息,解析得到返回值。
服务端:生成服务描述文件,以供客户端获取。接收客户端发来的SOAP请求消息,解析其中的方法调用和参数格式。根据WSDLWSML的描述,调用相应的COM对象来完成指定功能,并把返回值放入SOAP回应消息返回给用户。
高层接口
使用高层接口,不需要知道SOAPXML的任何信息,就可以生成和使用一个WebServiceSoapToolkit2.0通过提供两个COM对象――SoapClientSoapServer,来完成这些功能。
在客户端,只需要生成一个SoapClient实例,并用WSDL作为参数来调用其中的mssoapinit方法。SoapClient对象会自动解析WSDL文件,并在内部生成所有WebService的方法和参数信息。之后,你就可以像调用IDispatch接口里的方法一样,调用里面所有的方法。在VB或是脚本语言里,你甚至可以直接在SoapClient对象名后面直接加上.方法(参数…)进行调用。
低层接口
要使用低层接口,你必须对SOAPXML有所了解。你可以对SOAP的处理过程进行控制,特别是要做特殊处理的时候。
在客户端,首先要创建一个HttpConnector对象,负责HTTP连接。设定Connector的一些头部信息,比如EndPoinURLSoapAction等。如果网络连接需要使用代理服务器,那也要在这里设定相关的信息。接着创建SoapSerializer对象,用于生成Soap消息。按照WSDL里定义,把所有参数按顺序序列化,得到一个完整的SOAP请求消息。该Soap消息,作为Payload通过HttpConnector被发送到服务端。最后,生成一个SoapReader对象,负责读取服务端返回的SOAP消息,取得其中的返回值。

4.1使用PowerBuilder调用
适用版本8.0需下载BulletinWebServicesToolkit4.1
4.2使用java调用
需要下载apachesoap。下载地址:http://xml.apache.org/soap/index.html
导入:
importorg.apache.soap.*;
importorg.apache.soap.rpc.*;
例程:
importjava.io.*;
importjava.util.*;
importjava.net.*;
importorg.w3c.dom.*;
importorg.apache.soap.util.xml.*;
importorg.apache.soap.*;
importorg.apache.soap.encoding.*;
importorg.apache.soap.encoding.soapenc.*;
importorg.apache.soap.rpc.*;
importorg.apache.soap.transport.http.SOAPHTTPConnection;

publicclasstestClient{

publicstaticvoidmain(String[]args)throwsException{

URLurl=newURL("http://192.168.0.4/yundan/service1.wsdl");
//改成你的地址
SOAPMappingRegistrysmr=newSOAPMappingRegistry();
StringDeserializersd=newStringDeserializer();
smr.mapTypes(Constants.NS_URI_SOAP_ENC,newQName("","Result"),null,null,sd);

//创建传输路径和参数
SOAPHTTPConnectionst=newSOAPHTTPConnection();

//创建调用
Callcall=newCall();
call.setSOAPTransport(st);
call.setSOAPMappingRegistry(smr);

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

Vectorparams=newVector();
params.addElement(newParameter("NumberOne",Double.class,"10",null));
params.addElement(newParameter("NumberTwo",Double.class,"25",null));
call.setParams(params);

Responseresp=null;

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

//检查返回值
if(resp!=null&&!resp.generatedFault()){
Parameterret=resp.getReturnValue();
Objectvalue=ret.getValue();

System.out.println("Answer-->"+value);
}
else{
Faultfault=resp.getFault();
System.err.println("Generatedfault:");
System.out.println("FaultCode="+fault.getFaultCode());
System.out.println("FaultString="+fault.getFaultString());
}
}
}

4.3在asp中使用Jscript调用
需下载msSoapToolkit20.exe
引用:MSSOAP.SoapClient
例程:
<%@LANGUAGE=JScript%>
<HTML>
<HEAD>
<TITLE>webservice演示</TITLE>
</HEAD>
<BODY>
<%
varWSDL_URL="http://server0/yundan/webservice1.asmx?WSDL"
vara,b,res
varsoapclient
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>
<%
Dimsoapclient
ConstWSDL_URL="http://192.168.0.4/yundan/service1.wsdl"
setsoapclient=Server.CreateObject("MSSOAP.SoapClient")
soapclient.ClientProperty("ServerHTTPRequest")=True
soapclient.mssoapinit
http://192.168.0.4:8080/yundan/Service1.WSDL","Service1","Service1Soap",""
Dimres
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*
例程:
usingSystem;
usingSystem.Drawing;
usingSystem.Collections;
usingSystem.ComponentModel;
usingSystem.Windows.Forms;
usingSystem.Data;
namespacecsharp
{
publicclassForm1:System.Windows.Forms.Form
{
privateSystem.Windows.Forms.Labellabel1;
privateSystem.Windows.Forms.TextBoxtextBox1;
privateSystem.ComponentModel.Containercomponents=null;
publicForm1()
{
InitializeComponent();
}
protectedoverridevoidDispose(booldisposing)
{
if(disposing)
{
if(components!=null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#regionWindowsFormDesignergeneratedcode
privatevoidInitializeComponent()
{
this.label1=newSystem.Windows.Forms.Label();
this.textBox1=newSystem.Windows.Forms.TextBox();
this.SuspendLayout();
this.label1.AutoSize=true;
this.label1.Location=newSystem.Drawing.Point(88,48);
this.label1.Name="label1";
this.label1.Size=newSystem.Drawing.Size(91,14);
this.label1.TabIndex=0;
this.label1.Text="Webservice演示";
this.textBox1.Location=newSystem.Drawing.Point(88,128);
this.textBox1.Name="textBox1";
this.textBox1.TabIndex=1;
this.textBox1.Text="textBox1";
this.AutoScaleBaseSize=newSystem.Drawing.Size(6,14);
this.ClientSize=newSystem.Drawing.Size(292,273);
this.Controls.AddRange(newSystem.Windows.Forms.Control[]
{
this.textBox1,
this.label1
});
this.Name="Form1";
this.Text="C#Webservie演示";
this.Load+=newSystem.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
[STAThread]
staticvoidMain()
{
Application.Run(newForm1());
}

privatevoidForm1_Load(objectsender,System.EventArgse)
{
intstr;
你的web引用的名字.Service1cc=new你的web引用的名字.Service1();
str=cc.test(123,324);
textBox1.Text=str.ToString();
}
}
}

4.6(javascript)

需下载msSoapToolkit20.exe
引用:MSSOAP.SoapClient
例程:
varWSDL_URL="http://192.168.0.4/yundan/service1.wsdl"
WScript.echo("Connecting:"+WSDL_URL)
varCalc=WScript.CreateObject("MSSOAP.SoapClient")
Calc.mssoapinit(WSDL_URL,"","","")
varAnswer
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*
例程:
PublicClassForm1
InheritsSystem.Windows.Forms.Form
#Region"Windows窗体设计器生成的代码"
PublicSubNew()
MyBase.New()
InitializeComponent()
EndSub
ProtectedOverloadsOverridesSubDispose(ByValdisposingAsBoolean)
IfdisposingThen
IfNot(componentsIsNothing)Then
components.Dispose()
EndIf
EndIf
MyBase.Dispose(disposing)
EndSub
PrivatecomponentsAsSystem.ComponentModel.IContainer
FriendWithEventsLabel1AsSystem.Windows.Forms.Label
FriendWithEventsTextBox1AsSystem.Windows.Forms.TextBox
<System.Diagnostics.DebuggerStepThrough()>PrivateSubInitializeComponent()
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.netwebserive演示"
Me.ResumeLayout(False)
EndSub
#EndRegion
PrivateSubForm1_Load(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesMyBase.Load
DimccAsyundan.Service1=Newyundan.Service1()
TextBox1.Text=cc.test(12,123)
EndSub
EndClass

4.8使用vb6.0调用
需下载msSoapToolkit20.exe
添加引用:MicrosoftSoapTypeLibrary
位置:”C:\ProgramFiles\CommonFiles\MSSoap\Binaries\MSSOAP1.dll”
调用方法:
DimccAsNewMSSOAPLib.SoapClient
例程:
添加一个button控件Command1à添加3textbox控件,text1,text2,text3à标准EXEà新建工程
代码如下:
OptionExplicit
DimccAsNewMSSOAPLib.SoapClient
PrivateSubCommand1_Click()
cc.mssoapinit"http://192.168.0.4/yundan/Service1.asmx?WSDL"
Me.Text3.Text=cc.test(CInt(Text1.Text),CInt(Text2.Text))
EndSub
4.9使用vbscript调用
需下载msSoapToolkit20.exe
引用:MSSOAP.SoapClient
例程:
OptionExplicit
ConstWSDL_URL="http://192.168.0.4/yundan/service1.wsdl"
WScript.echo"Connecting:"&WSDL_URL
DimCalc
SetCalc=CreateObject("MSSOAP.SoapClient")
Calc.mssoapinitWSDL_URL
DimAnswer
Answer=Calc.test(14,28)
WScript.Echo"14+28="&Answer
将其存成domo.vbs文件,直接双击运行。

4.10使用vc调用
需下载msSoapToolkit20.exe
引用
#import"msxml3.dll"
usingnamespaceMSXML2;
#import"C:\ProgramFiles\CommonFiles\MSSoap\Binaries\mssoap1.dll"exclude("IStream","ISequentialStream","_LARGE_INTEGER","_ULARGE_INTEGER","tagSTATSTG","_FILETIME")raw_interfaces_only
usingnamespaceMSSOAPLib;
例程:
新建工程àMFCAppWizard(exe)[Mclient]àstep1à基本对话à其他默认值即可
修改源文件:
<StdAfx.h>
//stdafx.h:includefileforstandardsystemincludefiles,
//orprojectspecificincludefilesthatareusedfrequently,but
//arechangedinfrequently
//

#if!defined(AFX_STDAFX_H__045CD307_9518_4AF1_8CE3_8FFE38D1ACB2__INCLUDED_)
#defineAFX_STDAFX_H__045CD307_9518_4AF1_8CE3_8FFE38D1ACB2__INCLUDED_

#if_MSC_VER>1000
#pragmaonce
#endif//_MSC_VER>1000

#defineVC_EXTRALEAN//Excluderarely-usedstufffromWindowsheaders

#include<afxwin.h>//MFCcoreandstandardcomponents
#include<afxext.h>//MFCextensions
#include<afxdisp.h>//MFCAutomationclasses
#include<afxdtctl.h>//MFCsupportforInternetExplorer4CommonControls
#ifndef_AFX_NO_AFXCMN_SUPPORT
#include<afxcmn.h>//MFCsupportforWindowsCommonControls
#endif//_AFX_NO_AFXCMN_SUPPORT

#import"msxml3.dll"
usingnamespaceMSXML2;

#import"C:\ProgramFiles\CommonFiles\MSSoap\Binaries\mssoap1.dll"exclude("IStream","ISequentialStream","_LARGE_INTEGER","_ULARGE_INTEGER","tagSTATSTG","_FILETIME")raw_interfaces_only
usingnamespaceMSSOAPLib;


#defineMSG(message)\
{\
::MessageBox(NULL,_T(message),NULL,MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);\
gotocleanup;\
}


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


//{{AFX_INSERT_LOCATION}}
//MicrosoftVisualC++willinsertadditionaldeclarationsimmediatelybeforethepreviousline.

#endif//!defined(AFX_STDAFX_H__045CD307_9518_4AF1_8CE3_8FFE38D1ACB2__INCLUDED_)
<MClient.h>
//MClient.h:mainheaderfilefortheMCLIENTapplication
//

#if!defined(AFX_MCLIENT_H__9A397DA6_5A62_4AEF_BE5E_6C7629322ECC__INCLUDED_)
#defineAFX_MCLIENT_H__9A397DA6_5A62_4AEF_BE5E_6C7629322ECC__INCLUDED_

#if_MSC_VER>1000
#pragmaonce
#endif//_MSC_VER>1000

#ifndef__AFXWIN_H__
#errorinclude'stdafx.h'beforeincludingthisfileforPCH
#endif

#include"resource.h"//mainsymbols

/
//CMClientApp:
//SeeMClient.cppfortheimplementationofthisclass
//

classCMClientApp:publicCWinApp
{
public:
CMClientApp();

//Overrides
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CMClientApp)
public:
virtualBOOLInitInstance();
/

<MClientDlg.h>
//MClientDlg.h:headerfile
//

#if!defined(AFX_MCLIENTDLG_H__C2D8DBC4_30FE_40DD_848C_78D5834CAD07__INCLUDED_)
#defineAFX_MCLIENTDLG_H__C2D8DBC4_30FE_40DD_848C_78D5834CAD07__INCLUDED_

#if_MSC_VER>1000
#pragmaonce
#endif//_MSC_VER>1000

/
//CMClientDlgdialog

classCMClientDlg:publicCDialog
{
//Construction
public:
voidEnableButtons();
voidDisableButtons();
voidAssignpRef(VARIANT*var1,VARIANT*var2);
voidassignItem(LVITEM*item,UINTmask,intiItem,intiSubItem,LPTSTRpszText,intcchTextMax);
intUpdateList();
boolDestroyTree();
intCheckforURL();
intModifyDialog();
voidExecute();
intnCountParameter();
HTREEITEMAddtoTree(HTREEITEMhParent,HTREEITEMhInsertAfter,LPTSTRpszData,UINTmask,IUnknown*theInterface);
CMClientDlg(CWnd*pParent=NULL);//standardconstructor

//DialogData
//{{AFX_DATA(CMClientDlg)
enum{IDD=IDD_MCLIENT_DIALOG};
CTreeCtrlm_TreeCtrl;
CListCtrlm_Parameters;
CStringm_strParameter;
CStringm_strURL;
/

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

#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif

/
//CMClientDlgdialog

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

//
//function:CMClientDlg::Execute()
//
//parameters:NoParameters
//
//description:Passtheparametersandinvoketheoperation,gettheresultandupdatethe
//parametersandtheresultvalue
//returns:void
//
//
voidCMClientDlg::Execute()
{
USES_CONVERSION;

DisableButtons();

HTREEITEMhItem;
HTREEITEMhPort;
HTREEITEMhService;

DISPPARAMSparms;

VARIANTresult;
VARIANTvTempVariable;

CComPtr<ISOAPClient>pClient=NULL;
HRESULThr=S_OK;

BSTRbstrPort=0;
BSTRbstrService=0;
BSTRbstrWSDLFileName=0;
BSTRbstrWSMLFileName=0;

LVITEMItem;
LVITEMItem1;

intnNumParameters;
intnCounter;
intnCount;

DISPIDdispidFn;

WCHAR*pstrFunctionName;

charname[1024];

EXCEPINFOexcepinfo;

VARTYPEvt=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;

VARIANTvariantbstrtemp;
VARIANT*pArg=0;
VARIANT*pRef=0;

smIsInputEnumIsInput;

nNumParameters=nCountParameter();

if(nNumParameters!=-1)
{
pArg=newVARIANT[nNumParameters];
pRef=newVARIANT[nNumParameters];
}
else
MSG("Couldnotgetparametersfromparameterlist!");

if((!pArg)||(!pRef))
MSG("Thereisnoenoughmemory!");


if(m_TreeCtrl.ItemHasChildren(hItem))
MSG("Pleaseselectanoperation!");


hr=CoCreateInstance(__uuidof(SoapClient),NULL,CLSCTX_INPROC_SERVER,__uuidof(ISOAPClient),
(void**)&pClient);
CHECK_HRESULT(hr,"CannotcreatetheobjectoftheCLSID_SoapClient");


if(!pClient)
MSG("CannotcreatetheobjectoftheCLSID_SoapClient!");


//weneedtohavewsdlfileandportandservicenameformssoapinit
hPort=m_TreeCtrl.GetParentItem(hItem);
if(!hPort)
MSG("CannotgetPort!");

bstrPort=m_TreeCtrl.GetItemText(hPort).AllocSysString();
if(bstrPort==NULL)
MSG("CannotgetPortName!");


hService=m_TreeCtrl.GetParentItem(hPort);
if(!hService)
MSG("CannotgetService!");

bstrService=m_TreeCtrl.GetItemText(hService).AllocSysString();
if(bstrService==NULL)
MSG("CannotgetServiceName!");


bstrWSDLFileName=m_strURL.AllocSysString();
if(bstrWSDLFileName==NULL)
MSG("CannotgetWSDLfileName!");

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

//gettheselectedfunctionsname
pstrFunctionName=m_TreeCtrl.GetItemText(hItem).AllocSysString();
if(pstrFunctionName==NULL)
MSG("CouldnotgetfunctionName!");

parms.cArgs=nNumParameters;
parms.cNamedArgs=0;
parms.rgdispidNamedArgs=0;
//thereisapassbyref,andIwillusepRefasparameterlist
parms.rgvarg=pRef;

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

nCount=0;
//theloopshouldbe'numberofparameters'times
for(nCounter=0;nCounter<m_Parameters.GetItemCount();nCounter++)
{
//Ineedtogetthevalueofparameteranditstype
assignItem(&Item,LVIF_PARAM,nCounter,0,0,0);
assignItem(&Item1,LVIF_TEXT,nCounter,2,name,sizeof(name));

if(m_Parameters.GetItem(&Item)==0)
MSG("Couldnotgetitem!");
if(m_Parameters.GetItem(&Item1)==0)
MSG("Couldnotgetitem!");

//wewillnotfilltheargumentswithresult
reinterpret_cast<ISoapMapper*>(Item.lParam)->get_isInput(&IsInput);
if(IsInput!=smOutput)
{
::VariantInit(&pArg[nCount]);
//Ihavetofillthisarrayinreverseorderbacausetheserverexpectsitinreverseorder
::VariantInit(&pRef[nNumParameters-nCount-1]);

//IkeeptheparameterasBSTR
vTempVariable.vt=VT_BSTR;
vTempVariable.bstrVal=::SysAllocString(A2W(Item1.pszText));

//theconversionfortypeandvalueofparameterisdone
//thevaluewithcorrecttypeandvalueistakenintopArg
longltype;

hr=(reinterpret_cast<ISoapMapper*>(Item.lParam))->get_variantType(<ype);
CHECK_HRESULT(hr,"CouldnotgetVariantType");

hr=::VariantChangeType(&pArg[nCount],&vTempVariable,VARIANT_NOUSEROVERRIDE,(unsignedshort)ltype);
CHECK_HRESULT(hr,"CannotconvertVariantType!EithernoFunctionselectedorParameterisWrongorEmpty");

::VariantClear(&vTempVariable);
//assignthecorrectparametertopRefandindicateitisBYREF
pRef[nNumParameters-nCount-1].vt=pArg[nCount].vt|VT_BYREF;
AssignpRef(&pRef[nNumParameters-nCount-1],&pArg[nCount]);
nCount++;
}
}

//gettheIDofoperation
hr=pClient->GetIDsOfNames(IID_NULL,&pstrFunctionName,1,LOCALE_SYSTEM_DEFAULT,&dispidFn);
CHECK_HRESULT(hr,"TakingIDsFailed!");

//callingtheoperation
::VariantClear(&result);

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

::VariantInit(&variantbstrtemp);

//updatetheresults

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,"Variantcouldnotbeconverted");

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

if(m_Parameters.SetItem(&Item)==0)
MSG("CouldnotsetItemtolist");
}

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:foreachrowoflist,itcallstheRelease
//
//returns:void
//
//
voidCMClientDlg::OnDeleteitemListparam(NMHDR*pNMHDR,LRESULT*pResult)
{
//WehavetoreleaselParamthatIfilledwithobjectofISoapMapper
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:foreachtreeelements,itcallstheReleasemethod
//returns:void
//
//
voidCMClientDlg::OnDeleteitemTree(NMHDR*pNMHDR,LRESULT*pResult)
{
//WehavetoreleaselParamthatIfilledwithobject
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:forselectionontree,itupdatesthelist
//
//returns:void
//
//
voidCMClientDlg::OnSelchangedTree(NMHDR*pNMHDR,LRESULT*pResult)
{
//iftheselectedisoperation,updatethelistwithitsparameters
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("Parameterlistcannotbecreated!");
}

*pResult=0;

cleanup:
if(pOper)
pOper->Release();

return;
}
/
//function:CMClientDlg::OnLoad()
//
//parameters:NoParameters
//
//description:takestheservice,portsandoperationsandfillsthetree
//
//returns:void
//
/
voidCMClientDlg::OnLoad()
{
USES_CONVERSION;

UpdateData(true);
//chechifwsdlfileisgiven,ifnot,return
if(CheckforURL()==-1)
return;

//deletethetreeifexist,ifatreeexistandcantbedeleted,return
if(!DestroyTree())
return;

HRESULThr=S_OK;

BSTRbstrWSDLFileName=0;
BSTRbstrServiceName=0;
BSTRbstrPortName=0;
BSTRbstrOperationName=0;
intflag=1;
intflag_SERVICE=0;
intflag_PORT=0;
intflag_OPERATION=0;

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

longcFetched;

HTREEITEMhSERVICE;
HTREEITEMhPORT;
HTREEITEMhOPERATION;

//takethenameofwsdlfile
bstrWSDLFileName=m_strURL.AllocSysString();

if(bstrWSDLFileName==NULL)
return;

hr=CoCreateInstance(__uuidof(WSDLReader),NULL,CLSCTX_INPROC_SERVER,__uuidof(IWSDLReader),
(void**)&pIWSDLReader);
CHECK_HRESULT(hr,"CannotcreatetheobjectoftheCLSID_WSDLReader");

//loadingneedswsdlandwsmlfiles,butIdontknowwsmlfileandIpass""
hr=pIWSDLReader->Load(bstrWSDLFileName,L"");
CHECK_HRESULT(hr,"LoadingWSDLandWSMLfilesfailed!");

//getsoapservice
hr=pIWSDLReader->GetSoapServices(&pIEnumWSDLServices);
CHECK_HRESULT(hr,"CannotgetServices");

if(!pIEnumWSDLServices)
MSG("CannotgetServices");

while((hr=pIEnumWSDLServices->Next(1,&pIWSDLService,&cFetched))==S_OK)
{
//atleastonetimethisloopshouldgoinside;ifitdoesnot,theflagwontbeupdated
//sowecannotcontinueandshoulddestroythetreeifanypartcreated
flag_SERVICE=1;
//getservicename
hr=pIWSDLService->get_name(&bstrServiceName);
CHECK_HRESULT(hr,"CannotgetServicenames");

//addthenameofserviceintotree
//firstfieldisNULL,itmeansinsertthisasroot
hSERVICE=AddtoTree(NULL,TVI_SORT,W2A(bstrServiceName),TVIF_TEXT,pIWSDLService);
::SysFreeString(bstrServiceName);
if(!hSERVICE)
{
flag=0;
gotocleanup;
}

hr=pIWSDLService->GetSoapPorts(&pIEnumWSDLPorts);
CHECK_HRESULT(hr,"CannotgetPorts");

if(!pIEnumWSDLPorts)
MSG("CannotgetPorts");

while((hr=pIEnumWSDLPorts->Next(1,&pIWSDLPort,&cFetched))==S_OK)
{
//atleastonetimethisloopshouldgoinside;ifitdoesnot,theflagwontbeupdated
//sowecannotcontinueandshoulddestroythetreeifanypartcreated
flag_PORT=1;
//getportname
hr=pIWSDLPort->get_name(&bstrPortName);
CHECK_HRESULT(hr,"CannotgetPortnames");

//addtotreebutasachildofSERVICE
hPORT=AddtoTree(hSERVICE,TVI_SORT,W2A(bstrPortName),TVIF_TEXT,pIWSDLPort);
::SysFreeString(bstrPortName);
if(!hPORT)
{
flag=0;
gotocleanup;
}

hr=pIWSDLPort->GetSoapOperations(&pIEnumWSDLOps);
CHECK_HRESULT(hr,"CannotgetOperations");
if(!pIEnumWSDLOps)
MSG("CannotgetOperations");

while((hr=pIEnumWSDLOps->Next(1,&pIOperation,&cFetched))==S_OK)
{
//atleastonetimethisloopshouldgoinside;ifitdoesnot,theflagwontbeupdated
//sowecannotcontinueandshoulddestroythetreeifanypartcreated
flag_OPERATION=1;

hr=pIOperation->get_name(&bstrOperationName);
CHECK_HRESULT(hr,"CannotgetOperationnames");

hOPERATION=AddtoTree(hPORT,TVI_SORT,W2A(bstrOperationName),TVIF_TEXT,pIOperation);
::SysFreeString(bstrOperationName);
if(!hOPERATION)
{
flag=0;
gotocleanup;
}
//wedoreleasebyassigningto0
pIOperation=0;
}
if(flag_OPERATION==0)
{
flag=0;
MSG("CouldnotloadOPERATIONS!");
}
wedoreleasebyassigningto0
pIWSDLPort=0;
}
if(flag_PORT==0)
{
flag=0;
MSG("CouldnotloadPORTS!");
}
wedoreleasebyassigningto0
pIWSDLService=0;
}

if(flag_SERVICE==0)
{
flag=0;
MSG("CouldnotloadSERVICE!");
}
UpdateData(false);

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


if(flag==0)
DestroyTree();

return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值