跳轉到內容

XML - 資料交換/Web服務管理

來自Wikibooks,開放世界的開放書籍



上一章 下一章
AJAX XMLHTTP



學習目標

  • 瞭解Web服務及其功能。
  • 瞭解SOAP是什麼,以及Web服務如何使用它。
  • 瞭解Web服務描述語言是什麼,以及如何閱讀WSDL檔案。
  • 瞭解通用描述、發現和整合(UDDI)標準是什麼。
  • 瞭解如何使用Java連線到Web服務。

贊助商

佐治亞大學

特里商學院

管理資訊系統系

Web服務概述

[編輯 | 編輯原始碼]

Web服務是新一代的Web應用程式。它們是自包含的、自描述的、模組化的應用程式,可以在Web上釋出、定位和呼叫。Web服務執行功能,這些功能可以是簡單的請求到複雜的業務流程。一旦部署了Web服務,其他應用程式(和其他Web服務)就可以發現並呼叫已部署的服務。Web服務利用XML來描述請求和響應,並使用HTTP作為其網路傳輸。

Web服務和Web應用程式之間的主要區別在於協作。Web應用程式只是使用Web協議定位或呼叫的業務應用程式。類似地,Web服務也在網路上遠端執行計算功能。但是,Web服務使用網際網路協議,其目的是實現可互操作的機器到機器協調。

Web服務已成為解決分散式計算相關問題的解決方案。分散式計算是使用多個系統來執行功能,而不是讓單個系統執行功能。以前在分散式計算中使用的技術,主要是公共物件請求代理體系結構(CORBA)和分散式元件物件模型(DCOM),存在一些侷限性。例如,兩者都沒有實現完全的平臺獨立性或易於透過防火牆傳輸。此外,DCOM不是供應商獨立的,它是微軟的產品。

分散式計算標準的一些主要需求是

  • 跨平臺支援企業對企業以及內部通訊。
  • 儘可能符合現有的網際網路基礎設施。
  • 可擴充套件性,包括節點數量和複雜性。
  • 國際化。
  • 容錯性。
  • 供應商獨立性。
  • 適用於簡單和非簡單的請求。

隨著時間的推移,業務資訊系統變得高度配置和差異化。這不可避免地使系統互動變得極其昂貴和耗時。開發人員開始認識到標準化Web服務開發的好處。使用Web標準似乎是實現這些目標的直觀且合乎邏輯的步驟。Web標準已經為系統通訊提供了一種平臺獨立的方式,並且被資訊系統使用者廣泛接受。

最終結果是開發了Web服務。Web服務形成一個分散式環境,其中可以透過標準化介面遠端訪問物件。它使用三層模型,定義服務提供者、服務消費者和服務代理。這使得Web服務成為一種鬆散的關係,因此,如果服務提供者宕機,代理始終可以將消費者引導到另一個提供者。類似地,有很多代理,因此消費者總是可以找到一個可用的代理。為了進行通訊,Web服務使用開放的Web標準:TCP/IP、HTTP和基於XML的SOAP。

在更高層次上,可能會新增諸如XAML、XLANG(涉及多個Web服務的複雜Web事務的事務支援)和XKMS(微軟和Verisign正在進行的工作,以支援身份驗證和註冊)等技術。

SOAP結構

簡單物件訪問協議 (SOAP) 是一種以可擴充套件格式向Web服務傳送和接收資訊的方法。SOAP可用於傳送資訊或作為XML編碼的遠端過程呼叫。從本質上講,SOAP充當了與Web服務進行通訊的普遍接受的方法。企業遵守SOAP約定是為了簡化與Web服務互動的過程。

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

  <!-- SOAP header -->

 </SOAP:Header>
 <SOAP:Body SOAP:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

  <!-- SOAP body -->

 </SOAP:Body>
</SOAP:Envelope>

SOAP訊息包含用於呼叫Web服務的請求方法,或包含對Web服務請求的響應資訊。

在開發獨立的Web服務時遵循此佈局為企業提供了顯著的好處。由於Web應用程式旨在被眾多參與者使用,因此開發人員希望它們易於採用。使用既定且熟悉的通訊標準最終減少了使用者有效互動Web服務所需的工作量。

SOAP信封用於定義和組織Web服務訊息中包含的內容。主要的是,SOAP信封用於指示指定文件將用於服務互動。它包含一個可選的SOAP頭和一個SOAP主體。訊息在SOAP主體中傳送,SOAP頭用於傳送主體中不期望的其他資訊。例如,如果SOAP:actor屬性存在於SOAP頭中,則表示訊息的接收者應該是誰。

