耐心無(wú)止境 成功一瞬間

          BlogJava 聯(lián)系 聚合 管理
            31 Posts :: 5 Stories :: 25 Comments :: 0 Trackbacks
          本文描述了一個(gè)用Java編寫(xiě)的不使用專門(mén)SOAP庫(kù)的簡(jiǎn)單通用SOAP客戶機(jī)。該客戶機(jī)可以讓您用任何 XML 編輯器(或文本編輯器)創(chuàng)建自己的請(qǐng)求, 而不是在暗中為您創(chuàng)建 SOAP 請(qǐng)求 XML 文檔。 該客戶機(jī)向您顯示實(shí)際的 SOAP 響應(yīng) XML 文檔,而不是僅僅提供遠(yuǎn)程方法的返回值。 這個(gè)簡(jiǎn)短的 Java 程序精確顯示了什么是 SOAP:打開(kāi) HTTP 連接、發(fā)送適當(dāng) XML 以調(diào)用遠(yuǎn)程方法、接著讀取服務(wù)器返回的 XML 響應(yīng)。


          通用 Java SOAP 客戶機(jī)


          SOAP(簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議)是 IBM、Microsoft、DevelopMentor 和 UserLand Software 為在網(wǎng)絡(luò)上交換信息而開(kāi)發(fā)的一種已在發(fā)展的 W3C 標(biāo)準(zhǔn)。 隨著Web上可以公開(kāi)使用的SOAP服務(wù)器的不斷增加,SOAP幾乎對(duì)用任何語(yǔ)言編寫(xiě)的程序——即使是用流行的簡(jiǎn)單語(yǔ)言(如 Visual Basic、JavaScript 和 perl)編寫(xiě)的非常短小的程序——執(zhí)行著HTML對(duì)Web瀏覽器所做的事:它為這些程序提供一個(gè)簡(jiǎn)單的方法來(lái)利用萬(wàn)維網(wǎng)上不斷增加的可用信息源。

          與 HTML 類似,SOAP 提供一套標(biāo)記來(lái)表示在Web上使用HTTP傳輸協(xié)議(從 SOAP 1.1 以來(lái),SMTP 也可以)發(fā)送的不同信息塊的作用。但是,SOAP向您提供的能力遠(yuǎn)遠(yuǎn)強(qiáng)于HTML。使用SOAP,您的程序向 SOAP服務(wù)器發(fā)送“SOAP請(qǐng)求”(一個(gè)簡(jiǎn)短的XML文檔,描述在遠(yuǎn)程機(jī)器上要調(diào)用的方法和所有要傳遞給它的參數(shù))。SOAP服務(wù)器將嘗試用那些參數(shù)執(zhí)行該方法,并將SOAP響應(yīng)發(fā)回程序。響應(yīng)可以是執(zhí)行的結(jié)果,也可以是相應(yīng)的錯(cuò)誤消息。可以使用公共SOAP服務(wù)器為提出請(qǐng)求的客戶機(jī)提供股票價(jià)格、最新的貨幣兌換率、FedEx 包裹跟蹤信息、代數(shù)表達(dá)式的解決方案以及其它各類信息。

          在SOAP存在之前,嘗試使用這種信息的程序必須先捕獲Web頁(yè)面,然后“刮下”HTML,以查找適當(dāng)?shù)奈谋尽?對(duì)這些Web頁(yè)面進(jìn)行可視的重新設(shè)計(jì)(例如,將當(dāng)前股票價(jià)格放到表中第三列而不是第二列中)就可以使這些程序無(wú)用。SOAP規(guī)范以及它所攜帶的簡(jiǎn)要的SOAP請(qǐng)求和響應(yīng)模式為客戶機(jī)和服務(wù)器之間的聯(lián)絡(luò)提供了一個(gè)框架,該框架是那些強(qiáng)健得多的信息收集工具的基礎(chǔ)。

          有許多SOAP客戶機(jī)可用于大多數(shù)的流行編程語(yǔ)言;有關(guān)詳盡列表,請(qǐng)參閱 SOAP::Lite for Perl 主頁(yè)上的 SOAP Toolkits 部分(請(qǐng)參閱參考資料)。大多數(shù) SOAP 客戶機(jī)都提供類庫(kù)、COM 對(duì)象或從您自己程序調(diào)用的等同對(duì)象。通常,使用這些客戶機(jī)庫(kù)遵循以下模式:

          · 程序傳遞要調(diào)用的遠(yuǎn)程方法的名稱和所有必需參數(shù)。

          · 庫(kù)組裝 SOAP 請(qǐng)求的適當(dāng) XML 文檔以將這一信息打包。

          · 庫(kù)將這一 XML 文檔傳遞給 SOAP 端點(diǎn) URL 標(biāo)識(shí)的 SOAP 服務(wù)器,這與通過(guò)指定服務(wù)器的 URL 將瀏覽器指向 Web 服務(wù)器地址很類似。

          · SOAP 服務(wù)器嘗試執(zhí)行方法后,它組裝包含執(zhí)行結(jié)果的 SOAP 響應(yīng) XML 文檔,并將它發(fā)回 SOAP 客戶機(jī)。

          · 接收SOAP響應(yīng)時(shí),客戶機(jī)庫(kù)對(duì)XML進(jìn)行語(yǔ)法分析以獲得方法調(diào)用的結(jié)果,并將結(jié)果傳遞給使用庫(kù)的程序。


          SOAPClient4XG


          SOAP 的介紹(請(qǐng)參閱 developerWorks 上 Graham Glass 編寫(xiě)得極佳的“ Web 服務(wù)革命”專欄)總是討論用于 SOAP 請(qǐng)求和響應(yīng)的 XML 的結(jié)構(gòu),但是我接觸到的 SOAP 客戶機(jī)總是會(huì)暗中進(jìn)行 XML 組裝和語(yǔ)法分析,所以我從來(lái)不用知道。 作為使用 XML 的人員,我曾想自己執(zhí)行 XML 部分;我認(rèn)為如果 SOAP 這樣簡(jiǎn)單,那么我應(yīng)該能夠編寫(xiě)一個(gè)簡(jiǎn)單的 SOAP 客戶機(jī)來(lái)讀取 SOAP 請(qǐng)求的 XML 文檔、將它發(fā)送到命令行上指定的 SOAP 端點(diǎn) URL、讀回響應(yīng)文檔并輸出該響應(yīng)。這將使它成為一個(gè)真正的通用 SOAP 客戶機(jī),因?yàn)樗{(diào)用任何 SOAP 服務(wù)器上的任何方法。

          清單1中顯示的 SoapClient4XG(“SOAP Client for XML Geeks”)Java類執(zhí)行該任務(wù),而不使用早先提到的 SOAP Toolkits 頁(yè)面上列出的任何專用 Java SOAP 類(請(qǐng)參閱參考資料)。 檢查了必需的 SOAP 端點(diǎn) URL 和 SOAP XML 文檔文件名參數(shù)及可選的 SOAP 操作參數(shù)后,讀入文件,將它發(fā)送到 SOAP 服務(wù)器,讀回響應(yīng),然后將其輸出到標(biāo)準(zhǔn)出口。

          清單1

          Listing 1. The complete SOAP client
          /**
          * SOAPClient4XG. Read the SOAP envelope file passed as the second
          * parameter, pass it to the SOAP endpoint passed as the first parameter, and
          * print out the SOAP envelope passed as a response.  with help from Michael
          * Brennan 03/09/01
          *
          *
          * @author  Bob DuCharme
          * @version 1.1
          * @param   SOAPUrl      URL of SOAP Endpoint to send request.
          * @param   xmlFile2Send A file with an XML document of the request.  
          *
          * 5/23/01 revision: SOAPAction added
          */
          import java.io.*;
          import java.net.*;
          public class SOAPClient4XG {
              public static void main(String[] args) throws Exception {
                  if (args.length  < 2) {
                      System.err.println("Usage:  java SOAPClient4XG " +
                                         "http://soapURL soapEnvelopefile.xml" +
                                         " [SOAPAction]");
                                          System.err.println("SOAPAction is optional.");
                      System.exit(1);
                  }
                  String SOAPUrl      = args[0];
                  String xmlFile2Send = args[1];
                            String SOAPAction = "";
                  if (args.length  > 2)
                                          SOAPAction = args[2];
                  // Create the connection where we&#39;re going to send the file.
                  URL url = new URL(SOAPUrl);
                  URLConnection connection = url.openConnection();
                  HttpURLConnection httpConn = (HttpURLConnection) connection;
                  // Open the input file. After we copy it to a byte array, we can see
                  // how big it is so that we can set the HTTP Cotent-Length
                  // property. (See complete e-mail below for more on this.)
                  FileInputStream fin = new FileInputStream(xmlFile2Send);
                  ByteArrayOutputStream bout = new ByteArrayOutputStream();    
                  // Copy the SOAP file to the open connection.
                  copy(fin,bout);
                  fin.close();
                  byte[] b = bout.toByteArray();
                  // Set the appropriate HTTP parameters.
                  httpConn.setRequestProperty( "Content-Length",
                                               String.valueOf( b.length ) );
                  httpConn.setRequestProperty("Content-Type","text/xml; charset=utf-8");
                            httpConn.setRequestProperty("SOAPAction",SOAPAction);
                  httpConn.setRequestMethod( "POST" );
                  httpConn.setDoOutput(true);
                  httpConn.setDoInput(true);
                  // Everything&#39;s set up; send the XML that was read in to b.
                  OutputStream out = httpConn.getOutputStream();
                  out.write( b );    
                  out.close();
                  // Read the response and write it to standard out.
                  InputStreamReader isr =
                      new InputStreamReader(httpConn.getInputStream());
                  BufferedReader in = new BufferedReader(isr);
                  String inputLine;
                  while ((inputLine = in.readLine()) != null)
                      System.out.println(inputLine);
                  in.close();
              }
            // copy method from From E.R. Harold&#39;s book "Java I/O"
            public static void copy(InputStream in, OutputStream out)
             throws IOException {
              // do not allow other threads to read from the
              // input or write to the output while copying is
              // taking place
              synchronized (in) {
                synchronized (out) {
                  byte[] buffer = new byte[256];
                  while (true) {
                    int bytesRead = in.read(buffer);
                    if (bytesRead == -1) break;
                    out.write(buffer, 0, bytesRead);
                  }
                }
              }
            }
          }


          posted on 2005-10-28 13:26 Joshua Yan 閱讀(587) 評(píng)論(0)  編輯  收藏 所屬分類: JavaWeb
          主站蜘蛛池模板: 大足县| 嘉兴市| 田东县| 天全县| 青铜峡市| 汉沽区| 乐昌市| 通许县| 崇仁县| 平江县| 华亭县| 茶陵县| 宝清县| 阳原县| 青神县| 固始县| 台南县| 洛隆县| 大洼县| 民权县| 江孜县| 汾阳市| 竹山县| 文山县| 吴桥县| 慈溪市| 潮安县| 定安县| 仲巴县| 东乌珠穆沁旗| 惠水县| 文成县| 德清县| 三门峡市| 玛沁县| 谢通门县| 南部县| 萍乡市| 拜城县| 沐川县| 吕梁市|