• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            使用SAAJ 和JAXM的 SOAP客戶端及服務(wù) --- 轉(zhuǎn)自http://oss.org.cn/ossdocs/one_and_net/app7/12.1.htm

            本模塊講述了如何使用用于JavaTM 的帶附件的SOAP(SAAJ)和用于XML消息的Java TM API(JAXM)創(chuàng)建能夠發(fā)送和接收消息的客戶端,以及如何部署它們到Sun ONE Application Server上。本模塊包括以下幾節(jié):

            SOAP客戶端


            本節(jié)講述了SOAP客戶端可以采用的兩種消息模型以及開發(fā)和部署這類客戶端的過程。本節(jié)包括以下主題:

            SOAP客戶端消息模型

            可以使用以下兩種消息模型建立SOAP客戶端

            沒有消息提供者的客戶端

            不使用消息提供者的應(yīng)用程序只能交換同步消息。也就是說(shuō),扮演客戶端角色的應(yīng)用程序只能發(fā)送請(qǐng)求-響應(yīng)消息。這種類型的客戶端采用SAAJ API的SOAPConnection方法。下圖演示了在沒有消息提供者的情況下,同步消息如何在發(fā)送者和接收者之間交換。

            不使用消息提供者的SOAP消息


            不使用消息提供者的客戶端具有以下優(yōu)點(diǎn):

            • 可以采用J2SE平臺(tái)編寫應(yīng)用程序。
            • 不需要在servlet或J2EE容器中部署應(yīng)用程序。
            • 不需要配置消息提供者。

            不使用消息提供者的客戶端具有以下局限性:

            • 客戶端只能發(fā)送請(qǐng)求-響應(yīng)消息
            • 客戶端只能扮演客戶端角色

            使用消息提供者的客戶端

            如果想要獲得并且保存在任何時(shí)間發(fā)送給你的請(qǐng)求,你必須使用消息提供者。JAXM API提供了使用消息提供者發(fā)送和接收消息的框架。你需要在容器中運(yùn)行客戶端,容器提供了消息基礎(chǔ)結(jié)構(gòu)讓提供者使用。下圖演示了在使用消息提供者的情況 下,異步消息如何在發(fā)送者和接收者之間交換。

            使用消息提供者的SOAP消息


            使用消息提供者的客戶端具有以下優(yōu)點(diǎn):

            • 客戶端能夠扮演客戶端或者服務(wù)角色
            • 客戶端能夠切換消息傳遞給提供者
            • 在客戶端傳遞消息到最終接收者之前,它能夠發(fā)送消息到一個(gè)或多個(gè)目的地。這些中間的消息接收者被稱為actor,它們?cè)谙⒌腟OAPHeader對(duì)象中被指定。
            • 客戶端能夠利用任何提供者支持的SOAP消息協(xié)議和影響消息類型與可靠性的‘服務(wù)質(zhì)量’,以及消息傳遞服務(wù)的質(zhì)量。

            注意

            Sun ONE Application Server包含了一個(gè)示例JAXM提供者,它演示了如何使用提供者為發(fā)送客戶端激活“發(fā)后不理(fire and forget)”消息。請(qǐng)察看示例文檔獲取關(guān)于如何激活、部署和使用它的全面信息。示例應(yīng)用程序可以從以下位置得到:

            install_dir/samples/webservices/jaxm/jaxm-provider/

            Sun ONE Application Server的未來(lái)版本將會(huì)包括支持可靠SOAP消息和ebXML消息的JAXM提供者。


            SOAP消息

            本節(jié)向你介紹SOAP消息的結(jié)構(gòu)和組成部分、如何訪問它們、以及如何處理SOAP消息。本節(jié)講述以下主題:

            SOAP消息的組成部分

            SOAP消息是一個(gè)包括SOAPEnvelope、一個(gè)可選的SOAPHeader、以及SOAPBody的XML文件。SOAP消息頭包含了使消息在到達(dá)最終目的地之前,能夠被路由到一個(gè)或多個(gè)中間節(jié)點(diǎn)的信息。

              SOAP消息的組成部分

            這個(gè)圖展示了SOAP消息的結(jié)構(gòu)和組成部分。不同對(duì)象代表了SOAP消息的每一個(gè)部分。

            SOAPMessage對(duì)象包括:

            • 一個(gè)SOAPPart對(duì)象,其中包括
              • 一個(gè)SOAPEnvelope對(duì)象,其中包括
                • 一個(gè)空的SOAPHeader對(duì)象 – 可選,包括它是為了方便,因?yàn)榇蠖鄶?shù)消息都要用到它。
                • 一個(gè)空的SOAPBody對(duì)象 -可以容納消息的內(nèi)容,還能容納包含了狀態(tài)信息或者消息故障明細(xì)的錯(cuò)誤消息。
            • AttachmentPart可能容納普通文本或者圖像文件。

            SOAPEnvelope是代表消息的XML文件的根元素。它為消息如何處理、由誰(shuí)處理定義了框架。XML內(nèi)容從SOAPEnvelope開始。

            SOAPHeader是添加特性到SOAP消息的基本機(jī)制。它可以容納任意數(shù)目的擴(kuò)展了基礎(chǔ)協(xié)議 的子元素。例如,header子元素可能會(huì)定義認(rèn)證信息、事務(wù)信息、本地信息、等等。處理消息的軟件可以在沒有事先約定的情況下,使用這個(gè)機(jī)制定義誰(shuí)應(yīng)該 處理某個(gè)特性,以及該特性是強(qiáng)制的還是可選的。

            body是發(fā)給消息最終接收者的強(qiáng)制信息的容器。SOAP消息還可以容納一個(gè)附件,它不一定非得是XML文件。

            訪問消息的元素

            當(dāng)創(chuàng)建消息體或附件的時(shí)候,以及處理消息的時(shí)候,你需要訪問消息的組成部分。

            SOAPMessage對(duì)象含有一個(gè)SOAPPart對(duì)象。通過message對(duì)象可以得到它。

            SOAPPart soapPart = message.getSOAPPart();

            然后你可以利用SOAPPart獲得它所含有的SOAPEnvelope對(duì)象。

            SOAPEnvelope envelope = soapPart.getEnvelope();

            現(xiàn)在你可以利用envelope獲得它的空SOAPHeader和SOAPBody對(duì)象。

            SOAPHeader header = envelope.getHeader();

            SOAPBody body = envelope.getBody();

            SOAPBody對(duì)象最初是空的。

            命名空間

            XML命名空間是一種限定元素和屬性名稱的方法,目的是消除它們與同一文件中其他名稱之間產(chǎn)生的歧義。一個(gè)名確的XML命名空間聲明采用如下格式:

            <prefix:myElement

            xmlns:prefix ="URI">

            聲明定義prefix作為一個(gè)特定URI的別名。在myElement元素內(nèi),你可以對(duì)任何元素或?qū)傩允褂们熬Y,從而指定元素或?qū)傩詫儆赨RI指定的命名空間。下面的代碼是命名空間聲明的一個(gè)例子。

            <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

            該定義定義了SOAP_ENV作為命名空間http://schemas.xmlsoap.org/soap/envelope/

            的別名。

            定義了別名之后,可以使用它作為Envelope元素中任何屬性或元素的前綴。

            預(yù)定義的SOAP命名空間

            • SOAPEnvelope,SOAP消息的根元素,擁有下面的命名空間標(biāo)識(shí)http://schemas.xmlsoap.org/soap/envelope
            • SOAP serialization,定義SOAP序列化規(guī)則的URI,擁有下面的命名空間標(biāo)識(shí)"http://schemas.xmlsoap.org/soap/encoding".。

            當(dāng)使用SAAJ或JAXM構(gòu)造或者消費(fèi)消息的時(shí)候,你有責(zé)任保證正確設(shè)定或處理命名空間,并且丟棄含有錯(cuò)誤命名空間的消息。

            創(chuàng)建SOAP消息的時(shí)候使用命名空間

            當(dāng)創(chuàng)建SOAP消息的body或header元素的時(shí)候,你必須使用命名空間為元素指定一個(gè)完整的名稱。通過調(diào)用方法SOAPEnvelope.createName可以獲得一個(gè)名稱。

            調(diào)用該方法時(shí),可以傳遞一個(gè)本地名稱作為參數(shù),或者可以指定本地名稱、前綴、以及URI。例如,下面的命令行定義了一個(gè)名為bodyName的Name對(duì)象。

            Name bodyName = MyEnvelope.createName("TradePrice", "GetLTP", "http://foo.eztrade.com");

            這和下面的命名空間聲明作用相同。

            <GetLTP:TradePrice xmlns:GetLTP= "http://foo.eztrade.com">

            下面的代碼演示了如何創(chuàng)建一個(gè)名稱并把它和SOAPBody元素綁定。注意createName方法的使用和位置。

            SoapBody body = envelope.getBody();//get body from envelope

            Name bodyName = envelope.createName("TradePrice", "GetLTP", "http://foo.eztrade.com");

            SOAPBodyElement gltp = body.addBodyElement(bodyName);

            開發(fā)SOAP客戶端

            利用SAAJ,客戶端能夠以點(diǎn)對(duì)點(diǎn)的方式創(chuàng)建并且發(fā)送SOAP消息。JAXM為使用消息提供者的 XML消息定義了API。JAXM依賴用于 Java 的帶有附件的 SOAP API(SAAJ),它定義了在Java中操作帶有附件的SOAP消息模型的API。Sun ONE Application Server不包括它所支持的JAXM消息提供者。然而它的確包含了示例應(yīng)用程序,一個(gè)簡(jiǎn)單的JAXM提供者,演示了一個(gè)消息提供者如何處理來(lái)自客戶端的 異步SOAP消息。本節(jié)講述以下主題:

            SOAP消息是如何出現(xiàn)的?

            當(dāng)消息工廠生產(chǎn)的SOAP消息通過連接被發(fā)送到一個(gè)端點(diǎn)的時(shí)候,SOAP消息就出現(xiàn)了。本節(jié)講述以下主題:

            端點(diǎn)

            端點(diǎn)標(biāo)識(shí)消息的最終目的地。端點(diǎn)是由URLEndpoint類來(lái)定義的。如果不使用提供者,你可以構(gòu)造或者查找到一個(gè)消息端點(diǎn)。

            構(gòu)造端點(diǎn)

            你可以通過調(diào)用構(gòu)造函數(shù)或者在名稱服務(wù)中查找來(lái)初始化一個(gè)端點(diǎn)。

            以下代碼使用構(gòu)造函數(shù)創(chuàng)建一個(gè)URLEndpoint:

            myEndpoint = new URLEndpoint("http://host/myServlet")

            使用端點(diǎn)發(fā)送消息

            指定端點(diǎn)作為SOAPConnection.call方法的一個(gè)參數(shù),該方法是用來(lái)發(fā)送SOAP消息的。

            向多個(gè)端點(diǎn)發(fā)送消息

            管理對(duì)象是封裝了針對(duì)提供者的配置和命名信息的對(duì)象。如果使用管理對(duì)象定義端點(diǎn),需要注意的是:可以把該管理對(duì)象綁定到多個(gè)URL——每個(gè)URL都能夠處理到達(dá)的SOAP消息。

            以下代碼示例把lookup名稱為myEndpoint的端點(diǎn)綁定到兩個(gè)URL:http://www.myServlet1/

            和 http://www.myServlet2/。這個(gè)語(yǔ)法允許你使用SOAP連接發(fā)布SOAP消息到多個(gè)端點(diǎn)。

            imqobjmgr add
               -t e
               -l "cn=myEndpoint"
               -o "imqSOAPEndpointList=http://www.myServlet1/
                  http://www.myServlet2/"

            連接

            想要利用SAAJ或JAXM發(fā)送SOAP消息,必須分別獲得一個(gè)SOAPConnection 或ProviderConnection。你還可以使用消息隊(duì)列傳輸消息;更多信息請(qǐng)參見Sun ONE消息隊(duì)列開發(fā)人員指南。

            SOAP 連接

            SOAPConnection允許你直接向遠(yuǎn)程伙伴發(fā)送消息。通過調(diào)用靜態(tài)方法SOAPConnectionFactory.newInstance(),可以容易地得到SOAPConnection對(duì)象。這種類型的連接既不保證可靠性也不保證安全性。

            提供者連接

            從ProviderConnectionFactory 獲得的ProviderConnection可以創(chuàng)建到特定消息提供者的連接。當(dāng)使用提供者發(fā)送SOAP消息的時(shí)候,消息被傳遞給提供者,然后提供者負(fù)責(zé) 傳遞消息到它的最終目的地,這樣保證了可靠并且安全的消息傳輸。

            創(chuàng)建SOAP客戶端

            創(chuàng)建SOAP客戶端之前,確定你已經(jīng)設(shè)置了客戶端環(huán)境。關(guān)于設(shè)置客戶端環(huán)境的更多信息,請(qǐng)參見

            如果創(chuàng)建一個(gè)點(diǎn)對(duì)點(diǎn)客戶端,你必須導(dǎo)入SAAJ API的javax.xml.soap程序包。如果創(chuàng)建一個(gè)pub/sub客戶端,需要導(dǎo)入import JAXM API的javax.xml.messaging程序包。除此之外,你還必須導(dǎo)入以下程序包:

            import java.net.*;
            import java.io.*;
            import java.util.*;

            import javax.servlet.http.*;
            import javax.servlet.*;

            import javax.activation.*;
            import javax.naming.*;

            創(chuàng)建SOAP客戶端并訪問消息包括以下步驟:

            獲得連接

            單獨(dú)客戶端

            不使用消息提供者的客戶端使用SOAPConnection對(duì)象創(chuàng)建連接。使用SoapConnection對(duì)象發(fā)送的消息直接從發(fā)送者到發(fā)送者指定的URL。

            必須獲得一個(gè)SOAPConnectionFactory對(duì)象來(lái)創(chuàng)建連接。SAAJ API通過提供SOAPConnectionFactory類的一個(gè)默認(rèn)實(shí)現(xiàn)簡(jiǎn)化了這一過程。以下代碼演示了如何獲得該實(shí)現(xiàn)的一個(gè)實(shí)例:

            SOAPConnectionFactory scf = SOAPConnectionFactory. newInstance();

            現(xiàn)在,你可以使用scFactory創(chuàng)建SOAPConnection對(duì)象

            SOAPConnection con = scf.createConnection();

            創(chuàng)建消息

            使用MessageFactory對(duì)象來(lái)創(chuàng)建消息。如果想要?jiǎng)?chuàng)建一個(gè)單獨(dú)客戶端,也就是既不使用消息提供者也不在容器中運(yùn)行的客戶端,你可以使用SAAJ API提供的MessageFactory類的實(shí)現(xiàn)。以下代碼演示了如何獲得默認(rèn)消息工廠的一個(gè)實(shí)例,然后用它創(chuàng)建消息:

            MessageFactory mf = MessageFactory.newInstance();

            SOAPMessage msg = mf.createMessage();

            消息創(chuàng)建過程會(huì)完成SOAPPart的創(chuàng)建,它是SOAP 1.1規(guī)范中每個(gè)消息的必要部分。

            SOAPPart sp = msg.getSOAPPart();


            注意:

            通常,使用默認(rèn)的消息工廠創(chuàng)建消息。但是,你也可以編寫自己的消息工廠實(shí)現(xiàn),并且把它插入到系統(tǒng)屬性中,如下所示:

            • 通過擴(kuò)展javax.xml.soap.MessageFactory實(shí)現(xiàn)消息工廠類。 javax.xml.soap是在SAAJ API中定義的程序包。
            • 通過設(shè)定系統(tǒng)屬性javax.xml.soap.MessageFactory為消息工廠實(shí)現(xiàn)類mypackage.MySOAPMessageFactoryImpl的完全路徑名,指定希望被實(shí)例化的消息工廠類。

            關(guān)于SOAP消息結(jié)構(gòu)和組成部分的信息,請(qǐng)參見

            Header添加內(nèi)容

            創(chuàng)建一個(gè)SOAPHeaderElement對(duì)象,從而可以添加內(nèi)容到header中。以下代碼演示了如何使用SOAPEnvelope對(duì)象創(chuàng)建一個(gè)SOAPHeaderElement。

            SOAPHeader hdr = envelope.getHeader();

            Name headerName = envelope.createName("Purchase Order","PO", "http://www.sonata.com/order");

            SOAPHeaderElement headerElement = hdr.addHeaderElement(headerName);

            HeaderElement通過Name對(duì)象headerName進(jìn)行標(biāo)識(shí)。AddHeaderElement方法是用來(lái)添加或者創(chuàng)建header元素的。

            為了添加內(nèi)容到headerElement,請(qǐng)象以下代碼示例那樣使用addTextNode方法。

            headerElement.addTextNode("order");

            SOAPHeader對(duì)象包含一個(gè)內(nèi)容為"order"的SOAPHeaderElement對(duì)象。

            向消息添加內(nèi)容

            你可以向SOAPPart對(duì)象,或者一或多個(gè)AttachmentPart對(duì)象添加內(nèi)容,或者可以向消息的這兩個(gè)部分都添加內(nèi)容。

            為了向消息體添加內(nèi)容,請(qǐng)創(chuàng)建一個(gè)SOAPBodyElement對(duì)象并添加一個(gè)使用SOAPElement.addTextNode方法建立的XML元素。下面的代碼演示了如何添加內(nèi)容到消息:

            SOAPEnvelope envelope = sp.getSOAPEnvelope();

            SOAPBody bdy = envelope.getSOAPBody();

            SOAPBodyElement gltp = bdy.addBodyElement(envelope.createName("GetLastTradePrice", "ztrade", "http://wombat.ztrade.com"));

            gltp.addChildElement(envelope.createName("symbol","ztrade", "http://wombat.ztrade.com")).addTextNode("SUNW");;

            代碼的前三行訪問了SOAPBody對(duì)象body,目的是創(chuàng)建一個(gè)新 SOAPBodyElement對(duì)象并把它添加到body上。CreateName方法需要Name對(duì)象作為參數(shù),用來(lái)指定被添加的 SOAPBodyElement。最后一行添加傳遞給addTextNode方法的XML字符串。

            向消息添加一個(gè)附件

            向消息添加附件的過程對(duì)于使用或不使用消息提供者的客戶端來(lái)說(shuō)都是一樣的。使用AttachmentPart對(duì)象向消息中添加附件部分。

            使用SOAPMessage對(duì)象創(chuàng)建AttachmentPart對(duì)象。SOAPMessage 類含有三個(gè)創(chuàng)建附件的方法。第一個(gè)方法允許你創(chuàng)建一個(gè)沒有內(nèi)容的AttachmentPart。就是說(shuō),以后再使用AttachmentPart的方法 setContent來(lái)添加內(nèi)容到附件。

            URL url = new URL(data);

            AttachmentPart ap = msg.createAttachmentPart(new DataHandler(url));

            SetContent有兩個(gè)參數(shù),對(duì)應(yīng)內(nèi)容的Java對(duì)象以及標(biāo)識(shí)內(nèi)容類型的String對(duì)象。 內(nèi)容是消息的SOAPBody部分,消息有一個(gè)值為"text/xml"的內(nèi)容-類型(Content-Type)header,這是因?yàn)閮?nèi)容只能是 XML格式。在AttachmentPart中,內(nèi)容的類型只能被指定為該對(duì)象能夠容納的任意類型。

            每個(gè)AttachmentPart都有一個(gè)或多個(gè)與之相關(guān)的header。setContent 方法中用到的類型就是Content-Type這個(gè)header類型。這是唯一必須具備的header。你還可以設(shè)置其他可選的header,例如 Content-Id和Content-Location。為了方便,JAXM和SAAJ API為Content-type、 Content-Id、和Content-Location這幾個(gè)header提供了get和set方法。這些header在消息擁有多個(gè)附件的時(shí)候,可 以幫助對(duì)附件的訪問。

            以下代碼演示了如何使用setContent方法:

            String stringContent = "Update address for Sunny Skies " + "Inc., to 10 Upbeat Street, Pleasant Grove, CA 95439";

            ap.setContent(stringContent, "text/html");
            ap.setContentId("update_address");
            msg.addAttachmentPart(ap);

            如果你還想附加一個(gè)jpeg圖像,setContent方法的第二個(gè)參數(shù)必須被設(shè)為"image/jpeg"。下面的代碼演示了如何使用setContent方法附加圖片:

            AttachmentPart ap2 = msg.createAttachmentPart();

            byte[] jpegData = . . .;

            ByteArrayInputStream stream = new ByteArrayInputStream(jpegData);

            ap2.setContent(stream, "image/jpeg");

            msg.addAttachmentPart(ap2);

            AttachmentPart的另外兩個(gè)方法允許你創(chuàng)建帶內(nèi)容的AttachmentPart對(duì) 象。其中一個(gè)與AttachmentPart.setContent方法很象。它需要一個(gè)包含內(nèi)容的Java對(duì)象和一個(gè)指定內(nèi)容類型的String作為參 數(shù)。對(duì)象可以是String、stream、 javax.xml.transform.Source對(duì)象、或  javax.activation.DataHandler對(duì)象。

            另一個(gè)創(chuàng)建帶內(nèi)容的AttachmentPart對(duì)象的方法需要一個(gè)DataHandler對(duì)象作為輸入?yún)?shù),它是JavaBeans激活框架(JAF)的一部分

            以下代碼演示了如何在內(nèi)容中使用DataHandler。首先為想要作為內(nèi)容添加的文件創(chuàng)建一個(gè)java.net.URL對(duì)象。創(chuàng)建DataHandler對(duì)象,即javax.activation.DataHandler 對(duì)象dh,使用URL對(duì)象對(duì)其進(jìn)行初始化,然后把dh傳遞給createAttachmentPart方法。

            URL url = new URL("http://greatproducts.com/gizmos/img.jpg");
            DataHandler dh = new DataHandler(url);
            AttachmentPart ap = msg.createAttachmentPart(dh);
            ap.setContentId("gyro_image")
            msg.addAttachmentPart(ap);

            發(fā)送消息

            單獨(dú)客戶端

            為了發(fā)送消息,單獨(dú)客戶端使用SOAPConnection的call方法。該方法需要兩個(gè)輸入?yún)?shù),要發(fā)送的消息和消息的目的地,目的地是一個(gè)包含接收者URL的Endpoint對(duì)象。

            利用SoapConnection的情況下,使用javax.xml.soap.SOAPConnection.call()發(fā)送消息。

            例如:

            URL urlEndpoint = new URL(to);

            SOAPMessage reply = con.call(msg, urlEndpoint);

            從響應(yīng)消息中檢索內(nèi)容

            客戶端使用onMessage方法檢索消息內(nèi)容。客戶端通過消息得到envelope,再通過 envelope得到body,從而訪問SOAPBody對(duì)象。訪問SOAPBody對(duì)象是因?yàn)閮?nèi)容存放在該元素中。為了檢索由 Node.addTextNode方法添加的內(nèi)容,請(qǐng)調(diào)用Node.getValue方法。GetValue返回調(diào)用元素的直接子元素的值。為了訪問 bodyElement,需要在body上調(diào)用getChildElement方法。以下代碼演示了如何從響應(yīng)消息中檢索內(nèi)容。

            public SOAPMessage onMessage(SOAPMessage message)

            {

            SOAPEnvelop env = msg.getSOAPPart().getEnvelope();

            env getBody()
               .addChildElement(env.createName("Response"))
               .addTextNode("This is a Response");

            return msg;

            }

            想要從含有附件的消息中檢索內(nèi)容,你需要訪問附件。沒有參數(shù)的情況 下,SOAPMessage.getAttachments方法返回指向所有AttachmentPart對(duì)象的java.util.Iterator對(duì) 象。以下代碼打印出了SOAPMessage對(duì)象消息中每一個(gè)AttachmentPart對(duì)象的內(nèi)容。

            java.util.Iterator it = message.getAttachments();

            while (it.hasNext()) {

            AttachmentPart attachment = (AttachmentPart)it.next();
            Object content = attachment.getContent();
            String id = attachment.getContentId();
            System.out.print("Attachment " + id + " contains: " + content);
            System.out.println("");

            }

            訪問消息的附件部分

            當(dāng)收到帶有附件的消息或是希望改變消息附件的時(shí)候,都需要訪問消息的附件。沒有附加信息的 SOAPMesssage.getAttachments方法返回指向消息中所有AttachmentPart對(duì)象的 java.util.Iterator對(duì)象。以下代碼演示了如何訪問附件從而獲得SOAPMessage對(duì)象消息中每個(gè)AttachmentPart對(duì)象 的內(nèi)容。

            java.util.Iterator it = msg.getAttachments();

            while (it.hasNext()) {

            AttachmentPart ap = it.next();
            Object content = ap.getContent();
            String id = ap.getContentId();
            System.out.print("Attachment " + id + " contains: " + content);
            System.out.println("");

            }

            組裝并部署SOAP客戶端

            利用JAXM API和SAAJ API創(chuàng)建的應(yīng)用程序被組裝為web應(yīng)用(WAR)或者基于J2EE平臺(tái)的應(yīng)用(EAR)。關(guān)于組裝和部署web應(yīng)用,請(qǐng)參見Sun ONE Application Server開發(fā)人員web應(yīng)用指南。

            SOAP 服務(wù)


            本節(jié)講述如何編寫SOAP服務(wù)以及如何在SOAP消息中處理異常和錯(cuò)誤。本節(jié)講述以下主題:

            創(chuàng)建SOAP服務(wù)

            SOAP服務(wù)是SOAP消息的最終接收者,并且被實(shí)現(xiàn)為servlet。要么創(chuàng)建你自己的servlet,要么擴(kuò)展javax.xml.messaging包中的JAXMServlet類。本節(jié)講述了基于JAXMServlet類創(chuàng)建SOAP服務(wù)的過程。

            為了創(chuàng)建SOAP服務(wù),你的servlet必須實(shí)現(xiàn)ReqRespListener或者OneWayListener接口。ReqRespListener需要返回一個(gè)回應(yīng)。

            public class MyServlet extends JAXMServlet implements ReqRespListener{

            ...

            ...

            }

            public SOAPMessage onMessage(SOAP Message msg)

            使用任意借口,實(shí)現(xiàn)一個(gè)叫做onMessage(SOAPMsg)的方法。

            以下代碼是使用JAXMServlet 的SOAP消費(fèi)者的完整清單:

            public class MyServlet extends JAXMServlet implements ReqRespListener {

               public SOAPMessage onMessage(SOAP Message msg) {

               //Process message here

               }
            }

            JAXMServlet在使用HTTP POST方法接受消息之后會(huì)調(diào)用onMessage。你就省去了實(shí)現(xiàn)自己的doPost()方法把收到的消息轉(zhuǎn)換成為SOAP消息的麻煩。

            OnMessage方法需要分解由servlet傳入的SOAP消息并處理它的內(nèi)容。處理消息包括訪問SOAP消息的組成部分。如果在處理消息過程中出現(xiàn)故障,服務(wù)需要?jiǎng)?chuàng)建SOAP fault對(duì)象并把它發(fā)回到客戶端。關(guān)于處理錯(cuò)誤的更多信息,請(qǐng)參見

            以下代碼演示了SOAP消息的處理:

            {http://xml.coverpages.org/dom.html

            SOAPEnvelope env = reply.getSOAPPart().getEnvelope();

            SOAPBody sb = env.getBody();

            // create Name object for XElement that we are searching for Name ElName = env.createName("XElement");

            //Get child elements with the name XElement
            Iterator it = sb.getChildElements( ElName );

            //Get the first matched child element.
            //We know there is only one.
            SOAPBodyElement sbe = (SOAPBodyElement) it.next();

            //Get the value for XElement
            MyValue = sbe.getValue(); }

            異常和錯(cuò)誤處理

            On the client's side, JAXM and SAAJ uses a SOAP exception to handle errors that occur during the generation of the SOAP request or unmarshalling of the response. This section describes the following topics:

            在客戶端,JAXM和SAAJ使用SOAP異常來(lái)處理SOAP 請(qǐng)求生成過程中,或者響應(yīng)反編組過程中發(fā)生的錯(cuò)誤。本節(jié)講述以下主題:

            錯(cuò)誤處理

            服務(wù)器端代碼必須使用SOAPFault對(duì)象處理在反編組請(qǐng)求、處理消息、或是編組響應(yīng)過程中發(fā)生的錯(cuò)誤。SOAPFault接口擴(kuò)展了SOAPBodyElement接口。

            在服務(wù)器端,SOAP消息擁有用來(lái)形成錯(cuò)誤報(bào)告的特定元素和格式:SOAP消息的body可以包 含一個(gè)SOAPFault元素來(lái)報(bào)告發(fā)生在請(qǐng)求處理過程中的錯(cuò)誤。在服務(wù)器端創(chuàng)建并且從服務(wù)器發(fā)回到客戶端的SOAP消息包含了SOAPFault對(duì)象, 它報(bào)告了消息生成者沒有預(yù)期到的任何行為。

            SOAPFault元素定義了以下四個(gè)子元素

            faultcode

            標(biāo)識(shí)錯(cuò)誤的代碼。軟件使用該代碼為鑒別錯(cuò)誤提供一個(gè)算法機(jī)制。此元素是必需的。

            faultstring

            一個(gè)描述錯(cuò)誤代碼所標(biāo)識(shí)的錯(cuò)誤的字符串。該元素提供了為人們無(wú)法理解的錯(cuò)誤提供了一個(gè)解釋。此元素是必需的。

            faultactor

            指定錯(cuò)誤來(lái)源的URI:誰(shuí)引起了錯(cuò)誤。如果消息沒有通過任何中間站直接發(fā)送給它的最終目的地,該元素不是必需的。如果在中間站發(fā)生了錯(cuò)誤,這個(gè)錯(cuò)誤必須包含一個(gè)faultactor元素。

            detail

            該元素持有與body元素相關(guān)的特定信息。如果body元素的內(nèi)容不能夠被成功處理,它就必須被給出。因此,如果這個(gè)元素丟失了,客戶端應(yīng)該推斷出body元素已經(jīng)被處理了。除了畸形負(fù)載,這個(gè)元素對(duì)任何錯(cuò)誤都不是必須的,你可以在其他情況下用它來(lái)為客戶端提供附加信息。

            預(yù)定義的錯(cuò)誤代碼

            SOAP規(guī)范列出了以下四個(gè)預(yù)定義的faultcode值:

            VersionMismatch

            處理方發(fā)現(xiàn)SOAP envelope元素有一個(gè)不合法的命名空間;也就是說(shuō),SOAPEnvelope元素的命名空間不是http://schemas.xmlsoap.org/soap/envelope/.

            MustUnderstand

            SOAPHeader元素的一個(gè)直接子元素要么無(wú)法理解,要么接收者不能正確處理。這個(gè)元素的MustUnderstand屬性設(shè)被為1(true)。

            Client

            消息格式不正確或者沒包含合適的信息。例如,消息沒有包含正確的認(rèn)證或付款信息。客戶端應(yīng)該翻譯這個(gè)代碼從而指定這個(gè)消息在重新發(fā)送之間必須被修改。如果這是一個(gè)返回代碼,SOAPFault對(duì)象應(yīng)該包括一個(gè)detailEntry對(duì)象,它為格式錯(cuò)誤的消息提供附加信息。

            Server

            該消息由于一些與它的內(nèi)容沒有聯(lián)系的原因而不能被處理。例如,消息的一個(gè)處理者無(wú)法與另一個(gè)上游的、沒有相應(yīng)的消息處理者進(jìn)行通信。或者,服務(wù)器需要訪問的數(shù)據(jù)庫(kù)崩潰了。客戶端應(yīng)該解釋這個(gè)錯(cuò)誤,以指出事務(wù)可以在以后的某個(gè)及時(shí)時(shí)間點(diǎn)成功。

            定義SOAP錯(cuò)誤

            可以使用SOAPFault對(duì)象的方法為faultcode、 faultstring、和faultctor指定值。以下代碼演示了SOAPFault對(duì)象的創(chuàng)建和faultcode、 faultstring、faultctor屬性的設(shè)定。

            SOAPFault fault;

            reply = factory.createMessage();

            envp = reply.getSOAPPart().getEnvelope(true);

            someBody = envp.getBody();

            fault = someBody.addFault():

            fault.setFaultCode("Server");

            fault.setFaultString("Some Server Error");

            fault.setFaultActor("http://xxx.me.com/list/endpoint.esp/");

            reply.saveChanges();

            一旦發(fā)生服務(wù)器錯(cuò)誤,服務(wù)器能夠在對(duì)收到的SOAP消息做出的回應(yīng)中,返回這個(gè)對(duì)象。

            以下代碼演示了如何定義一個(gè)detail和detail entry對(duì)象。注意,必須為detail entry對(duì)象創(chuàng)建一個(gè)名稱。

            SOAPFault fault = someBody.addFault();

            fault.setFaultCode("Server");

            fault.setFaultActor("http://foo.com/uri");

            fault.setFaultString ("Unkown error");

            DetailEntry entry = detail.addEntry(envelope.createName("125detail", "m", "Someuri");

            entry.addTextNode("the message cannot contain the string //");

            reply.saveChanges();

            組裝并部署SOAP服務(wù)

            使用JAXM API和SAAJ API創(chuàng)建的應(yīng)用被組裝為web應(yīng)用(WAR)或者基于J2EE平臺(tái)的應(yīng)用(EAR)。關(guān)于組裝和部署web應(yīng)用,請(qǐng)參見Sun ONE Application Server開發(fā)人員web應(yīng)用指南。

            客戶端和服務(wù)示例

            客戶端和服務(wù)應(yīng)用程序示例被捆綁在Sun ONE Application Server中。這些例子示范如何創(chuàng)建發(fā)送和接收XML消息的服務(wù)和客戶端。你可以在下面的位置找到這些例子:

            install_dir/samples/webservices/jaxm

            install_dir/imq/demo/jaxm

            使用SAAJ 和JAXM的 SOAP客戶端及服務(wù)

            816-7869-10

            posted on 2012-06-22 16:10 大龍 閱讀(1199) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久人人爽人人爽人人爽| 久久久久久夜精品精品免费啦| 国产精品一区二区久久精品| 亚洲国产香蕉人人爽成AV片久久| 久久久精品波多野结衣| 91精品国产91久久久久福利| 性高湖久久久久久久久| 久久精品成人国产午夜| 久久精品国产亚洲av高清漫画| 99精品久久精品一区二区| 一本色道久久综合狠狠躁| 99久久99久久精品免费看蜜桃| 99久久精品免费| 国产午夜精品理论片久久| 狠狠色丁香婷综合久久| 91精品国产91久久综合| 91麻豆精品国产91久久久久久 | 久久精品国产只有精品66 | 国产精品无码久久综合| 久久精品国产99国产精品亚洲| 99久久人妻无码精品系列蜜桃| 国产亚洲色婷婷久久99精品91| 久久久久久久精品妇女99| 久久精品国产亚洲av麻豆图片 | 美女久久久久久| 日本WV一本一道久久香蕉| 欧美一区二区三区久久综| 国产精品久久精品| 久久久久久毛片免费看| 国产美女久久精品香蕉69| 欧美激情精品久久久久| 亚洲精品无码久久一线| 国产Av激情久久无码天堂| 精品免费久久久久国产一区| 久久国产精品无码网站| 国产偷久久久精品专区| 狠狠88综合久久久久综合网| 久久国产精品国语对白| 亚洲色欲久久久综合网东京热 | 精品久久久久久无码不卡| 久久精品国产亚洲AV麻豆网站|