Web服務事務涉及SOAP請求和SOAP響應。我們將使用的示例是Weather.gov提供的Web服務。輸入是緯度、經度、開始日期、所需的預報資訊天數以及資料的格式。SOAP請求如下所示

  <?xml version="1.0" encoding="UTF-8" standalone="no"?/>
  <SOAP-ENV:Envelope
      SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
      xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
     
     <SOAP-ENV:Body>
        <m:NDFDgenByDayRequest xmlns:SOAPSDK1="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl">
           <latitude xsi:type="xsd:decimal">33.955464</latitude>
           <longitude xsi:type="xsd:decimal">-83.383245</longitude>
           <startDate xsi:type="xsd:date"></startDate>
           <numDays xsi:type="xsd:integer">1</numDays>
           <format>24 Hourly</format>
        </m:NDFDgenByDayRequest>
     </SOAP-ENV:Body>
     
  </SOAP-ENV:Envelope>

startDate被留空,因為這將自動獲取最新資料。格式資料型別未定義,因為它在WSDL文件中定義。

響應SOAP如下所示。

  <?xml version="1.0" encoding="UTF-8" standalone="no"?/>
  <SOAP-ENV:Envelope
      SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
      xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
     
     <SOAP-ENV:Body>
        <NDFDgenByDayResponse xmlns:SOAPSDK1="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl">
           <dwmlByDayOut xsi:type="xsd:string">.....</dwmlByDayOut>
        </NDFDgenByDayResponse>
     </SOAP-ENV:Body>
     
  </SOAP-ENV:Envelope>

SOAP透過在傳送方對其進行編碼並在接收方對其進行解碼來處理資料。SOAP處理的資料型別基於W3C XML Schema規範。簡單型別包括字串、整數、浮點數和雙精度數,而複合型別由基本型別組成。

  <element name="name" type="xsd:string" />
  <SOAP:Array SOAP:arrayType="xsd:string[2]">
     <string>Web</string>
     <string>Services</string>
  </SOAP:Array>

由於它們是基於文字的,因此SOAP訊息通常不會遇到透過防火牆或其他障礙的問題。它們是向Web服務傳遞和接收資訊的理想方式。

服務描述 - WSDL

[編輯 | 編輯原始碼]

Web服務描述語言 (WSDL) 旨在提供有關如何連線到特定Web服務並對其進行查詢的資訊。此文件也遵循嚴格的格式和組織指南。但是,方法、引數和服務資訊是特定於應用程式的。Web服務執行不同的功能幷包含獨立的資訊,但它們都以相同的方式組織。透過為這些服務建立標準的組織架構,開發人員可以有效地呼叫和利用它們,而無需太多熟悉。要使用Web服務,開發人員可以遵循WSDL的設計標準,輕鬆確定與其使用相關的所有資訊和過程。

從本質上講,WSDL文件充當與Web服務互動的說明。它不包含任何應用程式邏輯,從而使服務具有一定的自主性。這使使用者能夠有效地與服務互動,而無需瞭解其內部工作原理。

以下是提供給定美國郵政編碼的溫度的Web服務的WSDL檔案的示例。

<?xml version="1.0"?>
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:si="http://soapinterop.org/xsd" xmlns:tns="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" 
xmlns:typens="http://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" 
targetNamespace="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl>
 
 <types>
    <xsd:schema targetNamespace="http://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd">
       <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
       <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
       <xsd:simpleType name="formatType">
          <xsd:restriction base="xsd:string">
             <xsd:enumeration value="24 hourly" />
             <xsd:enumeration value="12 hourly" />
          </xsd:restriction>
       </xsd:simpleType>
       <xsd:simpleType name="productType">
          <xsd:restriction base="xsd:string">
             <xsd:enumeration value="time-series" />
             <xsd:enumeration value="glance" />
          </xsd:restriction>
       </xsd:simpleType>
       <xsd:complexType name="weatherParametersType">
          <xsd:all>
             <xsd:element name="maxt" type="xsd:boolean" />
             <xsd:element name="mint" type="xsd:boolean" />
             <xsd:element name="temp" type="xsd:boolean" />
             <xsd:element name="dew" type="xsd:boolean" />
             <xsd:element name="pop12" type="xsd:boolean" />
             <xsd:element name="qpf" type="xsd:boolean" />
             <xsd:element name="sky" type="xsd:boolean" />
             <xsd:element name="snow" type="xsd:boolean" />
             <xsd:element name="wspd" type="xsd:boolean" />
             <xsd:element name="wdir" type="xsd:boolean" />
             <xsd:element name="wx" type="xsd:boolean" />
             <xsd:element name="waveh" type="xsd:boolean" />
             <xsd:element name="icons" type="xsd:boolean" />
             <xsd:element name="rh" type="xsd:boolean" />
             <xsd:element name="appt" type="xsd:boolean" />
          </xsd:all>
       </xsd:complexType>
    </xsd:schema>
