国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

使用SAAJ1.2發送和接收二進制Web服務內容(二)

2019-11-18 16:24:24
字體:
來源:轉載
供稿:網友
帶有附件的soap分析
    帶有附件的SOAP信息并沒有給SOAP增加新的特征。 確切的說,它定義了如何利用在SOAP信息中MIME類型來定義附件, 并且還定義了如何引用在SOAP體(SOAP Body)中的那些附件。
    MIME類型的復合塊/關聯(multipart/related)特性能定義由多部分組成的一個文檔。帶有附件的SOAP信息一定要符合這樣的復合塊/關聯(multipart/related)的MIME類型。下面的例子展示了一個復合塊/關聯的 SOAP 信息,它被綁定到到 HTTP 協議,帶有兩個附件:

POST /PRopertyListing HTTP/1.1
Host: www.realproperties.com
Content-Type: Multipart/Related; boundary=MIME_boundary; type=text/xml; start="<property1234@realhouses.com>"
Content-Length: NNNN

--MIME_boundary
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <property1234.xml@realhouses.com>

<?xml version='1.0'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>

    <realProperty:propertyListing id="property_432"
      xmlns:realProperty="http://schemas.realhouses.com/listingSubmission">

       <listingAgency>Really Nice Homes, Inc.</listingAgency>
      <listingType>Add</listingType>
      <propertyAddress>
        <street>1234 Main St</street>
        <city>Pleasantville</city>
        <state>CA</state>        
        <zip>94323</zip>
      </propertyAddress>
       <listPrice>
         250000
       </listPrice>

      <frontImage href="property1234_front.jpeg@realhouses.com"/>
       <interiorImage href="property1234_interior.jpeg@realhouses.com"/>

    </realProperty:propertyListing>

</SOAP-ENV: Body>
</SOAP-ENV: Envelope>

--MIME_boundary
Content-Type: image/jpeg
Content-ID:

....JPEG DATA .....
--MIME_boundary
Content-Type: image/jpeg
Content-ID:

....JPEG DATA .....
--MIME_boundary--

    上述的復合塊信息包含一系列的MIME頭和相關的數據。文件的底層是SOAP體(SOAP Body)。 因為SOAP體只包含XML數據,整個信息的MIME類型是本文/xml(text/xml)類型 。 在SOAP封套(SOAP envelope)后面是二個附件,每個附件都包含一個連同信息一起發送的圖像文件。
    用內容ID(Content ID)來識別每一個附件。W3C 備忘錄允許用內容ID或內容位置來引用附件,但是它優先選擇前者。這樣的一個內容ID作為統一資源標志符URI(Uniform Resource Identifier)引用給附件;SOAP 1.1的編碼規則定義了如何通過URI來引用SOAP信息里面的任何資源,不僅僅是引用XML( 參考SOAP1.1第5節資源)。當SOAP處理機處理信息時,它會解析這些URI引用。在上述的例子中,SOAP處理器把元素frontImage關聯到內容ID為property1234_front.jpeg@realhouses.com的數據段中。

創建并發送帶有附件的soap信息

    SAAJ能讓你創建并編輯SOAP信息的任何部份, 包括附件。 大多數的SAAJ以抽象類和接口為基礎,所以每個供應商都能實現它自己的SAAJ產品。Sun Microsystems公司的參考實現附在JWSDP包(java Web Services Developer Pack)中。
    因為SOAP信息只是XML文檔的一種特殊形式,JAAS在DOM(Document Object Model)API的基礎上處理XML。大多數的SOAP信息組件派生自 avax.xml.soap.Node接口, 而這個接口又是org.w3c.dom.Node的子類。SAAJ繼承了Node來添加SOAP樣式的結構。 舉例來說,這個特別的Node, SOAPElement,代表了一個SOAP信息元素。
    SAAJ依賴于接口和抽象類的直接結果是:你要通過工廠方法(factory methods)來完成大多數與SOAP相關的工作。 要把你的程序鏈接到SAAJ API,你首先要創建一個來自工廠方法SOAPConnectionFactory的鏈接SOAPConnection。要創建和編輯SOAP信息,你可以初始化MessageFactory和SOAPFactory。MessageFactory能讓你產生SOAP信息,而 SOAPFactory則提供方法產生SOAP信息的各個部份:

