使用開放源代碼框架的 Java 應用程序的 Web 服務集成模式,第 1 部分: 實現調用模式

發表于:2007-05-24來源:作者:點擊數: 標簽:框架java源代碼開放應用程序
主要有四種用于集成 Web 服務的模式。本系列包括兩個部分,本文是第 1 部分,將對 開發 服務和客戶機的方式進行建議,以便通過使用流行的開放源代碼框架調用采用所有四種服務端點模式的 Web 服務。我們將討論其中兩種模式,即請求-響應模式和單向端點模式,將
主要有四種用于集成 Web 服務的模式。本系列包括兩個部分,本文是第 1 部分,將對開發服務和客戶機的方式進行建議,以便通過使用流行的開放源代碼框架調用采用所有四種服務端點模式的 Web 服務。我們將討論其中兩種模式,即請求-響應模式和單向端點模式,將同時涵蓋文檔樣式和 RPC Web 服務調用演示的內容。本系列的下一篇文章將描述其他兩種集成模式,要求-響應模式和通知模式。

引言

在今天的企業中,Web 服務作為一項應用程序集成機制,正在迅速地擴大其應用領域。Web 服務還為應用程序提供了通過 Internet 與外部應用程序進行通信的功能,以實現企業間的 (B2B) 集成。簡單對象訪問協議(Simple Object Aclearcase/" target="_blank" >ccess Protocol,SOAP)是用于在此類情況下調用 Web 服務的協議之一。SOAP 提供了針對客戶機和服務間的通信進行了格式化的基于 XML 的標準化消息。SOAP 通常使用 HTTP 進行傳輸,但也支持使用 JMS 等其他傳輸協議。

服務的 Web 服務描述語言(Web Services Description Language,WSDL)定義提供該服務的細節,包括端點、端口、操作和消息等。服務和端點提供服務的連接細節,例如,如果服務可通過 HTTP 使用,則端點為一個 URL,如果服務可通過 JMS 使用,則端點提供 JMS 域名和查詢名。網絡服務端點的 WSDL 規范定義端點可支持的四個傳輸原語(也稱為操作)。即單向、請求-響應、要求-響應和通知。Web 服務可以通過四種模式中的任何一種進行調用。這些模式處于 WSDL 抽象級別,而到 SOAP 的“綁定”可通過將操作指定為面向 RPC 或面向文檔的操作而在集成機制方面提供更多的變化。Java™ 應用程序的一個總趨勢是在開發應用程序時使用開放源代碼軟件。不過,嘗試在 Java 應用程序中實現這些集成模式時,我們發現,并沒有任何單個開放源代碼軟件能提供同時實現所有四種模式的功能。為了實現這四種模式,我們必須將 Axis 和 WSIF 等組件中的各種可用功能結合使用。

在請求-響應模式中,端點(此時為實際的 Web 服務)在接收到需要響應的客戶機消息時,會發送回一個相關消息。在此模式中,客戶機——即應用程序——將調用 Web 服務,而 Web 服務對其進行響應;例如,當在線購物車向信用卡公司發送要記入借方的金額時,信用卡公司將使用事務 ID 進行響應。

在單向模式中,端點(Web 服務)從客戶機接收一個不需要進行響應的消息。在此模式中,客戶機(應用程序)向 Web 服務發送信息,且并不會等待響應??蛻魴C可以從服務請求一些信息,但它不會等待,而服務可以在稍后將響應發送回來。

后面的部分將討論如何實現 Java 應用程序與支持這兩種模式的服務端點的集成。





回頁首


用于 Web 服務實現的開放源代碼框架

Web 服務和客戶機可以通過使用各種開放源代碼框架來實現。來自 Apache 的 Axis 就是一個使用 Web 服務的框架,可以用于編寫 Web 服務客戶機。它提供了 Axis 服務器(實際是一個 SOAP 引擎)和一個 Axis 客戶機(可允許客戶機調用 SOAP Web 服務)。它使用 SOAP 作為進行通信的應用協議。Axis 缺省情況下支持 HTTP 作為傳輸協議,但也內置了一個 JMS 擴展。

Web 服務調用框架(Web Service Invocation Framework,WSIF)可用于為各種類型的服務編寫客戶機。它使用服務的 WSDL 定義來調用服務??梢允褂没?WSIF 的客戶機調用 Web 服務和調用使用 Java Message Service (JMS)、Enterprise JavaBean (EJB)、Java 程序及本機代碼實現的服務。使用 WSIF 的客戶機并不需要知道服務的實現細節,而僅需要服務的 WSDL 即可。

WSIF 框架使得編寫 Web 服務客戶機變得非常簡單,特別對于使用 JMS、Java 和 EJB 程序的動態客戶機更是如此。服務的參數細節在 WSDL 中定義,這些細節在執行時就已經知道了。

應該注意,WSIF 調用文檔樣式的 Web 服務方面有一些限制。從應用程序(在本例中為客戶機)的角度而言,我們將與請求-響應模式集成歸類為“同步調用”類型的活動,而單向模式則屬于“異步調用”類型。





回頁首


應用程序客戶機端點調用的請求

同步調用

在同步調用中,客戶機將消息發送給服務,并等待響應。服務接收到該消息,對其進行處理,并發送回響應。

按照 WSDL 語法中的定義,請求-響應操作包含輸入和輸出元素——首先是輸入,然后是輸出。


清單 1. 請求-響應操作的 WSDL
            <wsdl:definitions .... >
            <wsdl:portType .... > *
            <wsdl:operation name="nmtoken" parameterOrder="nmtokens">
            <wsdl:input name="nmtoken"? message="qname"/>
            <wsdl:output name="nmtoken"? message="qname"/>
            <wsdl:fault name="nmtoken" message="qname"/>*
            </wsdl:operation>
            </wsdl:portType >
            </wsdl:definitions>
            

WSIF 可提供動態調用 Web 服務的靈活性。WSIF 將對 WSDL 進行解析,獲取為服務定義的關于服務、端口、綁定和操作的信息。用戶可以在運行時選擇端口、傳輸和操作,并提供輸入參數來調用 Web 服務。此處的優勢在于,不需要為每個 Web 服務編寫獨立的客戶機。使用 WSIF 的另一個優勢是,即使 Web 服務的端點改變,客戶機也不用改變。事實上,客戶機甚至不需要知道 Web 服務的位置。而且,如果在將來給定服務作為 EJB 提供,客戶機可以使用新 WSDL 調用 EJB,而不要對客戶機代碼進行任何修改。WSIF 對 WSDL 進行分析,從而為輸入、輸出和錯誤的 WSIFService、WSIFPort、WSIFoperation、WSIFMessage 創建對象實例,并執行相應操作。WSIF 分發中提供了一個動態調用 Web 服務的一個示例。此方法特別適用于調用簡單 Web 服務。WSIF 可以用于調用 RPC 和文檔樣式的 Web 服務。在清單 2 中,示例代碼演示了如何使用 WSIF 來調用 RPC 樣式的 Web 服務。


清單 2. 使用 WSIF 的 RPC 樣式請求-響應 Web 服務客戶機示例代碼
            // ...
            // get service factory object
            WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
            // get service object for given wsdl definition object and service object
            WSIFService dpf =
            factory.getService(definition, service);
            // get port from wsif service object for given port name
            port = dpf.getPort(portName);
            // get operation object from port object for given operation and input/output message names
            MILY: Andale Mono, Lucida Console, Monaco, fixed, monospace" twffan="done">|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
            WSIFOperation operation = port.createOperation(
            operationName,
            inputMessage,
            outputMessage);
            // create input message
            WSIFMessage input = operation.createInputMessage();
            // invoke the service
            operation.executeRequestResponseOperation(input, output, fault);
            

如果 Web 服務是文檔樣式的 Web 服務,則應用程序可以使用 Axis 客戶機:

  • 應用程序動態創建一個客戶機(在應用程序執行期間完成),并使用 Web 服務定義中提供的端點信息(具體的端口地址)。
  • 客戶機創建 Axis 客戶機的“Call”對象的實例,并將 Call 對象中的目標端點地址設置為 Web 服務端點的地址。
  • 接下來,客戶機讀取調用的服務所需的輸入參數。為此,客戶機會在運行時使用 JAXB[12] 將 Java 格式的輸入參數轉換為 XML 元素對象 (org.w3c.dom.Element)。Java Architecture for XML Binding (JAXB) 提供了一種非常方便的方法,可將 XML 模式綁定到 Java 代碼中的表示形式。
  • 客戶機將創建一個由這些 Element 對象組成的數組,并調用 Axis Call 對象的 invoke 方法。
  • invoke 方法構造 SOAP 請求消息,并通過發送消息來調用服務,從服務獲取輸出參數,然后將其作為 org.apache.axis.message.SOAPBodyElement 對象數組返回給客戶機。
  • 客戶機然后構造與從服務接受到的輸出參數對應的等效 Java 對象,這同樣也是在運行時使用 JAXB(從 XML 到 Java 綁定)完成的。
  • 然后,客戶機將這一組 Java 對象提供給應用程序。

 

這種調用方法尤其適合用于調用具有復雜數據類型的文檔樣式 Web 服務。會首先使用 JAXB 將復雜數據類型轉換為 XML,然后傳遞給服務調用者。輸入參數也以 XML 格式接收,并使用 JAXB 解析回 Java 對象。


清單 3. 使用 WSIF 的 RPC 樣式請求-響應 Web 服務客戶機示例代碼
            SOAPBodyElement[] element = // create SOAPBodyElement array using input objects
            // create call object
            Service service = new Service();
            Call call = (Call) service.createCall();
            // set end point (http address)
            call.setTargetEndpointAddress(endPoint);
            // invoke the service by passing the SOAPBodyElement
            Vector output = (Vector) call.invoke(element);
            // create element array from vector
            Element elemArray[] = new Element[output.size()];
            for (int i = 0; i < output.size(); i++) {
            if (output.get(i) instanceof Element) {
            elemArray[i] = (Element) output.get(i);
            }
            if (output.get(i) instanceof SOAPBodyElement) {
            elemArray[i] = ((SOAPBodyElement) output.get(i)).getAsDOM();
            }
            }
            // convert Element array back into Java Objects using JAXB
            

異步調用

在異步調用中,客戶機將消息發送到服務,服務然后使用該消息。此時,客戶機并不會等待服務進行應答。

如 WSDL 語法所定義的,單向操作僅具有輸入元素。


清單 4. 單向操作的 WSDL
            <wsdl:definitions> <wsdl:portType .... > *
            <wsdl:operation name="nmtoken">
            <wsdl:input name="nmtoken"? message="qname"/>
            </wsdl:operation>
            </wsdl:portType >
            </wsdl:definitions>>
            

可以通過使用 SOAP over JMS 實現異步調用。JMS 的缺省行為就是進行異步消息傳遞。


清單 5. 使用 SOAP over JMS 的單向 Web 服務客戶機示例代碼
            // ...
            // provide JMS handler
            Call.addTransportPackage(packageName);
            Call.setTransportForProtocol(
            "JMSTransport",
            JMSTransport.class);
            // get client configuration
            EngineConfiguration defaultConfig =
            (new
            DefaultEngineConfigurationFactory()).getClientEngineConfig();
            // create custom configuration for client
            SimpleProvider config = new SimpleProvider(defaultConfig);
            // get chain for given transport
            SimpleTargetedChain chain =
            new SimpleTargetedChain(
            new JMSSender(connectionFactory, destination));
            config.deployTransport("JMSTransport", chain);
            // create service using custom configuration
            Service service = new Service(config);
            Call call = (Call) service.createCall();
            call.setOperation(super.getOperation());
            // set JMS specific information (topic/queue name, context factory) in call
            // these values will be needed in chain for actually sending JMS message
            call.setProperty(JMSConstants.DESTINATION, destination);
            call.setProperty(
            "transport.jms.ConnectionFactoryJNDIName",
            connectionFactory);
            if (destinationDomain.equalsIgnoreCase("topic")) {
            call.setProperty(JMSConstants.DOMAIN,
            JMSConstants.DOMAIN_TOPIC);
            }
            if (destinationDomain.equalsIgnoreCase("queue")) {
            call.setProperty(JMSConstants.DOMAIN,
            JMSConstants.DOMAIN_QUEUE);
            }
            call.setTransport(new JMSTransport());
            // invoke the web service
            call.invoke(params);
            // ...
            

WSIF 支持異步調用??梢酝ㄟ^調用 API 中的不同方法來使用 WSIF 客戶機進行異步調用。


清單 6. 使用 WSIF 的單向 Web 服務客戶機示例代碼
            // ...
            // create operation
            WSIFOperation operation = port.createOperation(
            operationName,
            inputMessage,
            outputMessage);
            // prepare input
            WSIFMessage input = operation.createInputMessage();
            // invoke web service one-way
            operation.executeInputOnlyOperation(input);
            // ...
            





回頁首


結束語

在本文中,我們對 Web 服務端點的請求-響應模式和單向模式進行了詳細的討論。而且說明,在標識了功能后,可以如何使用采用開放源代碼框架的相應 Web 服務來支持這兩種模式。在本系列的第 2 部分,我們將討論 Web 服務中涉及的客戶機端點可支持的其他兩個集成模式,即要求-響應模式和通知模式。

原文轉自:http://www.anti-gravitydesign.com

評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97