服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

web service实现包--axis2学习笔记二


  客户端的调用
  
  web services提供的服务多种多样,有的可以马上获得结果,有的要消耗很长的时间。所以,如果我们需要多种调用方式来对付不同的情况。
  
  大多数的web services都提供阻塞(blocking)和非阻塞(non-blocking)两种apis. 这两个概念以前应该学过,简单说一下。
  
  blocking api - 调用端要等被调用的函数运行完毕才继续往下走。
  
  non-bloking api - 调用端运行完调用函数以后就直接往下走了,调用端和被调用端是异步执行的。返回值是用回调函数来实现的。
  
  这种异步叫做api层异步(api level asynchrony)。他们只用到一个连接来发送和接收消息,而且,如果是那种需要运行很长时间的函数,还会碰到time out 错误,如果用两个连接分别处理发送和接收消息,调用的时间就可以缩短,也可以解决time out 问题。用两个连接来分别处理发送和接收消息,叫做传输层异步(transport level asynchrony)。
  
 web service实现包--axis2学习笔记二

  理论真无聊,还是来看实例吧。
  
  打开 eclipse, 创建一个新project, 新建一个叫userguide.clients的包, 把"samples/userguide/src/userguide/clients" 下面的文件都copy到那个包下面, 把axis2的lib下面的jar都加到ilbrary里面去(应该不用全加,懒一点就全加了吧.) 发现了关于echo的调用的方式, 居然有五个:
  
  echoblockingclient
  echoblockingdualclient
  echoblockingwsabasedclient
  echononblockingclient
  echononblockingdualclient
  
  一个一个看吧.
  
  echoblockingclient.java
  public class echoblockingclient {
  private static endpointreference targetepr = new endpointreference("http://localhost:8080/axis2/services/myservice");
  
  public static void main(string[] args) {
  try {
  omelement payload = clientutil.getechoomelement();
  call call = new call();
  call.setto(targetepr);
  call.settransportinfo(constants.transport_http,
  constants.transport_http,
  false);
  
  //blocking invocation
  omelement result = call.invokeblocking("echo",
  payload);
  
  stringwriter writer = new stringwriter();
  result.serializewithcache(xmloutputfactory.newinstance()
  .createxmlstreamwriter(writer));
  writer.flush();
  
  system.out.println(writer.tostring());
  
  } catch (axisfault axisfault) {
  axisfault.printstacktrace();
  } catch (xmlstreamexception e) {
  e.printstacktrace();
  }
  }
  }
  
  和一代几乎一样, 弄一个endpointreference, 再弄一个call, 其他不一样,但是也很简单, 弄一个omelement作为参数, 返回也是一个omelement. 可惜运行居然有错.
  
  再来看双通道的版本
  
  echoblockingdualclient.java
  public class echoblockingdualclient {
  private static endpointreference targetepr = new endpointreference("http://127.0.0.1:8080/axis2/services/myservice");
  
  public static void main(string[] args) {
  try {
  omelement payload = clientutil.getechoomelement();
  
  call call = new call();
  call.setto(targetepr);
  
  call.engagemodule(new qname(constants.module_addressing));
  call.settransportinfo(constants.transport_http,
  constants.transport_http,
  true);
  
  //blocking invocation
  omelement result = call.invokeblocking("echo",
  payload);
  
  stringwriter writer = new stringwriter();
  result.serializewithcache(xmloutputfactory.newinstance()
  .createxmlstreamwriter(writer));
  writer.flush();
  system.out.println(writer.tostring());
  
  
  //need to close the client side listener.
  call.close();
  
  } catch (axisfault axisfault) {
  axisfault.printstacktrace();
  } catch (exception ex) {
  ex.printstacktrace();
  }
  
  }
  }
  
  加了一句engagemodule, 这句话好像没什么用,我删掉这句话也能运行的, 然后settransportinfo最后一个参数改成了true. 关于settransportinfo的三个参数, 第一个是发送的transport, 第二个是接收的transport, 第三个是"是否双通道", 支持的搭配形式如下:
  
  http, http, true
  http, http, false
  http,smtp,true
  smtp,http,true
  smtp,smtp,true
  
  看下一个吧,echononblockingclient,这个是单通道的非阻塞模式:
  
  public class echononblockingclient {
  private static endpointreference targetepr = new endpointreference("http://127.0.0.1:8080/axis2/services/myservice");
  
  public static void main(string[] args) {
  try {
  omelement payload = clientutil.getechoomelement();
  
  call call = new call();
  call.setto(targetepr);
  call.settransportinfo(constants.transport_http,
  constants.transport_http,
  false);
  
  //callback to handle the response
  callback callback = new callback() {
  public void oncomplete(asyncresult result) {
  try {
  stringwriter writer = new stringwriter();
  result.getresponseenvelope().serializewithcache(xmloutputfactory.newinstance()
  .createxmlstreamwriter(writer));
  writer.flush();
  system.out.println(writer.tostring());
  
  
  } catch (xmlstreamexception e) {
  reporterror(e);
  }
  }
  
  public void reporterror(exception e) {
  e.printstacktrace();
  }
  };
  
  //non-blocking invocation
  call.invokenonblocking("echo", payload, callback);
  
  //wait till the callback receives the response.
  while (!callback.iscomplete()) {
  thread.sleep(1000);
  }
  
  } catch (axisfault axisfault) {
  axisfault.printstacktrace();
  } catch (exception ex) {
  ex.printstacktrace();
  }
  
  }
  }
  
  不同的地方,只是调用的方法从invokeblocking变成了invokenonblocking,然后写了一个简单的匿名callback类作为回调函数。关于这个callback类,它是一个抽象类,其中有两个方法:oncomplete和reporterror,都是client端必须实现的,他还有一个field,就是complete,可以用来设置和查询调用是否完成。可惜也不能运行,和上面的错误一样,是在createsoapmessage的时候报null错误。
  
  看下一个echononblockingdualclient,非阻塞的双通道:
  
  public class echononblockingdualclient {
  private static endpointreference targetepr = new endpointreference("http://127.0.0.1:8080/axis2/services/myservice");
  
  public static void main(string[] args) {
  try {
  omelement payload = clientutil.getechoomelement();
  
  call call = new call();
  call.setto(targetepr);
  
  //the boolean flag informs the axis2 engine to use two separate transport connection
  //to retrieve the response.
  call.engagemodule(new qname(constants.module_addressing));
  call.settransportinfo(constants.transport_http,
  constants.transport_http,
  true);
  
  //callback to handle the response
  callback callback = new callback() {
  public void oncomplete(asyncresult result) {
  try {
  stringwriter writer = new stringwriter();
  result.getresponseenvelope().serializewithcache(xmloutputfactory.newinstance()
  .createxmlstreamwriter(writer));
  writer.flush();
  system.out.println(writer.tostring());
  
  
  } catch (xmlstreamexception e) {
  reporterror(e);
  }
  }
  
  public void reporterror(exception e) {
  e.printstacktrace();
  }
  };
  
  //non-blocking invocation
  call.invokenonblocking("echo", payload, callback);
  
  //wait till the callback receives the response.
  while (!callback.iscomplete()) {
  thread.sleep(1000);
  }
  //need to close the client side listener.
  call.close();
  
  } catch (axisfault axisfault) {
  axisfault.printstacktrace();
  } catch (exception ex) {
  ex.printstacktrace();
  }
  
  }
  }
  双通道和单通道基本没什么不同,只是双通道的时候,它总是要

扫描关注微信公众号