加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

cxf webService异步调用模式

发布时间:2020-12-16 22:21:44 所属栏目:安全 来源:网络整理
导读:引用地址:http://blog.csdn.net/changpingchen/article/details/9048347 轮询方法(Polling approach) ?- 这种情况下调用远程方法,我们可以调用一个特殊的方法;该方法没有输出参数,但是返回一个? javax.xml.ws.Response ?实例。可以轮询该? Response 对
引用地址:http://blog.csdn.net/changpingchen/article/details/9048347

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

    下面是两种异步调用的方法的描述和示例代码。

    异步调用示例使用的契约

    下面展示的是异步调用示例中使用的WSDL契约,为保证教程的连续性,本文使用的是前面教程(1)中生成的HelloWorld服务的WSDL契约

    [java]? view plain ?copy
    1. <?xml?version="1.0"??>??
    2. <wsdl:definitions?name="HelloWorld"??
    3. ????targetNamespace="http://service.server.cxf.test.neareast.com/"??
    4. ????xmlns:ns1="http://schemas.xmlsoap.org/soap/http"?xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"??
    5. ????xmlns:tns="http://service.server.cxf.test.neareast.com/"?xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"??
    6. ????xmlns:xsd="http://www.w3.org/2001/XMLSchema">??
    7. ????<wsdl:types>??
    8. ????????<xs:schema?attributeFormDefault="unqualified"??
    9. ????????????elementFormDefault="unqualified"?targetNamespace="http://service.server.cxf.test.neareast.com/"??
    10. ????????????xmlns:tns="http://service.server.cxf.test.neareast.com/"?xmlns:xs="http://www.w3.org/2001/XMLSchema">??
    11. ????????????<xs:element?name="IntegerUserMap"?type="tns:IntegerUserMap"></xs:element>??
    12. ????????????<xs:complexType?name="User">??
    13. ????????????????<xs:sequence>??
    14. ????????????????????<xs:element?minOccurs="0"?name="name"?type="xs:string"></xs:element>??
    15. ????????????????</xs:sequence>??
    16. ????????????</xs:complexType>??
    17. ????????????<xs:complexType?name="IntegerUserMap">??
    18. ????????????????<xs:sequence>??
    19. ????????????????????<xs:element?maxOccurs="unbounded"?minOccurs="0"?name="entry"??
    20. ????????????????????????type="tns:IdentifiedUser"></xs:element>??
    21. ????????????<xs:complexType?name="IdentifiedUser">??
    22. ????????????????????<xs:element?name="id"?type="xs:int"></xs:element>??
    23. ????????????????????<xs:element?minOccurs="0"?name="user"?type="tns:User"></xs:element>??
    24. ????????????<xs:element?name="sayHi"?type="tns:sayHi"></xs:element>??
    25. ????????????<xs:complexType?name="sayHi">??
    26. ????????????????????<xs:element?minOccurs="0"?name="text"?type="xs:string"></xs:element>??
    27. ????????????<xs:element?name="sayHiResponse"?type="tns:sayHiResponse"></xs:element>??
    28. ????????????<xs:complexType?name="sayHiResponse">??
    29. ????????????????????<xs:element?minOccurs="0"?name="return"?type="xs:string"></xs:element>??
    30. ????????????<xs:element?name="sayHiToUser"?type="tns:sayHiToUser"></xs:element>??
    31. ????????????<xs:complexType?name="sayHiToUser">??
    32. ????????????????????<xs:element?minOccurs="0"?name="arg0"?type="tns:User"></xs:element>??
    33. ????????????<xs:element?name="sayHiToUserResponse"?type="tns:sayHiToUserResponse"></xs:element>??
    34. ????????????<xs:complexType?name="sayHiToUserResponse">??
    35. ????????????<xs:element?name="getUsers"?type="tns:getUsers"></xs:element>??
    36. ????????????<xs:complexType?name="getUsers">??
    37. ????????????????<xs:sequence></xs:sequence>??
    38. ????????????<xs:element?name="getUsersResponse"?type="tns:getUsersResponse"></xs:element>??
    39. ????????????<xs:complexType?name="getUsersResponse">??
    40. ????????????????????<xs:element?minOccurs="0"?name="return"?type="tns:IntegerUserMap"></xs:element>??
    41. ????????</xs:schema>??
    42. ????</wsdl:types>??
    43. ????<wsdl:message?name="getUsers">??
    44. ????????<wsdl:part?element="tns:getUsers"?name="parameters">??
    45. ????????</wsdl:part>??
    46. ????</wsdl:message>??
    47. ????<wsdl:message?name="sayHi">??
    48. ????????<wsdl:part?element="tns:sayHi"?name="parameters">??
    49. ????<wsdl:message?name="sayHiToUser">??
    50. ????????<wsdl:part?element="tns:sayHiToUser"?name="parameters">??
    51. ????<wsdl:message?name="sayHiToUserResponse">??
    52. ????????<wsdl:part?element="tns:sayHiToUserResponse"?name="parameters">??
    53. ????<wsdl:message?name="sayHiResponse">??
    54. ????????<wsdl:part?element="tns:sayHiResponse"?name="parameters">??
    55. ????<wsdl:message?name="getUsersResponse">??
    56. ????????<wsdl:part?element="tns:getUsersResponse"?name="parameters">??
    57. ????<wsdl:portType?name="iHelloWorld">??
    58. ????????<wsdl:operation?name="sayHi">??
    59. ????????????<wsdl:input?message="tns:sayHi"?name="sayHi">??
    60. ????????????</wsdl:input>??
    61. ????????????<wsdl:output?message="tns:sayHiResponse"?name="sayHiResponse">??
    62. ????????????</wsdl:output>??
    63. ????????</wsdl:operation>??
    64. ????????<wsdl:operation?name="sayHiToUser">??
    65. ????????????<wsdl:input?message="tns:sayHiToUser"?name="sayHiToUser">??
    66. ????????????<wsdl:output?message="tns:sayHiToUserResponse"?name="sayHiToUserResponse">??
    67. ????????<wsdl:operation?name="getUsers">??
    68. ????????????<wsdl:input?message="tns:getUsers"?name="getUsers">??
    69. ????????????<wsdl:output?message="tns:getUsersResponse"?name="getUsersResponse">??
    70. ????</wsdl:portType>??
    71. ????<wsdl:binding?name="HelloWorldSoapBinding"?type="tns:iHelloWorld">??
    72. ????????<soap:binding?style="document"??
    73. ????????????transport="http://schemas.xmlsoap.org/soap/http"></soap:binding>??
    74. ????????????<soap:operation?soapAction=""?style="document"></soap:operation>??
    75. ????????????<wsdl:input?name="sayHi">??
    76. ????????????????<soap:body?use="literal"></soap:body>??
    77. ????????????<wsdl:output?name="sayHiResponse">??
    78. ????????????????<soap:body?use="literal"></soap:body>??
    79. ????????????</wsdl:output>??
    80. ????????</wsdl:operation>??
    81. ????????<wsdl:operation?name="sayHiToUser">??
    82. ????????????<soap:operation?soapAction=""?style="document"></soap:operation>??
    83. ????????????<wsdl:input?name="sayHiToUser">??
    84. ????????????</wsdl:input>??
    85. ????????????<wsdl:output?name="sayHiToUserResponse">??
    86. ????????????<wsdl:input?name="getUsers">??
    87. ????????????<wsdl:output?name="getUsersResponse">??
    88. ????</wsdl:binding>??
    89. ????<wsdl:service?name="HelloWorld">??
    90. ????????<wsdl:port?binding="tns:HelloWorldSoapBinding"?name="HelloWorldImplPort">??
    91. ????????????<soap:address?location="http://localhost:9000/helloWorld"></soap:address>??
    92. ????????</wsdl:port>??
    93. ????</wsdl:service>??
    94. </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?的设置仅对直接的父元素起作用。

    本文只考虑第一种方法,即外部绑定声明。一个打开了异步调用开关的绑定声明文件的模版如下所示:

    copy
    <bindings?xmlns:xsd="http://www.w3.org/2001/XMLSchema"??
  1. ??????????xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"??
  2. ??????????wsdlLocation="http://localhost:9000/helloWorld?wsdl"??
  3. ??????????xmlns="http://java.sun.com/xml/ns/jaxws">??
  4. ??<bindings?node="wsdl:definitions">??
  5. ????<enableAsyncMapping>true</enableAsyncMapping>??
  6. ??</bindings>??
  7. </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 -p hellworldws?http://localhost:8080/jdbc/ws/tranws?wsdl

