使用JAX-WS调用异步Web服务:使用wsimport支持异步还是自己滚动?

时间:2012-07-01 15:18:55

标签: web-services asynchronous jax-ws jax-ws-customization

有一个excellent article by Young Yang解释了如何使用wsimport创建具有异步Web服务调用的Web服务客户端工件。异步要求WSDL具有标记

<enableAsyncMapping>true</enableAsyncMapping>

在其绑定部分。如果您使用自下而上的方法和JAX-WS带注释的Java类,则无法直接在WSDL中执行此操作,因为WSDL是Web服务器上生成的工件。相反,当在WSDL上执行wsimport时,您可以使用Ant或Maven等构建工具来包含此绑定。

生成的客户端工件具有返回

的异步方法调用
Future<?>

Response

这是一个未来。

在阅读杨的文章之后,我的问题是为什么不使用Executors和Futures滚动我自己的异步Web服务调用。 wsimport创建的工件是否提供了一些我无法通过自己的方法看到的优势?

如果有人对这两种方法都有经验或见解,我将非常感谢您的反馈。

2 个答案:

答案 0 :(得分:9)

理论上,生成的异步客户端不需要阻塞线程。通过传递AsyncHandler,系统可以在Web服务调用完成时使用NIO注册事件,并且可以调用该处理程序。没有线程需要阻止。

如果将同步 Web服务调用放入执行程序中,它仍将最终阻塞线程,直到结果到达,尽管至少此阻塞仅限于执行程序中的线程池。

只要有数百个线程浮动,系统性能就会因上下文切换而降低。

引擎盖下的Web服务库是否实际使用NIO是另一回事。它似乎不是JAX-WS规范所要求的。使用JDK 1.6并设置断点服务器端,我设置了100个客户端来调用服务器。使用附加到客户端的JVisualVM,可以看到它每次调用服务器时都创建了一个新线程。垃圾!

在Web上查看我发现Apache CXF支持限制异步调用中使用的线程池。果然,使用使用CXF生成的客户端并按照here所述在类路径上放置正确的库,重新测试显示只使用了25个线程。

那么为什么要使用jax-ws API而不是构建自己的API?因为建立自己的工作需要更多的工作; - )

答案 1 :(得分:5)

我知道它没有达到提示问题,只是补充问题中包含的一个信息:

“而是使用像Ant或Maven这样的构建工具在WSDL上执行wsimport时包含此绑定。”

可以通过使用选项-b向wsimport添加自定义xml文件来生成异步客户端:

示例:

wsimport -p helloAsyncClient -keep http://localhost:8080/helloservice?wsdl -b customAsync.xml

customAsync.xml内容:

<jaxws:bindings
        wsdlLocation="http://localhost:8080/helloservice?wsdl"
        xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
        <jaxws:enableAsyncMapping>true</jaxws:enableAsyncMapping>
</jaxws:bindings>

这是使用ant或maven生成异步客户端的另一种方法:)