`

CXF入门教程(5) -- webService异步调用模式

 
阅读更多
原文参考: http://blog.csdn.net/neareast/article/details/7726503
除了教程(3)中介绍的常见的同步调用模式,CXF还支持如下两种形式的异步调用模式:

轮询方法(Polling approach) - 这种情况下调用远程方法,我们可以调用一个特殊的方法;该方法没有输出参数,但是返回一个 javax.xml.ws.Response 实例。可以轮询该 Response 对象(继承自 javax.util.concurrency.Future 接口)来检查是否有应答消息到达。
回调方法(Callback approach) -这种情况下调用远程方法,我们调用另外一个特殊的方法:该方法使用一个回调对象(javax.xml.ws.AsyncHandler类型)的引用作为一个参数。只要有应答消息到达客户端,CXF运行时就会回调该 AsyncHandler 对象,并将应答消息的内容传给它。
下面是两种异步调用的方法的描述和示例代码。

异步调用示例使用的契约
下面展示的是异步调用示例中使用的WSDL契约,为保证教程的连续性,本文使用的是前面教程(1)中生成的HelloWorld服务的WSDL契约。
<?xml version="1.0" ?>  
<wsdl:definitions name="HelloWorld"  
    targetNamespace="http://service.server.cxf.test.neareast.com/"  
    xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"  
    xmlns:tns="http://service.server.cxf.test.neareast.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"  
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
    <wsdl:types>  
        <xs:schema attributeFormDefault="unqualified"  
            elementFormDefault="unqualified" targetNamespace="http://service.server.cxf.test.neareast.com/"  
            xmlns:tns="http://service.server.cxf.test.neareast.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">  
            <xs:element name="IntegerUserMap" type="tns:IntegerUserMap"></xs:element>  
            <xs:complexType name="User">  
                <xs:sequence>  
                    <xs:element minOccurs="0" name="name" type="xs:string"></xs:element>  
                </xs:sequence>  
            </xs:complexType>  
            <xs:complexType name="IntegerUserMap">  
                <xs:sequence>  
                    <xs:element maxOccurs="unbounded" minOccurs="0" name="entry"  
                        type="tns:IdentifiedUser"></xs:element>  
                </xs:sequence>  
            </xs:complexType>  
            <xs:complexType name="IdentifiedUser">  
                <xs:sequence>  
                    <xs:element name="id" type="xs:int"></xs:element>  
                    <xs:element minOccurs="0" name="user" type="tns:User"></xs:element>  
                </xs:sequence>  
            </xs:complexType>  
            <xs:element name="sayHi" type="tns:sayHi"></xs:element>  
            <xs:complexType name="sayHi">  
                <xs:sequence>  
                    <xs:element minOccurs="0" name="text" type="xs:string"></xs:element>  
                </xs:sequence>  
            </xs:complexType>  
            <xs:element name="sayHiResponse" type="tns:sayHiResponse"></xs:element>  
            <xs:complexType name="sayHiResponse">  
                <xs:sequence>  
                    <xs:element minOccurs="0" name="return" type="xs:string"></xs:element>  
                </xs:sequence>  
            </xs:complexType>  
            <xs:element name="sayHiToUser" type="tns:sayHiToUser"></xs:element>  
            <xs:complexType name="sayHiToUser">  
                <xs:sequence>  
                    <xs:element minOccurs="0" name="arg0" type="tns:User"></xs:element>  
                </xs:sequence>  
            </xs:complexType>  
            <xs:element name="sayHiToUserResponse" type="tns:sayHiToUserResponse"></xs:element>  
            <xs:complexType name="sayHiToUserResponse">  
                <xs:sequence>  
                    <xs:element minOccurs="0" name="return" type="xs:string"></xs:element>  
                </xs:sequence>  
            </xs:complexType>  
            <xs:element name="getUsers" type="tns:getUsers"></xs:element>  
            <xs:complexType name="getUsers">  
                <xs:sequence></xs:sequence>  
            </xs:complexType>  
            <xs:element name="getUsersResponse" type="tns:getUsersResponse"></xs:element>  
            <xs:complexType name="getUsersResponse">  
                <xs:sequence>  
                    <xs:element minOccurs="0" name="return" type="tns:IntegerUserMap"></xs:element>  
                </xs:sequence>  
            </xs:complexType>  
        </xs:schema>  
    </wsdl:types>  
    <wsdl:message name="getUsers">  
        <wsdl:part element="tns:getUsers" name="parameters">  
        </wsdl:part>  
    </wsdl:message>  
    <wsdl:message name="sayHi">  
        <wsdl:part element="tns:sayHi" name="parameters">  
        </wsdl:part>  
    </wsdl:message>  
    <wsdl:message name="sayHiToUser">  
        <wsdl:part element="tns:sayHiToUser" name="parameters">  
        </wsdl:part>  
    </wsdl:message>  
    <wsdl:message name="sayHiToUserResponse">  
        <wsdl:part element="tns:sayHiToUserResponse" name="parameters">  
        </wsdl:part>  
    </wsdl:message>  
    <wsdl:message name="sayHiResponse">  
        <wsdl:part element="tns:sayHiResponse" name="parameters">  
        </wsdl:part>  
    </wsdl:message>  
    <wsdl:message name="getUsersResponse">  
        <wsdl:part element="tns:getUsersResponse" name="parameters">  
        </wsdl:part>  
    </wsdl:message>  
    <wsdl:portType name="iHelloWorld">  
        <wsdl:operation name="sayHi">  
            <wsdl:input message="tns:sayHi" name="sayHi">  
            </wsdl:input>  
            <wsdl:output message="tns:sayHiResponse" name="sayHiResponse">  
            </wsdl:output>  
        </wsdl:operation>  
        <wsdl:operation name="sayHiToUser">  
            <wsdl:input message="tns:sayHiToUser" name="sayHiToUser">  
            </wsdl:input>  
            <wsdl:output message="tns:sayHiToUserResponse" name="sayHiToUserResponse">  
            </wsdl:output>  
        </wsdl:operation>  
        <wsdl:operation name="getUsers">  
            <wsdl:input message="tns:getUsers" name="getUsers">  
            </wsdl:input>  
            <wsdl:output message="tns:getUsersResponse" name="getUsersResponse">  
            </wsdl:output>  
        </wsdl:operation>  
    </wsdl:portType>  
    <wsdl:binding name="HelloWorldSoapBinding" type="tns:iHelloWorld">  
        <soap:binding style="document"  
            transport="http://schemas.xmlsoap.org/soap/http"></soap:binding>  
        <wsdl:operation name="sayHi">  
            <soap:operation soapAction="" style="document"></soap:operation>  
            <wsdl:input name="sayHi">  
                <soap:body use="literal"></soap:body>  
            </wsdl:input>  
            <wsdl:output name="sayHiResponse">  
                <soap:body use="literal"></soap:body>  
            </wsdl:output>  
        </wsdl:operation>  
        <wsdl:operation name="sayHiToUser">  
            <soap:operation soapAction="" style="document"></soap:operation>  
            <wsdl:input name="sayHiToUser">  
                <soap:body use="literal"></soap:body>  
            </wsdl:input>  
            <wsdl:output name="sayHiToUserResponse">  
                <soap:body use="literal"></soap:body>  
            </wsdl:output>  
        </wsdl:operation>  
        <wsdl:operation name="getUsers">  
            <soap:operation soapAction="" style="document"></soap:operation>  
            <wsdl:input name="getUsers">  
                <soap:body use="literal"></soap:body>  
            </wsdl:input>  
            <wsdl:output name="getUsersResponse">  
                <soap:body use="literal"></soap:body>  
            </wsdl:output>  
        </wsdl:operation>  
    </wsdl:binding>  
    <wsdl:service name="HelloWorld">  
        <wsdl:port binding="tns:HelloWorldSoapBinding" name="HelloWorldImplPort">  
            <soap:address location="http://localhost:9000/helloWorld"></soap:address>  
        </wsdl:port>  
    </wsdl:service>  
</wsdl:definitions>
 

生成异步 stub 代码
异步调用需要额外的stub代码(例如,服务端点接口中定义的专用的异步方法)。然而,这些特殊的stub代码不是默认生成的。要想打开异步特性,并生成必不可少的stub代码,我们必须使用WSDL 2.0规范的自定义映射特性。

自定义使我们能够改变 wsdl2java 工具生成stub代码的方式。特别地,它允许我们修改WSDL到Java的映射,并打开某些特性。在这里,自定义的作用是打开异步调用特性。自定义是用一个绑定声明规定的,该声明是我们用一个 jaxws:bindings 标签(jaxws 前缀绑定到 http://java.sun.com/xml/ns/jaxws 命名空间)定义的。指定一个绑定声明有两种可选的方式:

外部绑定声明 - jaxws:bindings 元素被定义在WSDL契约之外的一个单独的文件。生成stub代码的时候,我们需要对wsdl2java 工具指定绑定声明文件的位置。
嵌入式绑定声明 - 我们也可以直接把jaxws:bindings 元素嵌入到 WSDL 契约中,把它当做WSDL的扩展。在这种情况下,jaxws:bindings 的设置仅对直接的父元素起作用。
本文只考虑第一种方法,即外部绑定声明。一个打开了异步调用开关的绑定声明文件的模版如下所示:
<bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
          xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"  
          wsdlLocation="http://localhost:9000/helloWorld?wsdl"  
          xmlns="http://java.sun.com/xml/ns/jaxws">  
  <bindings node="wsdl:definitions">  
    <enableAsyncMapping>true</enableAsyncMapping>  
  </bindings>  
</bindings>  

其中的wsdlLocation指定了该绑定声明影响的WSDL文件的位置,可以是本地文件或一个URL。node节点是一个XPath 值,指定该绑定声明影响所影响的WSDL契约中的节点。 此处把node设为“wsdl:definitions”,表示我们希望对整个WSDL契约起作用。{jaxws:enableAsyncMapping}} 元素设置为true,用来使能异步调用特性。

如果我们只想对一个端口“iHelloWorld”生成异步方法,我们可以在前面的绑定声明中指定<bindings node="wsdl:definitions/wsdl:portType[@name='iHelloWorld']"> 。

接下来我们就可以使用wsdl2java命令来生成相应的带异步支持的stub代码了。为简单起见,假设绑定声明文件存储在本地文件async_binding.xml中,我们可以使用类似下面的命令:
wsdl2java -b async_binding.xml hello_world.wsdl

其中-b 选项用来指定绑定声明文件。通过这种方法生成stub代码之后,HelloWorld的服务端点接口定义如下:
import java.util.concurrent.Future;  
import javax.jws.WebMethod;  
import javax.jws.WebParam;  
import javax.jws.WebResult;  
import javax.jws.WebService;  
import javax.xml.bind.annotation.XmlSeeAlso;  
import javax.xml.ws.AsyncHandler;  
import javax.xml.ws.RequestWrapper;  
import javax.xml.ws.Response;  
import javax.xml.ws.ResponseWrapper;  
  
  
@WebService(targetNamespace = "http://service.server.cxf.test.neareast.com/", name = "iHelloWorld")  
@XmlSeeAlso({ObjectFactory.class})  
public interface IHelloWorld {  
  
    @RequestWrapper(localName = "sayHi", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHi")  
    @ResponseWrapper(localName = "sayHiResponse", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse")  
    @WebMethod(operationName = "sayHi")  
    public Response<com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse> sayHiAsync(  
        @WebParam(name = "text", targetNamespace = "")  
        java.lang.String text  
    );  
  
    @RequestWrapper(localName = "sayHi", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHi")  
    @ResponseWrapper(localName = "sayHiResponse", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse")  
    @WebMethod(operationName = "sayHi")  
    public Future<?> sayHiAsync(  
        @WebParam(name = "text", targetNamespace = "")  
        java.lang.String text,  
        @WebParam(name = "asyncHandler", targetNamespace = "")  
        AsyncHandler<com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse> asyncHandler  
    );  
  
    @WebResult(name = "return", targetNamespace = "")  
    @RequestWrapper(localName = "sayHi", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHi")  
    @WebMethod  
    @ResponseWrapper(localName = "sayHiResponse", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse")  
    public java.lang.String sayHi(  
        @WebParam(name = "text", targetNamespace = "")  
        java.lang.String text  
    );  
  
    @RequestWrapper(localName = "sayHiToUser", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUser")  
    @ResponseWrapper(localName = "sayHiToUserResponse", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUserResponse")  
    @WebMethod(operationName = "sayHiToUser")  
    public Response<com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUserResponse> sayHiToUserAsync(  
        @WebParam(name = "arg0", targetNamespace = "")  
        com.neareast.test.cxf.asyClient.WSDL2Java.User arg0  
    );  
  
    @RequestWrapper(localName = "sayHiToUser", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUser")  
    @ResponseWrapper(localName = "sayHiToUserResponse", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUserResponse")  
    @WebMethod(operationName = "sayHiToUser")  
    public Future<?> sayHiToUserAsync(  
        @WebParam(name = "arg0", targetNamespace = "")  
        com.neareast.test.cxf.asyClient.WSDL2Java.User arg0,  
        @WebParam(name = "asyncHandler", targetNamespace = "")  
        AsyncHandler<com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUserResponse> asyncHandler  
    );  
  
    @WebResult(name = "return", targetNamespace = "")  
    @RequestWrapper(localName = "sayHiToUser", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUser")  
    @WebMethod  
    @ResponseWrapper(localName = "sayHiToUserResponse", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUserResponse")  
    public java.lang.String sayHiToUser(  
        @WebParam(name = "arg0", targetNamespace = "")  
        com.neareast.test.cxf.asyClient.WSDL2Java.User arg0  
    );  
  
    @RequestWrapper(localName = "getUsers", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.GetUsers")  
    @ResponseWrapper(localName = "getUsersResponse", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.GetUsersResponse")  
    @WebMethod(operationName = "getUsers")  
    public Response<com.neareast.test.cxf.asyClient.WSDL2Java.GetUsersResponse> getUsersAsync();  
  
    @RequestWrapper(localName = "getUsers", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.GetUsers")  
    @ResponseWrapper(localName = "getUsersResponse", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.GetUsersResponse")  
    @WebMethod(operationName = "getUsers")  
    public Future<?> getUsersAsync(  
        @WebParam(name = "asyncHandler", targetNamespace = "")  
        AsyncHandler<com.neareast.test.cxf.asyClient.WSDL2Java.GetUsersResponse> asyncHandler  
    );  
  
    @WebResult(name = "return", targetNamespace = "")  
    @RequestWrapper(localName = "getUsers", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.GetUsers")  
    @WebMethod  
    @ResponseWrapper(localName = "getUsersResponse", targetNamespace = "http://service.server.cxf.test.neareast.com/", className = "com.neareast.test.cxf.asyClient.WSDL2Java.GetUsersResponse")  
    public com.neareast.test.cxf.asyClient.WSDL2Java.IntegerUserMap getUsers();  
}  

除了原来的同步方法(如sayHi方法),sayHi操作的两个异步调用方法也被同时生成了:
返回值类型为Future<?>,有一个类型为javax.xml.ws.AsyncHandler的额外参数的sayHiAsync()方法 —— 该方法可用于异步调用的回调方式。
返回值类型为Response<GreetMeSometimeResponse>的sayHiAsync()方法 —— 该方法可用于异步调用的轮询方式。


回调方式和轮询方式的细节将在下面的章节讨论。为体现异步调用的特点,笔者修改了教程(1)中Helloworld服务的部分实现,在sayHiToUser()方法中加入了3秒钟的休眠,并增强了代码的鲁棒性,改动如下:
public String sayHiToUser(User user) {  
    String retVal = null;  
    if(null == user){  
        retVal = "Error: user object null !";  
    }else{  
        try{  
            System.out.println("sleep for 3 seconds before return");  
            Thread.sleep(3000);  
        }catch(InterruptedException e){  
            e.printStackTrace();  
        }  
          
        System.out.println("sayHiToUser called by: " + user.getName());  
        users.put(users.size() + 1, user);  
        retVal = "Hello " + user.getName();  
    }  
    return retVal;  
}  


实现一个轮询方式的异步调用客户端
下面的代码演示了异步发送操作调用的轮询方式的实现。客户端是通过特殊的Java方法 _OperationName_Async(本例为sayHiAsync()方法)来调用这个操作的,该方法返回一个javax.xml.ws.Response<T> 对象,其中“T”是这个操作的响应消息的类型(本例中为SayHiResponse类型)。我们可以稍后通过轮询Response<T> 对象来检查该操作的响应消息是否已经到达。

[java] view plaincopyprint?
package com.neareast.test.cxf.asyClient.consumer;  
  
import java.util.concurrent.ExecutionException;  
  
import javax.xml.ws.Response;  
  
import com.neareast.test.cxf.asyClient.WSDL2Java.HelloWorld;  
import com.neareast.test.cxf.asyClient.WSDL2Java.IHelloWorld;  
import com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse;  
  
public class BasicClientPolling {  
    public static void main(String[] args) throws InterruptedException{  
        HelloWorld server = new HelloWorld();  
        IHelloWorld hello = server.getHelloWorldImplPort();  
  
        Response<SayHiResponse> sayHiResponseResp = hello.sayHiAsync(System.getProperty("user.name"));  
        while (!sayHiResponseResp.isDone()) {  
            Thread.sleep(100);  
        }  
  
        try {  
            SayHiResponse reply = sayHiResponseResp.get();  
            System.out.println( reply.getReturn() );  
        } catch (ExecutionException e) {  
            e.printStackTrace();  
        }  
          
    }  
}  

sayHiAsync()方法调用了sayHi操作,将输入参数传送到远程的服务,并返回javax.xml.ws.Response<SayHiResponse> 对象的一个引用。Response 类实现了标准的 java.util.concurrency.Future<T> 接口,该类设计用来轮询一个并发线程执行的任务的产出结果。本质上来说,使用Response对象来轮询有两种基本方法:

Non-blocking polling(非阻塞轮询) - 尝试获得结果之前,调用非阻塞方法Response<T>.isDone()来检查响应消息是否到达,例如:
<pre name="code" class="java">  User u = new User();  
          
    //非阻塞式轮询  
    u.setName(System.getProperty("user.name"));  
    Response<SayHiToUserResponse> sayHiToUserResponseResp = hello.sayHiToUserAsync(u);  
    while (!sayHiToUserResponseResp.isDone()) {  
        Thread.sleep(100);  
    }  
          
    try {  
        //如果没有前面isDone的检测,此处就退化为阻塞式轮询  
        SayHiToUserResponse reply = sayHiToUserResponseResp.get();  
        System.out.println( reply.getReturn() );  
    } catch (ExecutionException e) {  
        e.printStackTrace();  
    }</pre><br>  
<pre></pre>  
<pre></pre>  
<pre></pre>  
<pre></pre>  
<pre></pre>  
<pre></pre>  
<pre></pre>  


Blocking polling(阻塞轮询) - 立即调用Response<T>.get(),阻塞至响应到达(可以指定一个超时时长作为可选项)。例如,轮询一个响应,超时时长为60s:
//阻塞式轮询  
u.setName("NearEast");  
sayHiToUserResponseResp = hello.sayHiToUserAsync(u);  
try {  
    SayHiToUserResponse reply = sayHiToUserResponseResp.get(5L,java.util.concurrent.TimeUnit.SECONDS);  
    System.out.println( reply.getReturn() );  
} catch (ExecutionException e) {  
    e.printStackTrace();  
} catch (TimeoutException e) {  
    e.printStackTrace();  
}  


实现一个回调方式的异步调用客户端
发起异步操作调用的另一个可选方法是实现javax.xml.ws.AsyncHandler接口,派生出一个回调类。回调类必须实现 handleResponse() 方法,CXF运行时调用这个类将响应的到达通知给客户端。下面的代码给出了我们需要实现的 AsyncHandler 接口的轮廓。
The javax.xml.ws.AsyncHandler Interface
package javax.xml.ws;

public interface AsyncHandler<T>
{
  void handleResponse(Response<T> res);
}

本例使用一个测试用的回调类 SayHiToUserAsyHandler,代码如下:
package com.neareast.test.cxf.asyClient.consumer;  
  
import java.util.concurrent.ExecutionException;  
  
import javax.xml.ws.AsyncHandler;  
import javax.xml.ws.Response;  
  
import com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUserResponse;  
  
public class SayHiToUserAsyHandler implements AsyncHandler<SayHiToUserResponse> {  
    SayHiToUserResponse reply = null;  
  
    @Override  
    public void handleResponse(Response<SayHiToUserResponse> res) {  
        try {  
            reply = res.get();  
            System.out.println( reply.getReturn() );  
        } catch (ExecutionException e) {  
            e.printStackTrace();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
      
    public String getResponseText(){  
        return reply.getReturn();  
    }  
  
}  

上述 handleResponse() 的实现只是简单地获取响应数据,并把它存放到成员变量reply中。额外的getResponseText() 方法是为了方便地从响应中提炼出主要的输出参数。

下面的代码演示了发起异步操作调用的回调方法。客户端通过特定的Java方法 _OperationName_Async()来调用相应的操作,该方法使用一个额外的AsyncHandler<T>类型的参数,并返回一个 java.util.concurrency.Future<?> 对象。
package com.neareast.test.cxf.asyClient.consumer;  
  
import java.util.concurrent.Future;  
  
import com.neareast.test.cxf.asyClient.WSDL2Java.HelloWorld;  
import com.neareast.test.cxf.asyClient.WSDL2Java.IHelloWorld;  
import com.neareast.test.cxf.asyClient.WSDL2Java.User;  
  
public class BasicCallbackClient {  
    public static void main(String[] args) throws InterruptedException{  
        HelloWorld server = new HelloWorld();  
        IHelloWorld hello = server.getHelloWorldImplPort();  
          
        User u = new User();  
        //非阻塞式轮询  
        u.setName(System.getProperty("user.name"));  
        SayHiToUserAsyHandler asyHandler = new SayHiToUserAsyHandler();  
        Future<?> res = hello.sayHiToUserAsync(u, asyHandler);  
        while (!res.isDone()) {  
            Thread.sleep(100);  
        }  
          
        String reply = asyHandler.getResponseText();  
        System.out.println( reply );  
          
    }  
}  

sayHiToUserAsync()方法返回的 Future<?> 对象只是用来检测一个响应是否已经到达的 —— 例如,通过调用response.isDone()来轮询。响应消息的值只在回调对象SayHiToUserAsyHandler 中可得。

本文配套的完整代码已经上传,包括用到的wsdl契约文件和绑定声明文件;本文涉及的异步调用客户端的代码放在com.neareast.test.cxf.asyClient包下,欢迎下载:http://download.csdn.net/detail/neareast/4421250

本文参考自:http://cxf.apache.org/docs/developing-a-consumer.html
分享到:
评论

相关推荐

    CXF入门教程(4) -- webService异步调用模式

    CXF入门教程(4) -- webService异步调用模式文章配套代码,文中涉及的异步调用客户端的代码放在com.neareast.test.cxf.asyClient包下。原文地址:http://blog.csdn.net/neareast/article/details/7726503

    CXF入门 webService异步调用模式

    CXF入门教程(5)--webService异步调用模式文章配套代码,文中涉及的异步调用客户端的代码放在com.neareast.test.cxf.asyClient包下。原文地址:http://blog.csdn.net/neareast/article/details/7726503

    webService(基于cxf)的完整例子

    在这个基于CXF的Web服务完整例子中,我们将深入探讨CXF的核心概念、配置、以及如何创建和调用Web服务。 1. **CXF框架介绍**:CXF,全称为"Code first eXtended Framework",最初由XFire项目发展而来,后与Apache ...

    apache cxf_jar包

    5. **cxf-rt-transports-http-2.7.12.jar**: HTTP传输模块,负责处理HTTP/S协议的通信,使得CXF能够通过HTTP和HTTPS进行Web服务调用。 6. **cxf-rt-databinding-aegis-2.7.12.jar**: Aegis数据绑定模块,提供了一种...

    webservice apache-cxf-3.0.7 jar包

    6. **客户端API**:CXF提供了强大的客户端API,可以方便地调用远程Web服务,支持同步和异步调用模式。 7. **工具支持**:CXF包含了各种工具,如WSDL编辑器、服务测试工具等,帮助开发者在整个开发周期中进行调试和...

    Webservice-CXF实用手册学习大全

    - Jax-Rs异步调用:支持异步方式调用WebService,提高应用性能和用户体验。 - Cxf拦截器特征机制:通过拦截器可以在WebService的请求和响应过程中插入自定义逻辑,用于实现安全验证、日志记录等功能。 - 安全机制...

    WebService_CXF范例.

    【WebService CXF详解与入门】 WebService是一种允许不同系统之间进行通信和交互的标准协议,它基于HTTP协议,使得应用程序可以无视具体实现细节地调用互联网上的服务。这种技术使得分布式应用程序的发展成为可能,...

    webservice的cxf框架客户端调用所需jar包

    5. `ehcache-2.10.4.jar`: Ehcache是一个广泛使用的内存缓存系统,可以提高应用程序性能,通过缓存频繁访问的数据,减少数据库或远程服务的调用。 6. `guava-19.0.jar`: Google的Guava库提供了一系列的Java集合框架...

    基于CXF的webService本地数据交互----PC端与Android端(二)

    需要注意的是,由于Android的安全限制,可能需要处理网络权限问题,并考虑异步调用以避免阻塞UI线程。 4. 数据转换:Web服务返回的数据通常是XML或JSON格式,需要进行解析,转换为Android应用可使用的对象。 四、...

    基于CXF的webService本地数据交互----PC端与Android端(一)

    - 考虑到Android平台的异步特性,Web Service调用应放在AsyncTask或其他异步处理环境中,避免阻塞UI线程。 - 注意网络权限的设置,AndroidManifest.xml中需声明INTERNET权限。 - 对于Android低端设备,考虑到内存...

    WebService_CXF学习

    ### WebService_CXF 学习知识点详解 #### 一、WebService 概述 - **定义与作用**:WebService 是一种让程序能够透明地调用互联网上其他程序的技术,无需关心其实现细节。只要 WebService 公开了服务接口,远程...

    java调用C++ webservice

    - 对于大量调用,可以考虑使用异步调用或线程池来提高性能。 - 如果服务端支持,可以考虑使用RESTful Web服务,通常比SOAP更轻量级,性能更好。 8. **安全性**: - 考虑使用HTTPS进行安全传输,防止数据在传输...

    QT环境下Webservice服务调用,服务器端是在Java环境下

    6. **性能优化:** 对于频繁调用的Web服务,考虑使用缓存策略或异步调用来提高性能。QT的异步模型允许我们在等待网络响应的同时执行其他任务,提高用户体验。 7. **安全考虑:** 如果Web服务涉及敏感数据,确保通信...

    WebService-CXF学习.doc

    为了满足不同编程需求,CXF提供了全面的API支持,包括JAX-WS 2.x同步、异步和单向API,动态调用接口(DII),以及对JavaScript和E4X、CORBA和JBI的支持。它还支持从Java到WSDL、WSDL到Java、XSD到WSDL等双向转换,为...

    java调用webservice接口方法.rar

    调用WebService可能会有性能上的考量,可以通过缓存响应、减少不必要的网络通信、使用异步调用等方式提升效率。 10. **安全性考虑** 考虑到数据敏感性和安全性,可能需要在SOAP消息中添加数字签名、加密内容,...

    cxf webservice restful实现

    在IT行业中,CXF是一个广泛使用的开源框架,用于构建和开发Web服务。它支持多种Web服务规范,包括SOAP和RESTful。本项目聚焦于利用CXF与Spring框架集成,实现RESTful风格的Web服务。REST(Representational State ...

    WebService_CXF学习.doc

    - **JAX-WS 2.x**:客户端和服务端模式、同步/异步/单向API、动态调用接口等。 - **XML消息API**:用于处理XML消息。 - **JavaScript和ECMAScript 4 XML (E4X)**:支持脚本语言进行WebService开发。 - **CORBA**:...

    基于CXF的webService本地数据交互----PC端与Android端(三)

    另外,需要注意的是,由于Android的资源限制,可能需要优化和处理网络请求,比如使用异步调用,避免阻塞主线程。 3. **配置与部署**: 在PC端,服务端应用需要配置CXF的Servlet容器,如Tomcat,来发布Web Service...

Global site tag (gtag.js) - Google Analytics