SOAPConnectionFactory spConFactory = SOAPConnectionFactory.newInstance();
SOAPConnection con = spConFactory.createConnection();
SOAPFactory soapFactory = SOAPFactory.newInstance();


    把這些工具用在適當的位置,你就可以創建一個 SOAP 信息,在前面的例子中,來自房產代理的客戶可以使用這些信息發送項目表更新給一個網站入口。
    SAAJ 提供了幾個方法來產生一個新的 SOAP 信息。 下面例子演示了用最簡單的方法來創建一個有封套(envelope)的空白SOAP信息,這個封套還帶有頭(heade)和體(body)。如果你在這個信息中不需要SOAP頭(SOAP header),那么你可以將這個元素從信息中刪除:

SOAPMessage message = factory.createMessage();
SOAPHeader header = message.getSOAPHeader();
header.detachNode();


    把 XML 結構加入信息也是直接了當的:

SOAPBody body = message.getSOAPBody();

Name listingElementName = soapFactory.createName(
    "propertyListing", "realProperty",
    "http://schemas.realhouses.com/listingSubmission");
SOAPBodyElement listingElement = body.addBodyElement(listingElementName);

Name attname = soapFactory.createName("id");
listingElement.addAttribute(attname, "property_1234");

SOAPElement listingAgency = listingElement.addChildElement("listingAgency");
listingAgency.addTextNode("Really Nice Homes, Inc");

SOAPElement listingType = listingElement.addChildElement("listingType");
listingType.addTextNode("add");

SOAPElement propertyAddress = listingElement.addChildElement("propertyAddress");
SOAPElement street = propertyAddress.addChildElement("street");
street.addTextNode("1234 Main St");
SOAPElement city = propertyAddress.addChildElement("city");
city.addTextNode("Pleasantville");
SOAPElement state = propertyAddress.addChildElement("state");
state.addTextNode("CA");
SOAPElement zip = propertyAddress.addChildElement("zip");
zip.addTextNode("94521");

SOAPElement listPrice = listingElement.addChildElement("listPrice");
listPrice.addTextNode("25000");


   注意,你要把屬性的ID作為一個參數加入到屬性列表元素(propertyListing)中。 更進一步的是,你要用QName, 或namespace來限定propertyListing元素。

   你可以用幾種方法把附件加入到SOAP信息中。 在這一個例子中,你首先要創建元素來指示列表屬性的背景圖片和前景圖片。它們每個都有一個href屬性指明附件的內容ID:

String frontImageID = "property1234_front_jpeg@realhouses.com";
SOAPElement frontImRef = listingElement.addChildElement("frontImage");
Name hrefAttName = soapFactory.createName("href");
frontImRef.addAttribute(hrefAttName, frontImageID);

String interiorID = "property1234_interior_jpeg@realhouses.com";
SOAPElement interiorImRef = listingElement.addChildElement("interiorImage");
interiorImRef.addAttribute(hrefAttName, interiorID);

    要方便地把需要的圖像文件附加在信息中,可以使用JavaBeans Activation Framework架構里面的javax.activation.DataHandler對象。DataHandler能自動地檢測傳遞給它的數據類型,而且它還能自動地分配適當的MIME類型給附件:

URL url = new URL("file:///eXPort/files/pic1.jpg");
DataHandler dataHandler = new DataHandler(url);
AttachmentPart att = message.createAttachmentPart(dataHandler);
att.setContentId(frontImageID);
message.addAttachmentPart(att);


    另一種方法,你可以把一個對象,連同正確的MIME類型一起,傳遞到createAttachmentPart()方法里。這個方法跟第一個方法類似。在內部,SAAJ將會尋找處理器DataContentHandler 來處理這個MIME類型。 如果它不能找一個合適的處理器,createAttachmentPart() 方法將會拋出一個IllegalArgumentException異常:

