用JAXM發(fā)送和接收SOAP消息
在本篇技巧文章中,作者兼開(kāi)發(fā)人員 Nicholas Chase 向您演示如何使用用于XML消息傳遞的 Java API(Java API for XML Messaging (JAXM))簡(jiǎn)化創(chuàng)建和發(fā)送 SOAP 消息的過(guò)程。Web 服務(wù)的基礎(chǔ)在于以標(biāo)準(zhǔn)格式發(fā)送和接收消息以便使所有系統(tǒng)都能理解。通常,那種格式是簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議(Simple Object Access Protocol (SOAP))。SOAP 消息可以手工生成和發(fā)送,但是用于 XML 消息傳遞的 Java API(JAXM)使許多必需步驟(如創(chuàng)建連接或創(chuàng)建并發(fā)送實(shí)際消息)自動(dòng)化。這篇技巧文章記錄了一個(gè)同步 SOAP 消息的創(chuàng)建和發(fā)送。
這個(gè)過(guò)程包括創(chuàng)建 SOAP 連接、創(chuàng)建 SOAP 消息、填充消息、發(fā)送消息、檢索應(yīng)答。
JAXM 可以作為 Java XML Pack(2002 年春季版)的一部分和 Java Web Services Developer Pack EA2(請(qǐng)參閱參考資料)的一部分而獲得。后者還包含了一份 Tomcat Web 服務(wù)器以及樣本應(yīng)用程序的副本。那些樣本 Web 服務(wù)之一作為本技巧文章中 SOAP 消息的目的地,這個(gè)例子中實(shí)際服務(wù)的內(nèi)容和功能卻不是很重要。
一個(gè)基本的SOAP消息由包含兩個(gè)主要部分(報(bào)頭和主體)的封套組成。應(yīng)用程序決定如何使用這些部分,但整個(gè)消息必須遵循特定的 XML 結(jié)構(gòu),例如:
|
在這個(gè)例子中,報(bào)頭為空,而主體包含目的地為一個(gè)日歷應(yīng)用程序的信息。
請(qǐng)注意這個(gè)消息的結(jié)構(gòu)。Envelope 包含 Header 和 Body 元素,而三者全都是 http://schemas.xmlsoap.org/soap/envelope/ 名稱空間的一部分。整個(gè)消息將通過(guò)一個(gè) SOAP 連接發(fā)送到一個(gè) Web 服務(wù)中。
第一步是創(chuàng)建整個(gè)類和連接:
創(chuàng)建連接
|
SOAP消息可以通過(guò)使用SOAPConnection直接發(fā)送,或使用消息傳遞提供程序間接發(fā)送。在這個(gè)例子中,應(yīng)用程序通過(guò)使用工廠(factory)創(chuàng)建 SOAPConnection 對(duì)象。
工廠也創(chuàng)建消息本身:
創(chuàng)建消息對(duì)象
|
首先,通過(guò)使用 MessageFactory 來(lái)創(chuàng)建消息本身。這個(gè)消息已包含如 envelope 和 header 等基本部分的空白版本。SOAPPart 包含 envelope,而 envelope 包含主體。同時(shí)創(chuàng)建所需對(duì)象(如 SOAPBody)的引用。
接著,填充 SOAPBody:
|
SOAP 消息的主體就象任何其它 XML 元素,您可以在其中添加子元素(如 schedule 元素)。通常,您可以使用 addChildElement(elementname),但是這里演示的 envelope.createName() 方法使用用于數(shù)據(jù)或有效負(fù)載的名稱空間聲明簡(jiǎn)化了元素的創(chuàng)建。的確,創(chuàng)建 schedule 元素從而創(chuàng)建了 bodyElement SOAPElement 對(duì)象。然后,bodyElement 對(duì)象可以給其自己的子元素 cal:newitem 添加其自己的文本節(jié)點(diǎn)。通過(guò)這種方式,您可以象構(gòu)建任何其它 XML 文檔一樣構(gòu)建 XML 結(jié)構(gòu)。
然而,使用 JAXM,您也有機(jī)會(huì)通過(guò)使用外部文件直接創(chuàng)建消息的 SOAPPart。例如,第一個(gè)清單中的 XML 結(jié)構(gòu)保存在文件 prepped.msg 中,而且可以調(diào)用它來(lái)替代手工構(gòu)建文檔。
|
結(jié)果就是準(zhǔn)備發(fā)送的 SOAP 消息。
發(fā)送消息
對(duì)于同步消息,發(fā)送 SOAP 消息和接收應(yīng)答是在單個(gè)步驟中發(fā)生的:
|
實(shí)際的消息是使用 call() 方法發(fā)送的,該方法把消息本身和目的地作為參數(shù),然后返回第二個(gè) SOAPMessage 作為應(yīng)答。目的地必須是一個(gè) Endpoint 對(duì)象,或者是這個(gè)例子中的 URLEndpoint。這個(gè)示例使用來(lái)自 JWSDP 的一個(gè)樣本 servlet,它只用于獲取響應(yīng)。
call() 方法一直處于阻塞狀態(tài),直到它接收到返回的 SOAPMessage 為止。
返回的 SOAPMessage — reply — 是 SOAP 消息,它與已發(fā)送的消息格式相同,因此可以象操作任何其它 XML 消息那樣操作它。SOAP 允許您通過(guò)使用 XSLT 直接轉(zhuǎn)換應(yīng)答:
|
象在任何 XSLT 應(yīng)用程序中那樣創(chuàng)建 Transformer 對(duì)象。在這個(gè)例子中,我們只希望輸出內(nèi)容,所以沒(méi)有用到樣式表。這里,內(nèi)容本身就是消息的整個(gè) SOAP 部分(與可能包含附件的 SOAP 消息本身不同)。您還可以在處理之前抽取封套和主體。這個(gè)例子中的結(jié)果只是 System.out,但它可以是通常用于轉(zhuǎn)換的任何選擇。照常進(jìn)行轉(zhuǎn)換。
雖然本示例中的端點(diǎn)是提供靜態(tài)響應(yīng)的 servlet,但是實(shí)際的響應(yīng)取決于服務(wù)的功能和請(qǐng)求的性質(zhì)。同時(shí),雖然本篇技巧文章演示了消息的同步發(fā)送和接收,但是通過(guò)使用 ProviderConnection 對(duì)象而不是 SOAPConnection,JAXM 允許使用消息傳遞提供程序進(jìn)行異步發(fā)送。該提供程序一直保存這個(gè)消息,直到成功發(fā)送消息為止。
JAXM 還允許使用 profile,這樣很容易創(chuàng)建諸如 SOAP-RP 或 ebXML 消息那樣的專門 SOAP 消息,而且還能使非 XML 附件能夠附加到 SOAP 消息中。
參考資料
請(qǐng)查看 W3C 中的各種與 Web 服務(wù)相關(guān)的建議書的情況。
JAXM 可以作為 Java XML Pack(2002 年春季版)的一部分和 Java Web Services Developer Pack EA2 的一部分而獲得。
IBM WebSphere Studio Application Developer 是用于構(gòu)建、測(cè)試和部署 Web 服務(wù)的易用的集成開(kāi)發(fā)環(huán)境。
要獲取完整的 Web 服務(wù)工具箱,請(qǐng)下載 IBM 的 Web Services Development Kit。
在 developerWorks 的 XML 和 Web 服務(wù)專區(qū)查找更多參考資料。
關(guān)于作者
Nicholas Chase 一直在參與如 Lucent Technologies、Sun Microsystems、Oracle 和 Tampa Bay Buccaneers 等公司的網(wǎng)站開(kāi)發(fā)。Nick 曾經(jīng)是一位高中物理教師、低級(jí)放射性廢物設(shè)備的管理員、在線科幻小說(shuō)雜志的編輯、多媒體工程師和 Oracle 講師。近來(lái),他是佛羅里達(dá)州克利爾沃特 Site Dynamics Interactive Communications 的首席技術(shù)官,而且是有關(guān) Web 開(kāi)發(fā)的三本書,包括 Java and XML From Scratch(Que)和即將出版的 Primer Plus XML Programming(Sams)的作者。他愿意傾聽(tīng)讀者的意見(jiàn),可以通過(guò) nicholas@nicholaschase.com 與他聯(lián)系。
posted on 2005-12-15 11:25 Victor 閱讀(546) 評(píng)論(0) 編輯 收藏 所屬分類: web services