</types>

<message name="NDFDgenRequest">  
   <part name="latitude" type="xsd:decimal"/>
   <part name="longitude" type="xsd:decimal" />
   <part name="product" type="typens:productType" />
   <part name="startTime" type="xsd:dateTime" />
   <part name="endTime" type="xsd:dateTime" />
   <part name="weatherParameters" type="typens:weatherParametersType" />
</message>

<message name="NDFDgenResponse">
   <part name="dwmlOut" type="xsd:string" />
</message>

<message name="NDFDgenByDayRequest">  
   <part name="latitude" type="xsd:decimal" />
   <part name="longitude" type="xsd:decimal" />
   <part name="startDate" type="xsd:date" />
   <part name="numDays" type="xsd:integer" />
   <part name="format" type="typens:formatType" />
</message>

<message name="NDFDgenByDayResponse">
   <part name="dwmlByDayOut" type="xsd:string" />
</message>

<portType name="ndfdXMLPortType">
   <operation name="NDFDgen">
      <documentation> Returns National Weather Service digital weather forecast data </documentation>
      <input message="tns:NDFDgenRequest" />
      <output message="tns:NDFDgenResponse" />
   </operation>
   <operation name="NDFDgenByDay">
      <documentation> Returns National Weather Service digital weather forecast data summarized over either 24- or 12-hourly periods </documentation>
      <input message="tns:NDFDgenByDayRequest" />
      <output message="tns:NDFDgenByDayResponse" />
   </operation>
</portType>

<binding name="ndfdXMLBinding" type="tns:ndfdXMLPortType">
   <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
   <operation name="NDFDgen">
      <soap:operation soapAction="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl#NDFDgen" style="rpc" />
      <input>
         <soap:body use="encoded" namespace="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" 
             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </input>
      <output>
         <soap:body use="encoded" namespace="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" 
             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </output>
   </operation>
   <operation name="NDFDgenByDay">
      <soap:operation soapAction="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl#NDFDgenByDay" style="rpc" />
      <input>
         <soap:body use="encoded" namespace="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" 
             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </input>
      <output>
         <soap:body use="encoded" namespace="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" 
             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </output>
   </operation>
</binding>

<service name="ndfdXML">
   <documentation>The service has two exposed functions, NDFDgen and NDFDgenByDay. 
                        For the NDFDgen function, the client needs to provide a latitude and 
                        longitude pair and the product type. The client also needs to provide 
                        the start and end time of the period that it wants data for. For the 
                        time-series product, the client needs to provide an array of boolean values 
                        corresponding to which weather values should appear in the time series product. 
                        For the NDFDgenByDay function, the client needs to provide a latitude and longitude 
                        pair, the date it wants to start retrieving data for and the number of days worth 
                        of data. The client also needs to provide the format that is desired.</documentation>
   <port name="ndfdXMLPort" binding="tns:ndfdXMLBinding">
      <soap:address location="http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php" />
   </port>
  </service>
</definitions>

WSDL檔案定義了一個服務,該服務由稱為埠的不同端點組成。埠由網路地址和繫結組成。

<service name="ndfdXML">
   <documentation>The service has two exposed functions, NDFDgen and NDFDgenByDay. 
                        For the NDFDgen function, the client needs to provide a latitude and 
                        longitude pair and the product type. The client also needs to provide 
                        the start and end time of the period that it wants data for. For the 
                        time-series product, the client needs to provide an array of boolean values 
                        corresponding to which weather values should appear in the time series product. 
                        For the NDFDgenByDay function, the client needs to provide a latitude and longitude 
                        pair, the date it wants to start retrieving data for and the number of days worth 
                        of data. The client also needs to provide the format that is desired.</documentation>
   <port name="ndfdXMLPort" binding="tns:ndfdXMLBinding">
      <soap:address location="http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php" />
   </port>
</service>

