WebService大讲堂之Axis2(8):异步调用WebService
本文为原创,如需转载,请注明作者和出处,谢谢!
package
?service;
public ? class ?MyService { ???? ?String?getName() ????{ ???????? try ????????{???????????? ????????????System.out.println( " getName方法正在执行 ???????????? // ??延迟5秒 ????????????Thread.sleep( 5000 ); ????????} ???????? catch ?(Exception?e) ????????{???????? ????????} ???????? return 火星 ; ????} } ??? 为了模拟需要一定时间才返回的WebService方法,在getName方法中使用了sleep方法来延迟5秒。 <!--
??services.xml??
-->
<
service?
name
="myService"
>
???? description ????????异步调用演示 ???? </ parameter? ="ServiceClass" ????????service.MyService??? ???? parameter messageReceivers ???????? messageReceiver? mep ="http://www.w3.org/2004/08/wsdl/in-out" ????????????class ="org.apache.axis2.rpc.receivers.RPCMessageReceiver" /> service ??? 从上面的配置代码可以看出,MyService的配置方式与前几章的WebService的配置方式完全一样,也就是说,MyService只是一个普通的WebService。 ?client;
import ?javax.xml.namespace.QName; ?org.apache.axis2.addressing.EndpointReference; ?org.apache.axis2.client.Options; ?org.apache.axis2.context.MessageContext; ?org.apache.axis2.rpc.client.RPCServiceClient; ?RPCAsyncClient { ???? static void ?main(String[]?args)? throws ?Exception ????{ ????????RPCServiceClient?serviceClient? = new ?RPCServiceClient(); ????????Options?options? ?serviceClient.getOptions(); ????????EndpointReference?targetEPR? ?EndpointReference( ???????????????? http://localhost:8080/axis2/services/myService ); ????????options.setTo(targetEPR); ????????Object[]?opAddEntryArgs? ?Object[]{}; ????????QName?opAddEntry? ?QName( http://service ,? getName ); ????????serviceClient.invokeNonBlocking(opAddEntry,?opAddEntryArgs, ???????????????? ?org.apache.axis2.client.async.AxisCallback() ????????????????{ ????????????????????@Override ???????????????????? ?onComplete() ????????????????????{ ????????????????????} ????????????????????@Override ???????????????????? ?onError(Exception?arg0) ????????????????????{ ????????????????????}????????????????????} ????????????????????@Override ???????????????????? ?onFault(MessageContext?arg0) ????????????????????{ ????????????????????} ????????????????????@Override ???????????????????? ?onMessage(MessageContext?mc) ????????????????????{ ???????????????????????? ??输出返回值 ????????????????????????System.out.println(mc.getEnvelope().getFirstElement() ????????????????????????????????.getFirstElement().getFirstElement().getText()); ????????????????????} ????????????????}); ????????System.out.println( 异步调用! ); ???????? ??阻止程序退出 ????????System.in.read(); ????} }? ? ??? 从上面的代码可以看出,invokeNonBlocking方法有三个参数,前两个参数分别指定了要调用的方法及方法参数的相关信息,而最后一个参数并不是方法返回值的类型信息,而是一个实现org.apache.axis2.client.async.AxisCallback接口的类的对象实例。在本例中隐式实现了AxisCallback接口。在AxisCallback接口中有四个方法需要实现,其中当被异步调用的方法返回时onMessage方法被调用。当运行上面的程序后,将输出如下的信息: 异步调用!
火星 ??? 虽然上面的例子可以实现异步调用,但比较麻烦。为了更方便地实现异步调用,可以使用wsdl2java命令的-a参数生成可异步调用的Stub类。下面的命令可生成同步和异步调用的客户端代码(两个类),其中-s表示生成同步调用代码,-a表示生成异步调用代码。 %AXIS2_HOME%/bin/wsdl2java?-uri?http://localhost:
8080
/axis2/services/myService?wsdl?-p?client?-s?-a?-o?stub
??? 在执行上面的命令后,将生成两个类:MyServiceStub和MyServiceCallbackHandler类,其中MyServiceStub类负责同步和异步调用WebService,MyServiceCallbackHandler类是一个抽象类,也是一个回调类,当使用异步方式调用WebService方法时,如果方法返回,则MyServiceCallbackHandler类的receiveResultgetName方法被调用。下面是使用MyServiceStub类异步访问WebService的代码: ?client.MyServiceStub.GetNameResponse;
?MyCallback? extends ?MyServiceCallbackHandler { ????@Override ???? ?receiveResultgetName(GetNameResponse?result) ????{ ???????? ??输出getName方法的返回结果 ????????System.out.println(result.get_return()); ????} } ?StubClient { ???? ?Exception?? ????{ ????????MyServiceStub?stub? ?MyServiceStub();???????? ???????? ??异步调用WebService ????????stub.startgetName( ?MyCallback()); ????????System.out.println( ); ????????System.in.read();???? ????}? } ? ?? 执行上面的程序后,将输出如下的信息:??? 异步调用!
火星
??回调方法
private
?getNameCompletedEvent(object?sender,?WSC.asyn.getNameCompletedEventArgs?e)
{ ????listBox1.Items.Add(?e.Result.@ ); } ?button1_Click(object?sender,?EventArgs?e) {?????????? ????async.myService?my? ?WSC.async.myService(); ????my.getNameCompleted? += ?WSC.async.getNameCompletedEventHandler(getNameCompletedEvent); ?????my.getNameAsync(); ?????MessageBox.Show( 完成调用 ); } ??? 其中async是引用MyService的服务名。要注意的是,在C#中不能在同一个WebService实例的getName方法未返回之前,再次调用该实例的getName方法,否则将抛出异常。如下面的代码会抛出一个异常: ????async.myService?my?
?WSC.async.getNameCompletedEventHandler(getNameCompletedEvent);
??? my.getNameAsync(); ??? ??将抛出异常 ??? my.getNameAsync(); ??? 但不同的WebService实例的方法可以在方法未返回时调用,如下面的代码是可以正常工作的: asyn.myService?my?
?WSC.asyn.myService();
my.getNameAsync(); my.getNameCompleted? ?WSC.asyn.getNameCompletedEventHandler(getNameCompletedEvent); asyn.myService?my1? ?WSC.asyn.myService(); my1.getNameCompleted? ?WSC.asyn.getNameCompletedEventHandler(getNameCompletedEvent); my1.getNameAsync(); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |