最近给某省国家电网写一套系统,因为内部数据库单向隔离装置不支持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:
若是在浏览器中显示出如图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();
// 指定调用WebService的URL
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(<ype);
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; }