繫結標識每個操作的繫結樣式和協議。在這種情況下,它使用遠端過程呼叫樣式繫結,使用SOAP。

   <binding name="ndfdXMLBinding" type="tns:ndfdXMLPortType">
   <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
   <operation name="NDFDgen">
      <soap:operation soapAction="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl#NDFDgen" style="rpc" />
      <input>
         <soap:body use="encoded" namespace="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" 
             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </input>
      <output>
         <soap:body use="encoded" namespace="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" 
             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </output>
   </operation>
   <operation name="NDFDgenByDay">
      <soap:operation soapAction="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl#NDFDgenByDay" style="rpc" />
      <input>
         <soap:body use="encoded" namespace="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" 
             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </input>
      <output>
         <soap:body use="encoded" namespace="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" 
             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </output>
   </operation>
</binding>

埠型別是操作的抽象集合。在這種情況下,操作是getTemp。

   <portType name="ndfdXMLPortType">
      <operation name="NDFDgen">
         <documentation> Returns National Weather Service digital weather forecast data     </documentation>
         <input message="tns:NDFDgenRequest" />
         <output message="tns:NDFDgenResponse" />
      </operation>
      <operation name="NDFDgenByDay">
         <documentation> Returns National Weather Service digital weather forecast data summarized over either 24- or 12-hourly periods </documentation>
         <input message="tns:NDFDgenByDayRequest" />
         <output message="tns:NDFDgenByDayResponse" />
      </operation>
   </portType>

最後,訊息由操作用於通訊——換句話說,用於傳遞引數和返回值。

   <message name="NDFDgenByDayRequest">  
      <part name="latitude" type="xsd:decimal" />
      <part name="longitude" type="xsd:decimal" />
      <part name="startDate" type="xsd:date" />
      <part name="numDays" type="xsd:integer" />
      <part name="format" type="typens:formatType" />
   </message>

   <message name="NDFDgenByDayResponse">
      <part name="dwmlByDayOut" type="xsd:string" />
   </message>

從WSDL檔案,消費者應該能夠訪問Web服務中的資料。

有關此特定Web服務的更詳細分析,請訪問Weather.gov

服務發現 - UDDI

[編輯 | 編輯原始碼]

您已經瞭解瞭如何使用WSDL來共享Web服務的介面定義,但是您如何首先找到Web服務呢?有無數的獨立Web服務由同樣多的不同組織開發和維護。在採用Web服務實踐和方法後,開發人員試圖促進其系統的參與和創造性重用。很快發現,需要對這些服務及其各自的位置進行列舉記錄。此資訊將使開發人員能夠快速輕鬆地利用Web服務的最佳實踐和流程。此外,擁有當前Web服務功能的中央參考使開發人員能夠避免開發冗餘應用程式。

UDDI 定義了可以釋出和查詢服務的註冊中心。UDDI 規範是由微軟、Ariba 和 IBM 建立的。UDDI 定義了一種資料結構和應用程式程式設計介面 (API)。

在之前提到的三層模型中,UDDI 是服務代理。它的功能是使服務消費者能夠找到合適的服務提供者。

可以使用 Java API for XML Registries (JAXR) 透過 Java 連線到 UDDI 註冊中心。JAXR 建立了一個抽象層,因此它可以與 UDDI 和其他型別的 XML 註冊中心一起使用,例如 ebXML 註冊和儲存庫標準。

使用 Java 與 Web 服務

[編輯 | 編輯原始碼]

要執行 SOAP 訊息,必須使用應用程式與服務提供者通訊。由於其靈活性,幾乎任何程式語言都可以用來執行 SOAP 訊息。但是,為了我們的目的,我們將重點關注使用 Java 與 Web 服務進行互動。

使用 Java 與 Web 服務需要一些外部庫。

  • Apache SOAP 工具包
  • Java 郵件框架
  • JavaBeans 啟用框架
  • Xerces XML 解析器

讓我們一起學習如何使用 Java 查詢我們之前討論過的溫度 Web 服務。

import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.rpc.*;

public class TempClient
{

 public static float getTemp (URL url, String zipcode) throws Exception 
 {

  Call call = new Call ();

  // Service uses standard SOAP encoding
  String encodingStyleURI = Constants.NS_URI_SOAP_ENC;
  call.setEncodingStyleURI(encodingStyleURI);

  // Set service locator parameters
  call.setTargetObjectURI ("urn:xmethods-Temperature");
  call.setMethodName ("getTemp");

  // Create input parameter vector
  Vector params = new Vector ();
  params.addElement (new Parameter("zipcode", String.class, zipcode, null));
  call.setParams (params);

  // Invoke the service ....
  Response resp = call.invoke (url,"");

  // ... and evaluate the response
  if (resp.generatedFault ()) 
  {
   throw new Exception();
  } 
  else 
  {
   // Call was successful. Extract response parameter and return result
   Parameter result = resp.getReturnValue ();
   Float rate=(Float) result.getValue();
   return rate.floatValue();
  }
 }

