JAX-WS 异步

WebService最外层的包装其实是一个com.sun.xml.ws.transport.http.servlet.WSServlet。根据servlet的生命周期,每一个新的request,都是一个独立的线程。线程之间是无联系的,除了statful,statful将在后面文章中描述。

在每个request都是独立线程的情况下,server端的异步并不是很必要。但JAXWS还是提供了server端异步的机制。

在client端,异步是很重要的,就像浏览器在加载页面的时候,会异步的加载JS,CSS和图片一样。异步是提高客户端性能的重要手段。

前提

在理解JAXWS异步机制之前,必须要先了解Provider, Dispatch和Customization. 这三部分均可以再前面的文章中找到。

概括

在JAXWS中,异步的实现有3种方式:

  1. 只针对Server端,使用AsyncProvider.

  2. 只针对Client端,使用Dispatch。

  3. 只针对Client端,使用Customization产生异步service port operation。

前两种方法使用的是面向消息编程。AsyncProvider与Provider类似,只是AsyncProvider提供了一个异步方法,使用callback的方式异步返回消息。 Dispatch则提供了两个异步方法,一个是使用Future polling的方式,一个是使用callback方式。

第3中方式则是针对面向逻辑,面向对象的Service Port。使用wsimport命令,将WSDL+customization转成支持持异步的Web Service client。

下面,我将上一篇文章中的图书馆系统的client端,改造其中的一个addBook方法成异步方法。

创建customization文件

基于前一篇文章之中图书馆系统,其服务地址为http://localhost:8080/library/service 

我们使用wsimport来创建客户端,在创建客户端之前,必须先创建customization,以使addBook operation能转为异步方法。

custom.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    wsdlLocation="http://localhost:8080/library/service?wsdl=1"
    xmlns="http://java.sun.com/xml/ns/jaxws">
    <enableWrapperStyle>true</enableWrapperStyle>
    <enableAsyncMapping>false</enableAsyncMapping>
    
    <!-- wsdl:portType operation customization -->    
    <bindings node="wsdl:definitions/wsdl:portType[@name='Library']/wsdl:operation[@name='addBook']">
        <enableAsyncMapping>true</enableAsyncMapping>
    </bindings> 
    
</bindings>

生成客户端

因为Project是用Maven创建,所以wsimport用的是maven中的插件。

      <plugin>
        <groupId>org.jvnet.jax-ws-commons</groupId>
        <artifactId>jaxws-maven-plugin</artifactId>
        <version>2.3</version>
        <executions>
          <execution>
            <id>wsimport-from-jdk</id>
            <goals>
              <goal>wsimport</goal>
            </goals>
            <configuration>
              <executable>${tool.wsimport}</executable>
              <wsdlUrls>
                <wsdlUrl>http://localhost:8080/library/service?wsdl</wsdlUrl>
              </wsdlUrls>
              <bindingFiles>
                <bindingFile>d:/share/custom.xml</bindingFile>
              </bindingFiles>
              <verbose>true</verbose>
              <xdebug>true</xdebug>
            </configuration>
          </execution>
        </executions>
      </plugin>

运行mvn generate-sources

将产生的java文件复制到项目src中。

011047_A5hq_254689.png

打开Library.java文件,发现addBook产生了3个方法:

    /**
     * 
     * @param book
     * @return
     *     returns javax.xml.ws.Response<com.mycompany.library.AddBookResponse>
     */
    @WebMethod(operationName = "addBook")
    @RequestWrapper(localName = "addBook", targetNamespace = "http://library.mycompany.com", className = "com.mycompany.library.AddBook")
    @ResponseWrapper(localName = "addBookResponse", targetNamespace = "http://library.mycompany.com", className = "com.mycompany.library.AddBookResponse")
    public Response<AddBookResponse> addBookAsync(
        @WebParam(name = "book", targetNamespace = "http://library.mycompany.com")
        Book book);

    /**
     * 
     * @param book
     * @param asyncHandler
     * @return
     *     returns java.util.concurrent.Future<? extends java.lang.Object>
     */
    @WebMethod(operationName = "addBook")
    @RequestWrapper(localName = "addBook", targetNamespace = "http://library.mycompany.com", className = "com.mycompany.library.AddBook")
    @ResponseWrapper(localName = "addBookResponse", targetNamespace = "http://library.mycompany.com", className = "com.mycompany.library.AddBookResponse")
    public Future<?> addBookAsync(
        @WebParam(name = "book", targetNamespace = "http://library.mycompany.com")
        Book book,
        @WebParam(name = "asyncHandler", targetNamespace = "")
        AsyncHandler<AddBookResponse> asyncHandler);

    /**
     * 
     * @param book
     * @return
     *     returns com.mycompany.library.Book
     */
    @WebMethod
    @WebResult(name = "result", targetNamespace = "http://library.mycompany.com")
    @RequestWrapper(localName = "addBook", targetNamespace = "http://library.mycompany.com", className = "com.mycompany.library.AddBook")
    @ResponseWrapper(localName = "addBookResponse", targetNamespace = "http://library.mycompany.com", className = "com.mycompany.library.AddBookResponse")
    @Action(input = "http://library.mycompany.com/Library/addBookRequest", output = "http://library.mycompany.com/Library/addBookResponse")
    public Book addBook(
        @WebParam(name = "book", targetNamespace = "http://library.mycompany.com")
        Book book);

其中addBook是同步方法,addBookAsync是异步方法,两个addBookAsync中,一个是Future Poll模式,另一个是callback模式。

使用异步方法

在App.java的main函数中,演示一下异步调用的使用:

public class App {
    public static void main( String[] args ) throws InterruptedException, ExecutionException {
        Library port = new LibraryImplService().getLibraryImplPort();
        
        // polling
        Book newBook = new Book();
        newBook.setAuthor("xpbug");
        newBook.setName("java");
        Response<AddBookResponse> response = port.addBookAsync(newBook);
        while (!response.isDone()) {
            Thread.sleep(1000);
        }
        printBook(response.get().getResult());
        
        // callback
        newBook = new Book();
        newBook.setAuthor("cat");
        newBook.setName("c++");
        port.addBookAsync(newBook, new CallbackHandler());
        // wait 8 seconds then exit program.
        Thread.sleep(8000);
    }
    
    public static void printBook(Book book) {
        System.out.println("[id="+book.getId()+"; name="+book.getName()+"; author="+book.getAuthor()+"]");
    }
    
    private static class CallbackHandler implements AsyncHandler<AddBookResponse> {
        public void handleResponse(Response<AddBookResponse> response) {
            try {
                printBook(response.get().getResult());
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


转载于:https://my.oschina.net/xpbug/blog/229008

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值