URL url2 = new URL("file:///export/files/pic2.jpg");
Image im  = Toolkit.getDefaultToolkit().createImage(url2);
AttachmentPart att2 = message.createAttachmentPart(im, "image/jpeg");
att2.setContentId(interiorID);
message.addAttachmentPart(att2);


    這個方法的缺點集中在:它依賴于AWT中示例UI(用戶界面user interface)相關的類。 在一些粗心的(服務器)設置中,這些庫并沒有被正確的設置。
    不管你選擇什么方法來產生附件,上述的代碼表示了在第一個列表里面的SOAP信息。 既然這只是一個簡單的XML信息,你可以用任何Web服務器能夠接收的方法來發送這個消息: 一個直接的HTTP連接,JMX(JAVA管理擴展Java Management Extensions),Javaspaces, SMTP(簡單郵件傳輸協議Simple Mail Transfer Protocol),等等。 SAAJ 提供了簡單的方法來通過HTTP協議發送和接收SOAP信息。你只需要指定要發送的信息和連接終端的URL即可:

URL end point =
    new URL("http://localhost:8080/saajtest/servlet/InvServlet");

SOAPMessage response = connection.call(message, end point);


    SOAP連接的call()方法是同步的; 它會掛起直到它接收到回應。 回應以SOAP信息的形式發送過來。

用saaj接收并處理soap 信息

    讀取和處理一個 SOAP 信息和創建一個這樣的信息相似。在這一個例子中, servlet監聽進入的SOAP信息,然后使用SAAJ來決定該如何處理它們。下面的代碼段演示了用另外一種方法來構造 SOAP信息: 通過傳遞一組MIME頭(MIME headers)和一個輸入流到SOAP信息工廠來構造信息。 因此,在創建一個SOAP信息之前,你一定要解析HTTP請求的MIME頭:

