Terry.Li-彬

          虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks
          客戶端的調用

            Web services提供的服務多種多樣,有的可以馬上獲得結果,有的要消耗很長的時間。所以,如果我們需要多種調用方式來對付不同的情況。

            大多數的Web services都提供阻塞(Blocking)和非阻塞(Non-Blocking)兩種APIs.

            這兩個概念以前應該學過,簡單說一下。

            Blocking API - 調用端要等被調用的函數運行完畢才繼續往下走。

            Non-Bloking API - 調用端運行完調用函數以后就直接往下走了,調用端和被調用端是異步執行的。返回值是用回調函數來實現的。

            這種異步叫做API層異步(API Level Asynchrony)。他們只用到一個連接來發送和接收消息,而且,如果是那種需要運行很長時間的函數,還會碰到Time Out 錯誤,如果用兩個連接分別處理發送和接收消息,調用的時間就可以縮短,也可以解決Time Out 問題。用兩個連接來分別處理發送和接收消息,叫做傳輸層異步(Transport Level Asynchrony)。

            


            


            理論真無聊,還是來看實例吧。

            打開 Eclipse, 創建一個新Project, 新建一個叫userguide.clients的包, 把"samples\userguide\src\userguide\clients" 下面的文件都copy到那個包下面, 把AXIS2的lib下面的jar都加到ilbrary里面去(應該不用全加,懶一點就全加了吧.) 發現了關于echo的調用的方式, 居然有五個:

            EchoBlockingClient

            EchoBlockingDualClient

            EchoBlockingWsaBasedClient

            EchoNonBlockingClient

            EchoNonBlockingDualClient

            一個一個看吧.

            EchoBlockingClient.java

            public class EchoBlockingClient {

            private static EndpointReference targetEPR = new EndpointReference("http://localhost:8080/axis2/services/MyService");

            public static void main(String[] args) {

            try {

            OMElement payload = ClientUtil.getEchoOMElement();

            Call call = new Call();

            call.setTo(targetEPR);

            call.setTransportInfo(Constants.TRANSPORT_HTTP,

            Constants.TRANSPORT_HTTP,

            false);

            //Blocking invocation

            OMElement result = call.invokeBlocking("echo",

            payload);

            StringWriter writer = new StringWriter();

            result.serializeWithCache(XMLOutputFactory.newInstance()

            .createXMLStreamWriter(writer));

            writer.flush();

            System.out.println(writer.toString());

            } catch (AxisFault axisFault) {

            axisFault.printStackTrace();

            } catch (XMLStreamException e) {

            e.printStackTrace();

            }

            }

            }

            和一代幾乎一樣, 弄一個EndpointReference, 再弄一個call, 其他不一樣,但是也很簡單, 弄一個OMElement作為參數, 返回也是一個OMElement. 可惜運行居然有錯.

            再來看雙通道的版本

            EchoBlockingDualClient.java

            public class EchoBlockingDualClient {

            private static EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");

            public static void main(String[] args) {

            try {

            OMElement payload = ClientUtil.getEchoOMElement();

            Call call = new Call();

            call.setTo(targetEPR);

            call.engageModule(new QName(Constants.MODULE_ADDRESSING));

            call.setTransportInfo(Constants.TRANSPORT_HTTP,

            Constants.TRANSPORT_HTTP,

            true);

            //Blocking Invocation

            OMElement result = call.invokeBlocking("echo",

            payload);

            StringWriter writer = new StringWriter();

            result.serializeWithCache(XMLOutputFactory.newInstance()

            .createXMLStreamWriter(writer));

            writer.flush();

            System.out.println(writer.toString());

            //Need to close the Client Side Listener.

            call.close();

            } catch (AxisFault axisFault) {

            axisFault.printStackTrace();

            } catch (Exception ex) {

            ex.printStackTrace();

            }

            }

            }

            加了一句engageModule, 這句話好像沒什么用,我刪掉這句話也能運行的, 然后setTransportInfo最后一個參數改成了true. 關于setTransportInfo的三個參數, 第一個是發送的Transport, 第二個是接收的Transport, 第三個是"是否雙通道", 支持的搭配形式如下:

            http, http, true

            http, http, false

            http,smtp,true

            smtp,http,true

            smtp,smtp,true

            看下一個吧,EchoNonBlockingClient,這個是單通道的非阻塞模式:

            public class EchoNonBlockingClient {

            private static EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");

            public static void main(String[] args) {

            try {

            OMElement payload = ClientUtil.getEchoOMElement();

            Call call = new Call();

            call.setTo(targetEPR);

            call.setTransportInfo(Constants.TRANSPORT_HTTP,

            Constants.TRANSPORT_HTTP,

            false);

            //Callback to handle the response

            Callback callback = new Callback() {

            public void onComplete(AsyncResult result) {

            try {

            StringWriter writer = new StringWriter();

            result.getResponseEnvelope().serializeWithCache(XMLOutputFactory.newInstance()

            .createXMLStreamWriter(writer));

            writer.flush();

            System.out.println(writer.toString());

            } catch (XMLStreamException e) {

            reportError(e);

            }

            }

            public void reportError(Exception e) {

            e.printStackTrace();

            }

            };

            //Non-Blocking Invocation

            call.invokeNonBlocking("echo", payload, callback);

            //Wait till the callback receives the response.

            while (!callback.isComplete()) {

            Thread.sleep(1000);

            }

            } catch (AxisFault axisFault) {

            axisFault.printStackTrace();

            } catch (Exception ex) {

            ex.printStackTrace();

            }

            }

            }

            不同的地方,只是調用的方法從invokeBlocking變成了invokeNonBlocking,然后寫了一個簡單的匿名Callback類作為回調函數。關于這個Callback類,它是一個抽象類,其中有兩個方法:onComplete和reportError,都是client端必須實現的,他還有一個Field,就是complete,可以用來設置和查詢調用是否完成。可惜也不能運行,和上面的錯誤一樣,是在createSOAPMessage的時候報null錯誤。

            看下一個EchoNonBlockingDualClient,非阻塞的雙通道:

            public class EchoNonBlockingDualClient {

            private static EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");

            public static void main(String[] args) {

            try {

            OMElement payload = ClientUtil.getEchoOMElement();

            Call call = new Call();

            call.setTo(targetEPR);

            //The boolean flag informs the axis2 engine to use two separate transport connection

            //to retrieve the response.

            call.engageModule(new QName(Constants.MODULE_ADDRESSING));

            call.setTransportInfo(Constants.TRANSPORT_HTTP,

            Constants.TRANSPORT_HTTP,

            true);

            //Callback to handle the response

            Callback callback = new Callback() {

            public void onComplete(AsyncResult result) {

            try {

            StringWriter writer = new StringWriter();

            result.getResponseEnvelope().serializeWithCache(XMLOutputFactory.newInstance()

            .createXMLStreamWriter(writer));

            writer.flush();

            System.out.println(writer.toString());

            } catch (XMLStreamException e) {

            reportError(e);

            }

            }

            public void reportError(Exception e) {

            e.printStackTrace();

            }

            };

            //Non-Blocking Invocation

            call.invokeNonBlocking("echo", payload, callback);

            //Wait till the callback receives the response.

            while (!callback.isComplete()) {

            Thread.sleep(1000);

            }

            //Need to close the Client Side Listener.

            call.close();

            } catch (AxisFault axisFault) {

            axisFault.printStackTrace();

            } catch (Exception ex) {

            ex.printStackTrace();

            }

            }

            }

            雙通道和單通道基本沒什么不同,只是雙通道的時候,它總是要
          posted on 2007-11-21 18:08 禮物 閱讀(313) 評論(0)  編輯  收藏 所屬分類: web service
          主站蜘蛛池模板: 前郭尔| 布尔津县| 德州市| 文山县| 枣阳市| 梅河口市| 阿拉尔市| 靖安县| 涟水县| 边坝县| 和静县| 拉孜县| 德令哈市| 苍溪县| 清新县| 海宁市| 奉化市| 太谷县| 龙江县| 育儿| 吴堡县| 临沭县| 吴桥县| 咸丰县| 阿尔山市| 河间市| 平阴县| 霸州市| 安丘市| 扶风县| 静乐县| 蒙山县| 金昌市| 辽宁省| 黄平县| 汉源县| 江口县| 吴旗县| 龙州县| 广宁县| 福建省|