XML - 管理数据交换/Web 服务
上一章 | 下一章 |
← AJAX | XMLHTTP → |
学习目标
|
由以下机构赞助 佐治亚大学 特里商学院 管理信息系统系 |
Web 服务概述
[edit | edit source]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(Microsoft 和 Verisign 为支持身份验证和注册而进行的持续工作)等技术。
SOAP
[edit | edit source]简单对象访问协议 (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 被留空,因为这将自动获取最新数据。format 数据类型未定义,因为它在 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 服务传递信息和从 Web 服务接收信息的理想方式。
服务描述 - WSDL
[edit | edit source]Web 服务描述语言 (WSDL)旨在提供有关如何连接和查询特定 Web 服务的信息。该文档也遵守严格的格式和组织准则。但是,方法、参数和服务信息是特定于应用程序的。Web 服务执行不同的功能并包含独立的信息,但它们的组织方式相同。通过为这些服务创建标准的组织架构,开发人员可以有效地调用和利用它们,而无需太多或几乎无需熟悉。要使用 Web 服务,开发人员可以遵循 WSDL 的设计标准,以轻松确定与其使用相关的所有信息和过程。
本质上,WSDL 文档充当与 Web 服务交互的说明。它不包含任何应用程序逻辑,从而为服务提供了一定程度的自主权。这使用户能够有效地与服务交互,而不必了解其内部工作机制。
以下是一个 WSDL 文件示例,该文件用于提供给定美国邮政编码的温度的 Web 服务。
<?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
[edit | edit source]您已经了解了如何使用 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 注册中心和存储库标准。
要执行 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 版本为 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 服务的查找位置。 |
- Weather.gov
- WebServices.org
- W3C 的 Web 服务参考
- UDDI.org
- XMethods.net
- Java API for XML Registries
- Apache SOAP 工具包
- Java 邮件框架
- Java 激活框架
- Xerces Java 解析器
- Jasnowski, Mike. Java、XML 和 Web 服务圣经
- Microsoft Web 服务
- http://www.xml.com/
- https://w3schools.org.cn/soap/soap_intro.asp
- https://wikibooks.cn/wiki/XML_-_Managing_Data_Exchange/Web_services
- http://www.w3.org/TR/2007/REC-soap12-part0-20070427/
- http://www.eweek.com/article2/0,1895,1589730,00.asp
- http://www.ibm.com/developerworks/xml/library/x-soapcl/