public void doPost(HttpServletRequest req, HttpServletResponse res) 
      throws ServletException, IOException {

      ...

MimeHeaders mimeHeaders = new MimeHeaders();

Enumeration en = req.getHeaderNames();
while (en.hasMoreElements()) {
    String headerName = (String)en.nextElement();
    String headerVal = req.getHeader(headerName);
    StringTokenizer tk = new StringTokenizer(headerVal, ",");
    while (tk.hasMoreTokens()){
        mimeHeaders.addHeader(headerName, tk.nextToken().trim());
    }
}

SOAPMessage message =
    messageFactory.createMessage(mimeHeaders, req.getInputStream());

    通過那個SOAP信息,servlet能處理流入的信息。 要取回并發送公司的名字,比如,你或許首先要獲得SOAP體的元素然后獲得公司名字相應的元素:

SOAPBody body = message.getSOAPBody();
Name listingElName = soapFactory.createName(
     "propertyListing", "realProperty",
     "http://schemas.realhouses.com/listingSubmission");
Iterator listings = body.getChildElements(listingElName);
while (listings.hasNext()) {

      // The listing and its ID
     SOAPElement listing = (SOAPElement)listings.next();
     String listingID = listing.getAttribute("id");

     // The listing agency name
     Iterator ageIt = listing.getChildElements(soapFactory.createName("listingAgency"));
     SOAPElement listingAgency = (SOAPElement)ageIt.next();
     String agencyName = listingAgency.getValue();

      ...
}

    每個附件相關的內容ID使得Servlet能夠從SOAP里取得需要的圖片。這一個例子中,已經做了廣告的屬性的前景圖片被保存在文件系統中。附件的MIME內容的類型決定了分配給保存文件的擴展名:

Iterator frontImage = listing.getChildElements(soapFactory.createName("frontImage"));
SOAPElement front = (SOAPElement)frontImage.next();
if (front != null) {
    String frontID = front.getAttribute("href");
    Iterator attachments = message.getAttachments();
    while (attachments.hasNext()) {
        AttachmentPart att = (AttachmentPart)attachments.next();
        if (att.getContentId().equals(frontID)) {
               String contentType = att.getContentType();
             String[] parts = contentType.split("/");
               String fileExt = "UNK";
               if (parts.length > 0) {
                 fileExt = parts[1];
             }
             InputStream is = att.getDataHandler().getInputStream();
             FileOutputStream os =
                 new FileOutputStream("/tmp/" + listingID+ "_front." + fileExt);
             byte[] buff = new byte[1024];
             int read = 0;
             while ((read = is.read(buff, 0, buff.length)) != -1) {
                 os.write(buff, 0, read);
             }
             os.flush();
             os.close();
        }
     }  
}

     一旦servlet取得圖像并且處理了SOAP信息的XML內容,它就通過HTTP請求輸出給客戶一個答復。由于客戶會在這個回應中尋找MIME頭的類型,你必須在HTTP輸出流中指定MIME頭的值:

SOAPMessage reply = messageFactory.createMessage();
SOAPHeader header = reply.getSOAPHeader();
header.detachNode();
SOAPBody replyBody = reply.getSOAPBody();
SOAPBodyElement bodyElement = replyBody.addBodyElement(
   soapFactory.createName("ack"));
bodyElement.addTextNode("OK");

res.setHeader("Content-Type", "text/xml");

OutputStream os = res.getOuputStream();
reply.writeTo(os);
os.flush();


    當客戶接收到確認信息的時候, 它能夠處理這個信息,這跟服務器處理客戶信息的方式是一樣的。

    對用這種信息交換的一個告誡: 客戶端和服務器端一定要知道每個信息的結構。 因為一個網絡服務提供者總是把他的信息定義在Web服務注冊表中,以Web服務描述語言(Web Services Description Language WSDL)文件的形式定義,所以客戶端的程序員能檢查服務的 WSDL 定義并且根據它構造信息。

在soap中發送二進制的附件? 沒有問題

    開發者時常感覺用SOAP完成基于XML的遠程過程調用過分的復雜。 在這一篇文章中,你已經看到能以簡單的方式使用SOAP發送、接收簡單的信息,并且這個SOAP信息不僅能包含XML內容,還能包含二進制內容。 由于支持創造和解析SOAP文件的工具的不斷增多, 在SOAP上構建的一個簡單的文件-交換Web服務是非常方便的。
    如這一篇文章所說的, SAAJ沒有把構造和解析SOAP信息綁定到任何特定的信息傳輸通道。這樣的無關性能讓你自由選擇最適合你程序的信息交換方式。比如,如果你需要容錯的信息傳輸,你可能經由JAXM,Java信息服務(JMS)或JavaSpaces來傳輸SOAP信息。另一方面,如果你不需要招惹麻煩的高可靠性設計,就可能選擇通過簡單的HTTP連接經發送SOAP信息。

冬臨 ,java 愛好者,Matrixxml soap翻譯小組成員 
進入討論組討論。

(出處:http://m.survivalescaperooms.com)



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 遂川县| 房产| 灯塔市| 毕节市| 化州市| 寿宁县| 临汾市| 米易县| 阜南县| 南开区| 大连市| 洪泽县| 永济市| 马边| 西乌珠穆沁旗| 清河县| 六盘水市| 察雅县| 石柱| 绥德县| 栖霞市| 塘沽区| 海林市| 高邮市| 毕节市| 楚雄市| 通辽市| 龙江县| 青州市| 穆棱市| 乐都县| 河源市| 遂溪县| 太仓市| 邹平县| 惠州市| 宜阳县| 景德镇市| 万山特区| 浪卡子县| 黔南|