Axis2之异步调用

本章主要介绍axis2接口的异步调用方式。

一般情况下,我们使用同步方法(invokeBlocking)调用axis2接口,如果被调用的WebService方法长时间不返回,客户端将一直被阻塞,直到该方法返回为止。使用同步方法来调用WebService虽然很直观,但当WebService方法由于各种原因需要很长时间才能返回的话,就会使客户端程序一直处于等待状态,这样用户是无法忍受的。

当然,我们很容易就可以想到解决问题的方法,这就是多线程。解决问题的基本方法是将访问WebService的任务交由一个或多个线程来完成,而主线程并不负责访问WebService。这样即使被访问的WebService方法长时间不返回,客户端仍然可以做其他的工作。我们可以管这种通过多线程访问WebService的方式称为异步访问。

虽然直接使用多线程可以很好地解决这个问题,但比较麻烦。幸好Axis2的客户端提供了异步访问WebService的功能。
RPCServiceClient类提供了一个invokeNonBlocking方法可以通过异步的方式来访问WebService。下面结合一个实例程序说明。

目录结构:

关键代码:

package com.alfred.client;

import java.io.IOException;

import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.async.AxisCallback;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.rpc.client.RPCServiceClient;

public class ServiceClient {
	public static void main(String args[]) throws IOException {
		sendAxis2();
	}

	/**
	 * 发送axis2的接口信息
	 *
	 * @throws IOException
	 */
	private static void sendAxis2() throws IOException {
		// 使用RPC方式调用WebService
		RPCServiceClient serviceClient = new RPCServiceClient();

		Options options = serviceClient.getOptions();
		// 指定调用WebService的URL
		EndpointReference targetEPR = new EndpointReference(
				"http://127.0.0.1:8080/awyb/services/mySoapService");
		options.setTo(targetEPR);
		// 指定sayHello方法的参数值,如果有多个,继续往后面增加即可
		Object[] opAddEntryArgs = new Object[] { "alfred" };
		// 在创建QName对象时,QName类的构造方法的第一个参数表示WSDL,文件的命名空间名,也就是<wsdl:definitions>元素的targetNamespace属性值
		// 第二个参数是要调用的方法名
		QName opAddEntry = new QName("http://service.alfred.com", "sayHello");
		serviceClient.invokeNonBlocking(opAddEntry, opAddEntryArgs,new AxisCallback() {
			public void onComplete() {}

			public void onError(Exception arg0) {}

			public void onFault(MessageContext arg0) {}

			public void onMessage(MessageContext mc) {
				// 输出返回值
				System.out.println(mc.getEnvelope().getFirstElement()
						.getFirstElement().getFirstElement().getText());
			}
		});
		System.out.println("异步调用!");
		// 阻止程序退出
		System.in.read();
	}

}

ServiceClient.java

package com.alfred.service;

import org.apache.axis2.AxisFault;