 // Driver to illustrate service invocation
 public static void main(String[] args)
 {
  try
  {
   URL url=new URL("http://services.xmethods.net:80/soap/servlet/rpcrouter");
   String zipcode= "30605";
   float temp = getTemp(url,zipcode);
   System.out.println(temp);
  }
  catch (Exception e) 
  {
   e.printStackTrace();
  }
 }
}

此 Java 程式碼有效地隱藏了使用者的所有 SOAP。它透過名稱和 URL 呼叫目標物件,並設定引數zipcode。但是底層的 SOAP 請求是什麼樣子的呢?

  <?xml version="1.0" encoding="UTF-8"?>
  <soap:Envelope xmlns:n="urn:xmethods-Temperature"
      xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

     <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <n:getTemp>
           <zipcode xsi:type="xs:string">30605</zipcode>
        </n:getTemp>
     </soap:Body>

  </soap:Envelope>

如您所見,SOAP 請求使用 Java 呼叫傳遞的引數來填充 SOAP 信封並指導訊息。類似地,響應作為“70.0”返回到 Java 程式中。響應 SOAP 也被 Java 程式隱藏。

  <?xml version='1.0' encoding='UTF-8'?>
  <SOAP-ENV:Envelope 
      xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema">

     <SOAP-ENV:Body>
        <ns1:getTempResponse xmlns:ns1="urn:xmethods-Temperature" 
            SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
           <return xsi:type="xsd:float">70.0</return>
        </ns1:getTempResponse>
     </SOAP-ENV:Body>

  </SOAP-ENV:Envelope>

這是使用 Java 和 SOAP 與 Web 服務互動的另一個示例。此特定 Web 服務稱為“美國郵編驗證器”,它以郵政編碼作為引數,然後返回相應的經度和緯度。在開發與 Web 服務互動的應用程式時,第一步應該是檢視 WSDL 文件。

此服務的 WSDL 文件位於此處:http://www.webservicemart.com/uszip.asmx?WSDL

此文件將包含與“美國郵編驗證器”Web 服務互動所需的所有說明。

SOAPClient4XG

修改者 - Duncan McAllister 來自:http://www.ibm.com/developerworks/xml/library/x-soapcl/

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

public class SOAPClient4XG {
    
    public static void main(String[] args) throws Exception {

        args = new String[2];
        
        args[0] = "http://services.xmethods.net:80/soap/servlet/rpcrouter";
        args[1] = "SOAPrequest.xml";
        
        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 = "";

				
        // Create the connection where we'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'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'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);
        }
      }
    }
  } 
}

此 Java 類引用了一個 XML 文件 (SOAPRequest.xml),該文件用作 SOAP 訊息。此文件應包含在呼叫服務的 Java 應用程式的同一專案資料夾中。

在查看了“美國郵編驗證器”WSDL 文件後,很明顯我們想呼叫“getTemp”方法。此資訊包含在 SOAP 主體中,幷包含相應的引數。

SOAPRequest.xml

<?xml version="1.0" encoding="UTF-8"?>
  <soap:Envelope xmlns:n="urn:xmethods-Temperature"
      xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

     <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <n:getTemp>
           <zipcode xsi:type="xs:string">30605</zipcode>
        </n:getTemp>
     </soap:Body>

  </soap:Envelope>

成功互動後,Web 服務提供商將提供一個格式類似於使用者請求的響應。在 NetBeans 中開發時,執行此專案並在 Tomcat 輸出視窗中檢查隨後的 SOAP 訊息響應。


使用 Netbeans 的 Web 服務

[編輯 | 編輯原始碼]

此說明中使用的 Netbeans 版本為 5.0。

開啟 Netbeans 後,單擊左側窗格中的“執行時”選項卡,然後右鍵單擊“Web 服務”並選擇“新增 Web 服務”。在“URL”欄位中,輸入 Web 服務 WSDL 檔案的地址,在上面的示例中為“http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl”,然後單擊“獲取 Web 服務描述”。這將顯示 Web 服務的資訊。

Web 服務是使用 XML 與許多不同系統通訊以執行任務的應用程式。為了促進 Web 服務的使用,開發了允許它們靈活且可擴充套件的協議。SOAP 用於傳送和定義資訊,而 WSDL 用於提供有關如何連線和查詢 Web 服務的資訊。UDDI 描述了這些 Web 服務可以在哪裡找到。
[編輯 | 編輯原始碼]
華夏公益教科書