WebService之Axis2系列教程(七)非同步呼叫WebService

來源:互聯網
上載者:User

在前面幾篇文章中都是使用同步方式來調用WebService。也就是說,如果被調用的WebService方法長時間不返回,用戶端將一直被阻塞,直到該方法返回為止。使用同步方法來調用WebService雖然很直觀,但當WebService方法由於各種原因需要很長時間才能返回的話,就會使用戶端程式一直處於等待狀態,這樣使用者是無法忍受的。
       當然,我們很容易就可以想到解決問題的方法,這就是多線程。解決問題的基本方法是將訪問WebService的任務交由一個或多個線程來完成,而主線程並不負責訪問WebService。這樣即使被訪問的WebService方法長時間不返回,用戶端仍然可以做其他的工作。我們可以管這種通過多線程訪問WebService的方式稱為非同步訪問。
       雖然直接使用多線程可以很好地解決這個問題,但比較麻煩。幸好Axis2的用戶端提供了非同步訪問WebService的功能。
       RPCServiceClient類提供了一個invokeNonBlocking方法可以通過非同步方式來訪問WebService。下面先來建立一個WebService。
       MyService是一個WebService類,代碼如下:

       package service;       public class MyService {              public String getName() {                     try {                                        System.out.println("getName方法正在執行 ");                            //  延遲5秒                            Thread.sleep(5000);                     } catch (Exception e) {                                                         }                     return "火星";              }       }

      為了類比需要一定時間才返回的WebService方法,在getName方法中使用了sleep方法來延遲5秒。
       下面是MyService類的配置代碼:

       <!--  services.xml  -->       <service name="myService">              <description>                     非同步呼叫示範              </description>              <parameter name="ServiceClass">                     service.MyService                 </parameter>              <messageReceivers>                     <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"                            class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />              </messageReceivers>       </service>

      從上面的配置代碼可以看出,MyService的配置方式與前幾章的WebService的配置方式完全一樣,也就是說,MyService只是一個普通的WebService。
       下面是非同步呼叫MyService的Java用戶端代碼:

       package client;              import javax.xml.namespace.QName;       import org.apache.axis2.addressing.EndpointReference;       import org.apache.axis2.client.Options;       import org.apache.axis2.context.MessageContext;       import org.apache.axis2.rpc.client.RPCServiceClient;              public class RPCAsyncClient {              public static void main(String[] args) throws Exception {                     RPCServiceClient serviceClient = new RPCServiceClient();                     Options options = serviceClient.getOptions();                     EndpointReference targetEPR = new EndpointReference(                            "http://localhost:8080/axis2/services/myService");                     options.setTo(targetEPR);                     Object[] opAddEntryArgs = new Object[]{};                     QName opAddEntry = new QName("http://service", "getName");                     serviceClient.invokeNonBlocking(opAddEntry, opAddEntryArgs,                            new org.apache.axis2.client.async.AxisCallback() {                            @Override                            public void onComplete() {}                            @Override                            public void onError(Exception arg0) {}                                                @Override                            public void onFault(MessageContext arg0) {}                            @Override                            public void onMessage(MessageContext mc) {                                          //  輸出傳回值                                          System.out.println(mc.getEnvelope().getFirstElement()                                                 .getFirstElement().getFirstElement().getText());                            }                            });                     System.out.println("非同步呼叫!");                     //  阻止程式退出                     System.in.read();              }       }  

      從上面的代碼可以看出,invokeNonBlocking方法有三個參數,前兩個參數分別指定了要調用的方法及方法參數的相關資訊,而最後一個參數並不是方法傳回值的類型資訊,而是一個實現org.apache.axis2.client.async.AxisCallback介面的類的對象執行個體。在本例中隱式實現了AxisCallback介面。在AxisCallback介面中有四個方法需要實現,其中當被非同步呼叫的方法返回時onMessage方法被調用。當運行上面的程式後,將輸出如下的資訊:

      非同步呼叫!
       火星

      雖然上面的例子可以實現非同步呼叫,但比較麻煩。為了更方便地實現非同步呼叫,可以使用wsdl2java命令的-a參數產生可非同步呼叫的Stub類。下面的命令可產生同步和非同步呼叫的用戶端代碼(兩個類),其中-s表示產生同步調用代碼,-a表示產生非同步呼叫代碼。

       %AXIS2_HOME%\bin\wsdl2java        -uri http://localhost:8080/axis2/services/myService?wsdl -p client -s -a -o stub

      在執行上面的命令後,將產生兩個類:MyServiceStub和MyServiceCallbackHandler類,其中MyServiceStub類負責同步和非同步呼叫WebService,MyServiceCallbackHandler類是一個抽象類別,也是一個回調類,當使用非同步方式調用WebService方法時,如果方法返回,則MyServiceCallbackHandler類的receiveResultgetName方法被調用。下面是使用MyServiceStub類非同步訪問WebService的代碼:

       package client;              import client.MyServiceStub.GetNameResponse;              class MyCallback extends MyServiceCallbackHandler {              @Override              public void receiveResultgetName(GetNameResponse result) {                     //  輸出getName方法的返回結果                     System.out.println(result.get_return());              }       }       public class StubClient {              public static void main(String[] args) throws Exception  {                     MyServiceStub stub = new MyServiceStub();                             //  非同步呼叫WebService                     stub.startgetName(new MyCallback());                     System.out.println("非同步呼叫!");                     System.in.read();                  }        }

      執行上面的程式後,將輸出如下的資訊:    

       非同步呼叫!
       火星

 

 

 

 

 

教程源碼下載:

AxisTest

AxisSpring

AxisProject

 

轉載請標明出處http://blog.csdn.net/shimiso

歡迎有識之士加入我們的技術交流群:173711587

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.