public class SoapService {
	public String sayHello(String name) throws AxisFault {
		try {
			System.out.println("sayHello方法正在执行 ");
			// 延迟5秒
			Thread.sleep(5000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "Hello," + name;
	}

	public String getWorld() {
		return "Hello,World";
	}
}

SoapService.java

客户端异步访问axis2的sayHello,控制台打印信息:

可以看到程序并没有等待接口返回就继续执行之后的操作。

异步调用使用的方法是invokeNonBlocking,从上面的代码可以看出,invokeNonBlocking方法有三个参数,前两个参数分别指定了要调用的方法及方法参数的相关信息,而最后一个参数并不是方法返回值的类型信息,而是一个实现org.apache.axis2.client.async.AxisCallback接口的类的对象实例。在本例中隐式实现了AxisCallback接口。在AxisCallback接口中有四个方法需要实现,其中当被异步调用的方法返回时onMessage方法被调用。

我们也可以使用wsdl2java命令的-a参数生成可异步调用的Stub类(需先安装axis2,配置好AXIS2_HOME环境变量)。下面的命令可生成同步和异步调用的客户端代码(两个类),其中-s表示生成同步调用代码,-a表示生成异步调用代码。

%AXIS2_HOME%\bin\wsdl2java -uri http://127.0.0.1:8080/awyb/services/mySoapService?wsdl -p client -s -a -o stub

在执行上面的命令后,将生成两个类:MySoapServiceStub和MySoapServiceCallbackHandler类,其中MySoapServiceStub类负责同步和异步调用WebService,MySoapServiceCallbackHandler类是一个抽象类,也是一个回调类,当使用异步方式调用WebService方法时,如果方法返回,则MySoapServiceCallbackHandler类的receiveResultgetName方法被调用。下面是使用MySoapServiceStub类异步访问WebService的代码。

目录结构:

关键代码:

package client;

import client.MySoapServiceStub.GetWorldResponse;
import client.MySoapServiceStub.SayHelloResponse;

public class MyCallback extends MySoapServiceCallbackHandler {

	@Override
	public void receiveResultgetWorld(GetWorldResponse result) {
		// 输出getWorld方法的返回结果
		System.out.println(result.get_return());
	}

	@Override
	public void receiveResultsayHello(SayHelloResponse result) {
		// 输出sayHello方法的返回结果
		System.out.println(result.get_return());
	}

}

MyCallback.java

package client;

import client.MySoapServiceStub.SayHello;

public class StubClient {
	public static void main(String[] args) throws Exception {
		MySoapServiceStub stub = new MySoapServiceStub();
		// 异步调用WebService
		SayHello sayHello = new SayHello();
		sayHello.setName("alfred other");
		stub.startsayHello(sayHello, new MyCallback());
		System.out.println("异步调用!");
		System.in.read();
	}
}

StubClient.java

MySoapServiceCallbackHandler和MySoapServiceStub是自动生成的代码。

访问sayHello后控制台打印结果:

时间: 2024-12-22 13:49:51

Axis2之异步调用的相关文章

Axis2发布webservice(4)&mdash;webservice的异步调用

一,发布一个webservice,代码如下 package com.hoo.service; public class AsynchronousService { public String execute() throws InterruptedException{ //让当前线程睡眠5钟,展示异步调用 Thread.sleep(5000); return "done"; } } 二.发布Service,参见前面教程,不多讲 三.RPC方式异步调用: import java.io.I

(转)spring boot注解 [email&#160;protected] 异步调用

原文:http://www.cnblogs.com/azhqiang/p/5609615.html EnableAsync注解的意思是可以异步执行,就是开启多线程的意思.可以标注在方法.类上. 1 @Component 2 public class Task { 3 4 @Async 5 public void doTaskOne() throws Exception { 6 // 同上内容,省略 7 } 8 9 @Async 10 public void doTaskTwo() throws

CXF简单示例(二)之异步调用

在实际使用中,客户端在调用服务时,并不能及时得到响应,比如调用的服务本身是一个耗时费事的活,服务器破死命的跑,也只能在一分钟后才能够返回结果,这时候如果是同步的情况,那么客户端就必须在这里到等上一分钟,啥事不干.这肯定是不能容忍的,光吃饭不干活,再有这么好的事,请告诉我! OK,所以我们需要异步调用. 在这里,先介绍CXF提供的一个工具:WSDL2Java. 我们可以方便的利用它来生成相应的客户端接口,配置什么的脏活累活它都给我们干了,而我们只需要这样直接用就行了. 1. 获得服务的WSDL路径

spring-boot实战【10】【转】:Spring Boot中使用@Async实现异步调用

什么是"异步调用"? "异步调用"对应的是"同步调用",同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行:异步调用指程序在顺序执行时,不等待异步调用的语句返回结果就执行后面的程序. 同步调用 下面通过一个简单示例来直观的理解什么是同步调用: 定义Task类,创建三个处理函数分别模拟三个执行任务的操作,操作消耗时间随机取(10秒内) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

简述自己用过的几种异步调用方式

直接上代码 1.BeginInvoke和EndInvoke方式 private static void BeginInvoke1() { Func<int,string> fun = Todo; for (int i = 0; i < 5; i++) { //fun.BeginInvoke(i,TodoCallBack, fun); /* 异步调用委托BeginInvoke * handler.EndInvoke(x)为执行委托的结果 */ fun.BeginInvoke(i, x =&

C#委托异步调用

废话不多说,直接上代码(PS:我就喜欢简单.直接.粗暴) using System;using System.Collections.Generic;using System.Linq;using System.Runtime.Remoting.Messaging;using System.Text;using System.Threading;using System.Threading.Tasks; namespace 异步调用委托{    class Program    {       

同步调用和异步调用同时存在导致的混乱

其实在Promise之外也存在这个问题,这里我们以一般的使用情况来考虑此问题.这个问题的本质是接收回调函数的函数,会根据具体的执行情况,可以选择是以同步还是异步的方式对回调函数进行调用.下面我们以 onReady(fn) 为例进行说明,这个函数会接收一个回调函数进行处理. mixed-onready.js function onReady(fn) { var readyState = document.readyState; if (readyState == 'interactive' ||

WCF的异步调用

1.服务契约 namespace Contracts { [ServiceContract] public interface ICalculator { [OperationContract] double Add(double x,double y); } } 2.服务实现 namespace Services { public class CalculatorService:ICalculator { public double Add(double x, double y) { retu

C#异步调用

在有时候,我们要从一些外设备或是网络索取大量数据时,外设备可能须要处理非常久才干把传输数据回计算机,这时我们仅仅有傻傻的等待. 但我们採用异步方法就不同了,我们能够利用这点时间去做别的事,等待完毕后,再通知我们接收. 1.怎样进行异步调用 (1)定义要运行异步的方法. (2)定义一个与运行异步方法同样签名的托付. (3)实例化该托付,该托付应该指向该异步方法. (4)利用BeginInvoke启动异步方法. (5)利用EndInvoke得到结果. (6)设置回调方法.(非必需) 2.BeginI