其中-b 选项用来指定绑定声明文件。通过这种方法生成stub代码之后,HelloWorld的服务端点接口定义如下:

copy
    import?java.util.concurrent.Future;??
  1. import?javax.jws.WebMethod;??
  2. import?javax.jws.WebParam;??
  3. import?javax.jws.WebResult;??
  4. import?javax.jws.WebService;??
  5. import?javax.xml.bind.annotation.XmlSeeAlso;??
  6. import?javax.xml.ws.AsyncHandler;??
  7. import?javax.xml.ws.RequestWrapper;??
  8. import?javax.xml.ws.Response;??
  9. import?javax.xml.ws.ResponseWrapper;??
  10. ??
  11. ??
  12. @WebService(targetNamespace?=?"http://service.server.cxf.test.neareast.com/",?name?=?"iHelloWorld")??
  13. @XmlSeeAlso({ObjectFactory.class})??
  14. public?interface?IHelloWorld?{??
  15. ????@RequestWrapper(localName?=?"sayHi",?targetNamespace?=?"http://service.server.cxf.test.neareast.com/",?className?=?"com.neareast.test.cxf.asyClient.WSDL2Java.SayHi")??
  16. ????@ResponseWrapper(localName?=?"sayHiResponse",?className?=?"com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse")??
  17. @WebMethod(operationName?=?"sayHi")??
  18. ????public?Response<com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse>?sayHiAsync(??
  19. ????????@WebParam(name?=?"text",?targetNamespace?=?"")??
  20. ????????java.lang.String?text??
  21. ????);??
  22. public?Future<?>?sayHiAsync(??
  23. ????????java.lang.String?text,??
  24. @WebParam(name?=?"asyncHandler",92); line-height:18px"> ????????AsyncHandler<com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse>?asyncHandler??
  25. @WebResult(name?=?"return",?className?=?"com.neareast.test.cxf.asyClient.WSDL2Java.SayHi")??
  26. @WebMethod??
  27. ????public?java.lang.String?sayHi(??
  28. ????????"")??
  29. ????????java.lang.String?text??
  30. ????);??
  31. @RequestWrapper(localName?=?"sayHiToUser",?className?=?"com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUser")??
  32. @ResponseWrapper(localName?=?"sayHiToUserResponse",?className?=?"com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUserResponse")??
  33. @WebMethod(operationName?=?"sayHiToUser")??
  34. public?Response<com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUserResponse>?sayHiToUserAsync(??
  35. @WebParam(name?=?"arg0",255); line-height:18px"> ????????com.neareast.test.cxf.asyClient.WSDL2Java.User?arg0??
  36. public?Future<?>?sayHiToUserAsync(??
  37. ????????com.neareast.test.cxf.asyClient.WSDL2Java.User?arg0,??
  38. ????????AsyncHandler<com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUserResponse>?asyncHandler??
  39. "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUser")??
  40. @WebMethod??
  41. public?java.lang.String?sayHiToUser(??
  42. ????????com.neareast.test.cxf.asyClient.WSDL2Java.User?arg0??
  43. @RequestWrapper(localName?=?"getUsers",?className?=?"com.neareast.test.cxf.asyClient.WSDL2Java.GetUsers")??
  44. @ResponseWrapper(localName?=?"getUsersResponse",?className?=?"com.neareast.test.cxf.asyClient.WSDL2Java.GetUsersResponse")??
  45. @WebMethod(operationName?=?"getUsers")??
  46. public?Response<com.neareast.test.cxf.asyClient.WSDL2Java.GetUsersResponse>?getUsersAsync();??
  47. "com.neareast.test.cxf.asyClient.WSDL2Java.GetUsers")??
  48. "com.neareast.test.cxf.asyClient.WSDL2Java.GetUsersResponse")??
  49. @WebMethod(operationName?=?"getUsers")??
  50. public?Future<?>?getUsersAsync(??
  51. ????????AsyncHandler<com.neareast.test.cxf.asyClient.WSDL2Java.GetUsersResponse>?asyncHandler??
  52. public?com.neareast.test.cxf.asyClient.WSDL2Java.IntegerUserMap?getUsers();??
  53. }??

除了原来的同步方法(如sayHi方法),sayHi操作的两个异步调用方法也被同时生成了:

  • 返回值类型为Future<?>,有一个类型为javax.xml.ws.AsyncHandler的额外参数的sayHiAsync()方法 —— 该方法可用于异步调用的回调方式。
  • 返回值类型为Response<GreetMeSometimeResponse>的sayHiAsync()方法 —— 该方法可用于异步调用的轮询方式。

回调方式和轮询方式的细节将在下面的章节讨论。为体现异步调用的特点,笔者修改了教程(1)中Helloworld服务的部分实现,在sayHiToUser()方法中加入了3秒钟的休眠,并增强了代码的鲁棒性,改动如下:

copy
    public?String?sayHiToUser(User?user)?{??
  1. ????String?retVal?=?null;??
  2. if(null?==?user){??
  3. ????????retVal?=?"Error:?user?object?null?!";??
  4. ????}else{??
  5. ????????try{??
  6. ????????????System.out.println("sleep?for?3?seconds?before?return");??
  7. ????????????Thread.sleep(3000);??
  8. ????????}catch(InterruptedException?e){??
  9. ????????????e.printStackTrace();??
  10. ????????}??
  11. ??????????
  12. ????????System.out.println("sayHiToUser?called?by:?"?+?user.getName());??
  13. ????????users.put(users.size()?+?1,?user);??
  14. ????????retVal?=?"Hello?"?+?user.getName();??
  15. ????}??
  16. return?retVal;??
  17. }??

实现一个轮询方式的异步调用客户端

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

copy
    package?com.neareast.test.cxf.asyClient.consumer;??
  1. import?java.util.concurrent.ExecutionException;??
  2. import?com.neareast.test.cxf.asyClient.WSDL2Java.HelloWorld;??
  3. import?com.neareast.test.cxf.asyClient.WSDL2Java.IHelloWorld;??
  4. import?com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse;??
  5. class?BasicClientPolling?{??
  6. static?void?main(String[]?args)?throws?InterruptedException{??
  7. ????????HelloWorld?server?=?new?HelloWorld();??
  8. ????????IHelloWorld?hello?=?server.getHelloWorldImplPort();??
  9. ????????Response<SayHiResponse>?sayHiResponseResp?=?hello.sayHiAsync(System.getProperty("user.name"));??
  10. ????????while?(!sayHiResponseResp.isDone())?{??
  11. 100);??
  12. try?{??
  13. ????????????SayHiResponse?reply?=?sayHiResponseResp.get();??
  14. ????????????System.out.println(?reply.getReturn()?);??
  15. ????????}?catch?(ExecutionException?e)?{??
  16. ????????????e.printStackTrace();??
  17. ????????}??
  18. ??????????
  19. sayHiAsync()方法调用了sayHi操作,将输入参数传送到远程的服务,并返回javax.xml.ws.Response<SayHiResponse>?对象的一个引用。Response?类实现了标准的?java.util.concurrency.Future<T>?接口,该类设计用来轮询一个并发线程执行的任务的产出结果。本质上来说,使用Response对象来轮询有两种基本方法:

    • Non-blocking polling(非阻塞轮询)?- 尝试获得结果之前,调用非阻塞方法Response<T>.isDone()来检查响应消息是否到达,例如:
      [java]? view plain ?copy
        <pre?name="code"?class="java">????User?u?=?new?User();??
      1. ??????????
      2. ????//非阻塞式轮询??
      3. ????u.setName(System.getProperty("user.name"));??
      4. ????Response<SayHiToUserResponse>?sayHiToUserResponseResp?=?hello.sayHiToUserAsync(u);??
      5. while?(!sayHiToUserResponseResp.isDone())?{??
      6. ????????Thread.sleep(100);??
      7. ????}??
      8. ??????????
      9. try?{??
      10. ????????//如果没有前面isDone的检测,此处就退化为阻塞式轮询??
      11. ????????SayHiToUserResponse?reply?=?sayHiToUserResponseResp.get();??
      12. ????????System.out.println(?reply.getReturn()?);??
      13. ????}?catch?(ExecutionException?e)?{??
      14. ????????e.printStackTrace();??
      15. ????}</pre><br>??
      16. <pre></pre>??
      17. <pre></pre>??
      18. <pre></pre>??
    • Blocking polling(阻塞轮询)?- 立即调用Response<T>.get(),阻塞至响应到达(可以指定一个超时时长作为可选项)。例如,轮询一个响应,超时时长为60s:
      copy
        //阻塞式轮询??
      1. u.setName("NearEast");??
      2. sayHiToUserResponseResp?=?hello.sayHiToUserAsync(u);??
      3. ????SayHiToUserResponse?reply?=?sayHiToUserResponseResp.get(5L,java.util.concurrent.TimeUnit.SECONDS);??
      4. ????System.out.println(?reply.getReturn()?);??
      5. }?catch?(ExecutionException?e)?{??
      6. ????e.printStackTrace();??
      7. catch?(TimeoutException?e)?{??
      8. }??

    实现一个回调方式的异步调用客户端

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

    The javax.xml.ws.AsyncHandler Interface
    <span class="code-keyword" style="color: rgb(0,145); background-color: inherit; ">package</span> javax.xml.ws;
    
    <span class="code-keyword" style="color: rgb(0,145); background-color: inherit; ">public</span> <span class="code-keyword" style="color: rgb(0,145); background-color: inherit; ">interface</span> AsyncHandler<T>
    {
      void handleResponse(Response<T> res);
    }
    

    本例使用一个测试用的回调类?SayHiToUserAsyHandler,代码如下:

    copy
      import?javax.xml.ws.Response;??
    1. import?com.neareast.test.cxf.asyClient.WSDL2Java.SayHiToUserResponse;??
    2. class?SayHiToUserAsyHandler?implements?AsyncHandler<SayHiToUserResponse>?{??
    3. ????SayHiToUserResponse?reply?=?null;??
    4. @Override??
    5. void?handleResponse(Response<SayHiToUserResponse>?res)?{??
    6. ????????????reply?=?res.get();??
    7. catch?(InterruptedException?e)?{??
    8. ????}??
    9. ??????
    10. public?String?getResponseText(){??
    11. return?reply.getReturn();??
    12. 上述?handleResponse()?的实现只是简单地获取响应数据,并把它存放到成员变量reply中。额外的getResponseText()?方法是为了方便地从响应中提炼出主要的输出参数。

      下面的代码演示了发起异步操作调用的回调方法。客户端通过特定的Java方法?_OperationName_Async()来调用相应的操作,该方法使用一个额外的AsyncHandler<T>类型的参数,并返回一个?java.util.concurrency.Future<?>?对象。

      copy
        import?com.neareast.test.cxf.asyClient.WSDL2Java.User;??
      1. class?BasicCallbackClient?{??
      2. ????????User?u?=?new?User();??
      3. //非阻塞式轮询??
      4. ????????u.setName(System.getProperty("user.name"));??
      5. ????????SayHiToUserAsyHandler?asyHandler?=?new?SayHiToUserAsyHandler();??
      6. ????????Future<?>?res?=?hello.sayHiToUserAsync(u,?asyHandler);??
      7. while?(!res.isDone())?{??
      8. ????????String?reply?=?asyHandler.getResponseText();??
      9. ????????System.out.println(?reply?);??
      10. 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

        轮询方法(Polling approach)?接口)来检查是否有应答消息到达。
      11. ?对象,并将应答消息的内容传给它。
      12. 下面是两种异步调用的方法的描述和示例代码。

        异步调用示例使用的契约

        [java]? view plain ?copy
          <?xml?version="1.0"??>??
        1. <wsdl:definitions?name="HelloWorld"??
        2. ????targetNamespace="http://service.server.cxf.test.neareast.com/"??
        3. ????xmlns:ns1="http://schemas.xmlsoap.org/soap/http"?xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"??
        4. ????xmlns:tns="http://service.server.cxf.test.neareast.com/"?xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"??
        5. ????xmlns:xsd="http://www.w3.org/2001/XMLSchema">??
        6. ????<wsdl:types>??
        7. ????????<xs:schema?attributeFormDefault="unqualified"??
        8. ????????????elementFormDefault="unqualified"?targetNamespace="http://service.server.cxf.test.neareast.com/"??
        9. ????????????xmlns:tns="http://service.server.cxf.test.neareast.com/"?xmlns:xs="http://www.w3.org/2001/XMLSchema">??
        10. ????????????<xs:element?name="IntegerUserMap"?type="tns:IntegerUserMap"></xs:element>??
        11. ????????????<xs:complexType?name="User">??
        12. ????????????????<xs:sequence>??
        13. ????????????????????<xs:element?minOccurs="0"?name="name"?type="xs:string"></xs:element>??
        14. ????????????????</xs:sequence>??
        15. ????????????</xs:complexType>??
        16. ????????????<xs:complexType?name="IntegerUserMap">??
        17. ????????????????<xs:sequence>??
        18. ????????????????????<xs:element?maxOccurs="unbounded"?minOccurs="0"?name="entry"??
        19. ????????????????????????type="tns:IdentifiedUser"></xs:element>??
        20. ????????????<xs:complexType?name="IdentifiedUser">??
        21. ????????????????????<xs:element?name="id"?type="xs:int"></xs:element>??
        22. ????????????????????<xs:element?minOccurs="0"?name="user"?type="tns:User"></xs:element>??
        23. ????????????<xs:element?name="sayHi"?type="tns:sayHi"></xs:element>??
        24. ????????????<xs:complexType?name="sayHi">??
        25. ????????????????????<xs:element?minOccurs="0"?name="text"?type="xs:string"></xs:element>??
        26. ????????????<xs:element?name="sayHiResponse"?type="tns:sayHiResponse"></xs:element>??
        27. ????????????<xs:complexType?name="sayHiResponse">??
        28. ????????????????????<xs:element?minOccurs="0"?name="return"?type="xs:string"></xs:element>??
        29. ????????????<xs:element?name="sayHiToUser"?type="tns:sayHiToUser"></xs:element>??
        30. ????????????<xs:complexType?name="sayHiToUser">??
        31. ????????????????????<xs:element?minOccurs="0"?name="arg0"?type="tns:User"></xs:element>??
        32. ????????????<xs:element?name="sayHiToUserResponse"?type="tns:sayHiToUserResponse"></xs:element>??
        33. ????????????<xs:complexType?name="sayHiToUserResponse">??
        34. ????????????<xs:element?name="getUsers"?type="tns:getUsers"></xs:element>??
        35. ????????????<xs:complexType?name="getUsers">??
        36. ????????????????<xs:sequence></xs:sequence>??
        37. ????????????<xs:element?name="getUsersResponse"?type="tns:getUsersResponse"></xs:element>??
        38. ????????????<xs:complexType?name="getUsersResponse">??
        39. ????????????????????<xs:element?minOccurs="0"?name="return"?type="tns:IntegerUserMap"></xs:element>??
        40. ????????</xs:schema>??
        41. ????</wsdl:types>??
        42. ????<wsdl:message?name="getUsers">??
        43. ????????<wsdl:part?element="tns:getUsers"?name="parameters">??
        44. ????????</wsdl:part>??
        45. ????</wsdl:message>??
        46. ????<wsdl:message?name="sayHi">??
        47. ????????<wsdl:part?element="tns:sayHi"?name="parameters">??
        48. ????<wsdl:message?name="sayHiToUser">??
        49. ????????<wsdl:part?element="tns:sayHiToUser"?name="parameters">??
        50. ????<wsdl:message?name="sayHiToUserResponse">??
        51. ????????<wsdl:part?element="tns:sayHiToUserResponse"?name="parameters">??
        52. ????<wsdl:message?name="sayHiResponse">??
        53. ????????<wsdl:part?element="tns:sayHiResponse"?name="parameters">??
        54. ????<wsdl:message?name="getUsersResponse">??
        55. ????????<wsdl:part?element="tns:getUsersResponse"?name="parameters">??
        56. ????<wsdl:portType?name="iHelloWorld">??
        57. ????????<wsdl:operation?name="sayHi">??
        58. ????????????<wsdl:input?message="tns:sayHi"?name="sayHi">??
        59. ????????????</wsdl:input>??
        60. ????????????<wsdl:output?message="tns:sayHiResponse"?name="sayHiResponse">??
        61. ????????????</wsdl:output>??
        62. ????????</wsdl:operation>??
        63. ????????<wsdl:operation?name="sayHiToUser">??
        64. ????????????<wsdl:input?message="tns:sayHiToUser"?name="sayHiToUser">??
        65. ????????????<wsdl:output?message="tns:sayHiToUserResponse"?name="sayHiToUserResponse">??
        66. ????????<wsdl:operation?name="getUsers">??
        67. ????????????<wsdl:input?message="tns:getUsers"?name="getUsers">??
        68. ????????????<wsdl:output?message="tns:getUsersResponse"?name="getUsersResponse">??
        69. ????</wsdl:portType>??
        70. ????<wsdl:binding?name="HelloWorldSoapBinding"?type="tns:iHelloWorld">??
        71. ????????<soap:binding?style="document"??
        72. ????????????transport="http://schemas.xmlsoap.org/soap/http"></soap:binding>??
        73. ????????????<soap:operation?soapAction=""?style="document"></soap:operation>??
        74. ????????????<wsdl:input?name="sayHi">??
        75. ????????????????<soap:body?use="literal"></soap:body>??
        76. ????????????<wsdl:output?name="sayHiResponse">??
        77. ????????????????<soap:body?use="literal"></soap:body>??
        78. ????????????</wsdl:output>??
        79. ????????</wsdl:operation>??
        80. ????????<wsdl:operation?name="sayHiToUser">??
        81. ????????????<soap:operation?soapAction=""?style="document"></soap:operation>??
        82. ????????????<wsdl:input?name="sayHiToUser">??
        83. ????????????</wsdl:input>??
        84. ????????????<wsdl:output?name="sayHiToUserResponse">??
        85. ????????????<wsdl:input?name="getUsers">??
        86. ????????????<wsdl:output?name="getUsersResponse">??
        87. ????</wsdl:binding>??
        88. ????<wsdl:service?name="HelloWorld">??
        89. ????????<wsdl:port?binding="tns:HelloWorldSoapBinding"?name="HelloWorldImplPort">??
        90. ????????????<soap:address?location="http://localhost:9000/helloWorld"></soap:address>??
        91. ????????</wsdl:port>??
        92. ????</wsdl:service>??
        93. </wsdl:definitions>??

        生成异步 stub 代码

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

        http://java.sun.com/xml/ns/jaxws?命名空间)定义的。指定一个绑定声明有两种可选的方式:

        • 外部绑定声明?-?jaxws:bindings?元素被定义在WSDL契约之外的一个单独的文件。生成stub代码的时候,我们需要对wsdl2java 工具指定绑定声明文件的位置。
        • 嵌入式绑定声明?- 我们也可以直接把jaxws:bindings?元素嵌入到 WSDL 契约中,把它当做WSDL的扩展。在这种情况下,jaxws:bindings?的设置仅对直接的父元素起作用。

        本文只考虑第一种方法,即外部绑定声明。一个打开了异步调用开关的绑定声明文件的模版如下所示:

        copy
          <bindings?xmlns:xsd="http://www.w3.org/2001/XMLSchema"??
        1. ??????????xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"??
        2. ??????????wsdlLocation="http://localhost:9000/helloWorld?wsdl"??
        3. ??????????xmlns="http://java.sun.com/xml/ns/jaxws">??
        4. ??<bindings?node="wsdl:definitions">??
        5. true</enableAsyncMapping>??
        6. ??</bindings>??
        7. </bindings>??

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

        [@name='iHelloWorld']">?。

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

        wsdl2java -b async_binding.xml hello_world.wsdl

        其中-b 选项用来指定绑定声明文件。通过这种方法生成stub代码之后,HelloWorld的服务端点接口定义如下:

        copy
          import?java.util.concurrent.Future;??
        1. import?javax.jws.WebMethod;??
        2. import?javax.jws.WebParam;??
        3. import?javax.jws.WebResult;??
        4. import?javax.jws.WebService;??
        5. import?javax.xml.bind.annotation.XmlSeeAlso;??
        6. import?javax.xml.ws.AsyncHandler;??
        7. import?javax.xml.ws.RequestWrapper;??
        8. import?javax.xml.ws.Response;??
        9. import?javax.xml.ws.ResponseWrapper;??
        10. ??
        11. ??
        12. "iHelloWorld")??
        13. class})??
        14. interface?IHelloWorld?{??
        15. "com.neareast.test.cxf.asyClient.WSDL2Java.SayHi")??
        16. "com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse")??
        17. @WebMethod(operationName?=?"sayHi")??
        18. public?Response<com.neareast.test.cxf.asyClient.WSDL2Java.SayHiResponse>?sayHiAsync(??
        19. "")??
        20. ????????java.lang.String?text??
        21. ????);??
        22. public?Future<?>?sayHiAsync(??
        23. @WebParam(name?=?"asyncHandler"

        (编辑:李大同)

        【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读