<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kapok

    垃圾桶,嘿嘿,我藏的這么深你們還能找到啊,真牛!

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      455 隨筆 :: 0 文章 :: 76 評論 :: 0 Trackbacks
    http://www.ftponline.com/china/XmlFile.aspx?ID=258

    見資源
    將異步消息傳遞(如Java Message Service)與SOAP結合起來就意味著Web services可以有更多的用途。
    by David Chappell and Tony Hong

    直到最近,Web services的用途一直集中于通過HTTP實現的同步請求/回應模式(request/reply model)。這是很自然的,因為Web services的第一個用例就是集中在Remote Procedure Call(RPC)和分布式組件交互的。然而,Web services的這種應用情況忽視了當今IT前景的一個重大的方面:異步消息傳遞(asynchronous messaging),它有很大的價值,因為它給數據傳輸和處理帶來了一定的可靠性和靈活性,這些性能是同步消息傳遞很難實現的。通過異步消息傳輸機制(如JMS),把異步消息傳遞同SOAP結合起來就可以將如今的Web services標準應用到更廣的領域。

    將這種技術結合用于重要的企業集成環境是最受歡迎的了。該領域一直是由Electronic Data Interchange (EDI)、Enterprise Application Integration(EAI)和B2B統治的——然而IT社團一直在尋找成本更低、更高效、更基于標準的方法。在這些領域中,用即時的同步RPC來換取一些功能會讓我們更滿意,這些功能包括可靠的傳遞能力、更適合面向企業交易的松散耦合的、粗粒度的(coarse-grained)接口;面向文檔的異步交互和對通訊協議和傳輸機制的支持。

    讓我們看看JMS是如何成為一種可靠的異步SOAP消息傳遞的方法的。我們也將探討如何將JMS用于可靠的Web services調用。(你可以在這里下載樣例代碼;注意,你需要接受一個許可協議并在www.xmethods.net網站上注冊。)

    
				圖1.
    圖1. 多方同步通訊
    許多Web services都運用一個同步的RPC模式,在這個模式中,服務呈現細粒度的(fine-grained)接口,而且一個Web services客戶端調用RPC型(RPC-style)的交互。在一個RPC型的環境中,參與一個單獨的通訊流程的所有的應用程序和服務都必須是可用的,以使多方通訊成功。在有些情況下,同步模式是必需的,比如當服務傳遞的信息在本質上是實時的(如詳細目錄查找)時候。然而,這種同步處理是一種要么全有要么全無的(all-or-nothing)命題。如果由于某種原因不能得到一個下行的(downstream)服務,那么提出請求的應用程序及其上行的(upstream)參與者就需要處理應用程序代碼中的錯誤(見圖1)。

    可靠的異步通訊是指,為了保持整個環境的健全,系統的所有方面不需要在任何特定的時候都是可用的。即使對于一個簡單的兩方客戶端/服務(client/service)交互來說,運用可靠的異步通訊就意味著,當客戶端對服務提出請求時,被調用的服務不需要是可用的。客戶端將請求傳遞到一個可靠的異步傳輸機制中,該請求暫時不能與服務進行對話。然后客戶端本身變成不可用的,當服務成為可用的時,就可以進行服務調用了。

    處于等待狀態的(pending)交互
    異步交互也不需要客戶端等待響應。一個Web service端點(end point)可以代表一個應用程序,它需要一些時間來執行計算、查找或轉換等任務。對一個服務提出異步請求的客戶端可以繼續執行其它任務,同時其Web service交互處于等待狀態。這就提高了并行性(concurrency)和可擴展性。

    細粒度的RPC型的接口需要每個應用程序和服務都知道它們是如何同其它應用程序和服務進行通訊的。例如,一個訂單接口上可能有諸如getQuantity()、getTotal()或getBillToAddress()等方法。

    粗粒度、文本型(document-style)的接口是指,每個應用程序或服務只需要關心封裝的XML文檔,該XML文檔包含所有相關的信息,服務可以與其它感興趣者共享這些信息,并可以以SOAP envelope的形式將這些信息發送給他們。同樣,在使用服務時,我們可以從XML文檔選擇相關的數據(例如<ShipTo>地址),進行相應的處理,然后將結果發送到其它目的地。當你將異步交互同文本型、粗粒度的接口結合起來時,你就為消息傳遞形式的調用做好了主要準備了。

    
				圖2.
    圖2. 消息隊列
    得到可靠的異步通訊的最明智的方法就是運用基于JMS的消息隊列。JMS是個標準,它提供了一組通用API讓應用程序使用,并提供了一組通用的消息傳遞語義,如確保消息傳遞、消息一定會被傳遞且僅傳遞一次(once-and-only-once delivery)。JMS將其性能和執行原則封裝在自己的層中,這個層是同應用程序層分離的。一個將基于JMS消息傳遞系統作為傳輸機制的應用程序不需要關心消息是如何傳遞的。SOAP消息可以在發送者和接收者之間列隊等待(見圖2)。JMS提供者負責處理異步、消息持續性、交易完整性和接收確認等所有方面。

    Java 2 Platform、Enterprise Edition(J2EE)架構圖總是將JMS看做是個隱藏在防火墻后面的組件,通過它我們在一個JSP servlet引擎和消息驅動的bean之間異步地傳遞消息。如果你在制作Web頁面并將它們同中間層商業邏輯結合起來,那么這個架構就是個有效的用例,但這并不是運用消息傳遞的唯一的方式。

    JMS消息傳遞機制是跨Internet傳遞數據、SOAP或其它信息的一個完全可行的解決方案。一個JMS機制可以在哪里部署以及如何部署的細節取決于供應商。許多JMS供應商都提供某種通道性能(tunneling capabilities)。例如,在SonicMQ例子中,JMS客戶端到JMS服務器的通訊可以很容易地跨越公開的Internet、跨越防火墻、以一種運用HTTP、HTTPS、SSL或TCP sockets的安全的、可靠的方式進行。

    將JMS作為一種SOAP傳輸機制
    自1998年被引進到業界以來,JMS就作為一種基于標準的消息傳遞方法,在應用程序之間傳輸SOAP消息。它有五種消息類型,可以傳遞任何類型的數據(基于XML或不基于XML)。XML數據可以很容易地作為一個JMS BytesMessage中的二元數據或作為TextMessage中的串數據(string data)來傳遞。

    不管對話兩端運用何種API,我們把傳輸層上運用的JMS看做是除了普通的、老的HTTP傳輸之外的另一種可選方法。在我們的例子中,我們將JMS的API和Apache SOAP結合起來了——運用JMS API來連接、發送和接收消息,運用Apache SOAP來建構(construct)和析構(deconstruct)SOAP envelope。在不久的將來,JMS將作為一個傳輸層被嵌入到Apache Axis中。JMS將會成為一個部署選項。

    JMS也有一個內置的同步請求/回應模式。這個請求/回應模式也可以異步地工作。請求者不需要block請求,等待即時的響應。響應可以在稍后的時間異步地發送。JMS可以使最初的請求消息同相應的響應消息關聯起來,即使請求和響應在時間上是分離的,或者即使請求過程在失敗后又恢復正常。

    XMethods中列出的BabelFish服務給AltaVista的很受歡迎的BabelFish翻譯工具提供了一個典型的PRC SOAP接口(見資源)。下面我們來看一下這個Web service的一個異步版本,稱為AsynchBabelFish。

    從根本上說,該服務主要是異步交換SOAP文檔。客戶端給服務發送一個AsynchBabelFish轉換請求文檔,一段時間后,服務將一個AsynchBabelFish轉換結果文檔發送回客戶端。交換是在消息隊列上完成的。從這個簡單的例子,我們可以看到的一個明顯的好處就是,即使服務出了問題,客戶端也不會受影響;它可以將請求放到服務隊列中,該請求是肯定可以被完成的——即使不是在現在,在稍后時間服務恢復正常時就可以完成。而且,運用一個異步模式也可以給客戶端和服務器提供很多的靈活性,使它們可以控制消息的處理速度,例如,服務器可以從服務隊列取出消息,按自己的意愿隨時處理它們。

    在客戶端和AsynchBabelFish服務之間可能交換了三個文檔:從客戶端發送到服務的轉換請求文檔、從服務發送回客戶端的轉換結果文檔、以及如果請求出了問題或如果轉換請求由于某種原因不能完成,發送回客戶端的一個替代結果文檔的SOAP fault envelope。

    要對AsynchBabelFish服務提出一個請求,客戶端需要將轉換請求文檔創建成一個字符串,并將它作為一個TextMessage列在AsynchBabelFish服務請求隊列中。Envelope采用的形式見列表1

    轉換請求envelope的body部分包含SourceText元素,它帶有用戶想要轉換的文本。Xml:lang屬性為文本語言指定了編碼,traslateTo屬性為用戶想將文本轉換到的語言指定了編碼。所支持的語言包括English(en)、German(de)、French(fr)、Italian(it)和Portuguese(pt)。對于源文(source text),有150個字的限制。

    注意SOAP header中運用的WS-Security header元素。AsynchBabelFish服務要求對XMethods用戶ID/密碼數據庫進行驗證,該元素用來提供請求者的身份憑證(credentials)。(關于WS-Security的更多信息,請參閱資源。)轉換結果envelope的body部分包含兩個子元素,SourceText和TranslationText。例如:
    <?xml version="1.0" encoding=
    	"UTF-8"?>
    <soap:Envelope xmlns:soap=
    	"http://schemas.xmlsoap.org/
    	soap/envelope/">
    	<soap:Body>
    		<SourceText xml:lang="en"
    			xmlns:xml=http://www.w3.org/
    			XML/1998/namespace
    			xmlns="http://xmethods.net/
    			babelfish">hello</SourceText>
    		<TranslationText xml:lang="fr" 
    			xmlns:xml=
    			"http://www.w3.org/XML/1998/
    			namespace"
    			xmlns="http://xmethods.net/
    				babelfish">bonjour
    		</TranslationText>
    	</soap:Body>
    </soap:Envelope>
    

    SourceText只是重復傳遞到請求的內容。TranslationText包含轉換的文本及其語言的xml:lang指示符。如果請求envelope有問題,從而不可能完成請求,就會返回一個標準的SOAP fault envelope來替代轉換結果文檔。下面的例子顯示的是SOAP fault envelope;如果請求消息帶有的TextMessage不是格式規范的XML,那么這個特殊的fault就會被發送回客戶端:
    <?xml version='1.0' encoding=
    	'UTF-8'?>
    <soap:Envelope xmlns:soap=
    	'http://schemas.xmlsoap.org/
    	soap/envelope/'>
    	<soap:Body>
    		<soap:Fault>
    			<faultcode>soap:Client
    			</faultcode>
    			<faultstring>Incoming text 
    				is not XML</faultstring>
    		</soap:Fault>
    	</soap:Body>
    </soap:Envelope>
    

    通過一個基于JMS的Web service(如AsynchBabelFish),客戶端和服務器就不是直接進行交互的了;取而代之的是,SOAP請求可以通過消息隊列在客戶端和服務器之間進行傳遞,而不受時間的影響(time-independent)。

    現在,讓我們看看一個消息是如何從客戶端傳遞到服務器的(見圖3)。客戶端創建一個轉換請求envelope,并將它放在該服務的請求隊列中。服務的所有客戶端都可以運用這個眾所周知的公用隊列,如同基于HTTP的服務運用固定的、眾所周知的HTTP端點URL一樣。客戶端也給請求消息提供了一個reply-to JMS header,它包含一個響應隊列的名字,從而讓服務知道將響應消息發送到哪里。AsynchBabelFish服務過程是否立即完成同該步驟(將請求放入隊列)是無關的。

    
				圖3.
    圖3. 請求消息的過程
    然后,服務從隊列得到請求。該步驟可以是在客戶端放置請求后立即實現的,也可以在稍后時間完成,取決于服務器什么時候做好準備接收請求。然后服務器處理請求。如果請求在某些方面是無效的——例如,它可能不是一個有效的請求文檔,或它可能用了不被支持或無效的語言編碼——那么它就會生成一個SOAP fault envelope,其中詳細說明出了什么問題。否則,服務就執行轉換并生成適當的結果文檔。如果在轉換過程中出現與請求本身的有效性無關的技術錯誤,那么請求就保留在隊列中,服務定期重試它們。最后,服務器就通過響應隊列給客戶端返回一個響應消息(見圖4)。

    嘗試
    服務將轉換結果文檔(或SOAP fault)放在JMS reply-to指定的響應隊列中。它包含JMS請求消息的ID,并設置相關的響應消息ID來匹配它,因此客戶端就可以根據其意愿進行相應的請求/響應操作了。然后,在需要的時候,客戶端就可以從響應隊列得到完成的轉換結果文檔了(或SOAP fault)。

    
				圖4.
    圖4. 處理響應消息的過程
    你自己可以嘗試調用AsynchBabelFish服務。(要訪問AsynchBabelFish的client package和相關的JMS client libraries,請參閱www.xml-mag.com上的在線資源。)這個包(package)包括客戶端源代碼、二進制代碼和它所依賴的第三方類庫(libraries)。要運用這個客戶端,你也需要創建一個XMethods帳號并請求你自己的響應隊列(XMethods給它的用戶提供了一個作為messagebox的響應隊列,它是對該服務以及未來引發的異步服務所做的SOAP響應)。客戶端下載包所包含的指南對這些步驟的每一步都提供了更詳細的說明。Client package中的源程序文件在表1中有簡要的說明。

    TranslatorRequestor可以讓你創建請求并將它發送到AsynchBabelFish請求隊列中(見列表2)。其運行如下所示:
    java asynchBabelFish.
    	TranslatorRequestor <username> 
    	<password> <text> <fromLanguage> 
    	<toLanguage> <responseQueue>
    

    讓我們來看看TranslatorRequestor的一些重點。首先,程序實例化一個到AsynchBabelFish服務隊列的JMS連接。然后實例化一個RequestEnvelope對象:
    RequestEnvelope requestEnv=
    	new RequestEnvelope(userID,
    	password,sourceText,
    	sourceLanguage,toLanguage);
    

    RequestEnvelope對象帶有你傳遞的參數并在內部構造一個SOAP envelope。然后,當你調用它的toString()方法時,它就會以字符串形式給你返回一個相應的轉換請求SOAP文檔。我們用這個字符串創建一個JMS TextMessage對象:
    TextMessage message=
    	queueSession.createTextMessage(
    	requestEnv.toString());
    

    將響應隊列的句柄(handle)添加到消息的JMS reply-to header:
     // Get a handle to the reply-to 
    // queue
    Queue replyToQueue=queueSession.
    	createQueue(replyToQueueName);
    
    // and add it to the reply-to 
    // field
    message.setJMSReplyTo(
    	replyToQueue);
    

    形成的結果消息就會在控制臺打印出來并發送到服務隊列。在這個例子中,你可以看到,被調用的TranslatorRequestor程序用了一個我們設置的測試帳號“joe”和一個測試響應隊列(testResponseQueue)(見圖5)。

    
				圖5.
    圖5. 請求轉換
    然后服務器處理消息,返回一個轉換結果文檔或一個SOAP fault。ReplyProcessor程序負責處理響應消息(見列表3)。在這個例子中,我們用了一個與請求程序不同的程序來處理響應消息,盡管這并不是必需的。ReplyProcessor的調用方式如下所示:
    java asynchBabelFish.
    	ReplyProcessor <username> 
    	<password> <responseQueue> 

    程序首先建立一個到命令行參數所指定的響應隊列的JMS連接。然后它將自己注冊為那個隊列的一個listener。在典型的JMS消息傳遞模式中,傳送的消息被反饋到ReplyProcessor 的onMessage()方法。

    得到有趣的信息
    對于進入響應隊列的每個新消息,onMessage()都從消息中讀取SOAP envelope(以一個TextMessage的形式),然后將來自TextMessage的字符串傳遞到ResponseEnvelope構造器中:
    ResponseEnvelope response=
    	new ResponseEnvelope( 
    	((TextMessage)message).
    	getText());
    

    ResponseEnvelope(見列表4)是個輔助類(helper class),它可以讓我們更容易地處理轉換結果文檔。它的構造器以字符串形式讀取SOAP XML,并實例化一個Apache SOAP Envelope對象,它用get()方法處理這個對象來提取有趣的參數(源文本、轉換文本等等)。它的toString()方法也可以讓你得到SOAP消息的源XML文檔。然后響應消息和SOAP文檔本身的相關ID(correlation ID)就被打印出來了:
    // The correlation ID matches the 
    // JMS Message ID of the original 
    // request message
    System.out.println("\nResponse: 
    	JMS Correlation ID = "+message.
    	getJMSCorrelationID()+"\n");
    
    // Print out the response SOAP 
    // envelope
    System.out.println(response);
    

    最后,從轉換結果文檔中打印出我們感興趣的四個參數:源文本、源語言、轉換文本和轉換語言:
     // And print out a summary of the 
    // translation.
    System.out.println("\""+response.
    	getSourceText()+"\" (
    	"+response.getSourceLanguage()
    	+") translates to \""+response.
    	getTranslationText()+"\"    (
    	"+response.
    	getTranslationLanguage()
    	+")\n\n");;
    

    如果傳送的消息的確產生了一個SOAP fault,而不是一個有效的轉換結果文檔,那么要實例化ResponseEnvelope就會拋出一個異常,會從SOAP fault中形成錯誤字符串,并打印出對那個異常的堆棧跟蹤(stack trace)(見列表5)。當程序對我們先前用TranslatorRequestor發送的請求的響應文檔進行處理時,你就可以看到程序的結果(見圖6)。

    
				圖6.
    圖6. 處理響應消息
    RPC機制限制了Web services的有效性。異步消息傳遞以及它同Web services整合的價值就在于,SOAP和更高級的Web services協議是獨立于傳輸機制(transport-neutral)的;對于分布式計算(distributed computing)來說,沒有通用的(one-size-fits-all)方法。JMS提供了可靠的異步傳輸,這種傳輸可以與其它受歡迎的SOAP堆棧一起(或隱藏在這些SOAP堆棧下)跨Internet實現。

    不管你選擇哪種SOAP客戶端類庫,你都需要考慮如何運用異步消息傳遞來在企業內部或跨企業實現有效的數據傳輸。AsynchBabelFish例子可能并不是你在日常工作中使用或實現的那種服務,但它的確說明了SOAP是如何同JMS整合在一起的。


    關于作者:
    David Chappel是Sonic Software的副總和主要技術傳播者。他也是Java Web Services (O’Reilly & Associates, 2002)、Professional ebXML Foundations (Wrox, 2001)和The Java Message Service (O’Reilly & Associates, 2000)的合著者。最近,他獲得了Java Pro雜志的“Java Community個人杰出貢獻獎”(請訪問www.sonicsoftware.com)。Tony Hong是Xmethods的合著者,是Web services目錄的出版商(請訪問www.xmethods.net)。Dave的聯系方式是chappell@sonicsoftware.com,Tony的聯系方式是thong@xmethods.net
    posted on 2005-08-22 09:19 笨笨 閱讀(2504) 評論(0)  編輯  收藏 所屬分類: ALLWeb Services
    主站蜘蛛池模板: 亚洲成在人天堂在线| 亚洲Av无码乱码在线znlu| 免费看黄的成人APP| 美女巨胸喷奶水视频www免费| 日韩插啊免费视频在线观看 | 亚洲 欧洲 自拍 另类 校园| 久久精品国产亚洲AV未满十八| 欧洲精品码一区二区三区免费看| 成人无码a级毛片免费| 亚洲乱码中文字幕久久孕妇黑人| 免费很黄很色裸乳在线观看| 在线亚洲午夜理论AV大片| 亚洲AV无码乱码在线观看代蜜桃| 阿v免费在线观看| 色片在线免费观看| 国产成人亚洲影院在线观看| 亚洲人成色4444在线观看| 丰满人妻一区二区三区免费视频| 无码日韩人妻av一区免费| 国产亚洲日韩在线三区| 999zyz**站免费毛片| 免费国产在线观看老王影院| 一级一级一级毛片免费毛片| 无码专区永久免费AV网站| 亚洲欧美成人av在线观看| 亚洲国产成人精品无码久久久久久综合 | 国产va免费观看| 日产乱码一卡二卡三免费| 亚洲欧洲另类春色校园小说| 最近国语视频在线观看免费播放 | 亚洲日韩国产精品乱| 鲁丝片一区二区三区免费| 亚洲乱码国产一区网址| 久久亚洲中文字幕无码| 免费精品人在线二线三线区别| 亚洲AV无码1区2区久久| 18禁止看的免费污网站 | 亚洲日本精品一区二区| 国产性生大片免费观看性| 亚洲精品国产电影午夜| 叮咚影视在线观看免费完整版|