本技巧阐明了 Web 服务描述语言(Web Services Description Language,WSDL)文件中两种类型的导入语句之间的细微差别。
导入
(Import)语句很简单,对吗?差不多每个程序或接口语言都用到它。当你阅读这篇技巧时,可能早已了解了关于导入的所有知识。那么,为什么要阅读这篇
关于 Web 服务描述语言(Web Services Description Language,WSDL)文件导入的技巧呢?首先,import
语句有两种类型:XSD 导入和 WDSL 导入。其次,这两种导入语句各自的特点不完全相同。最后,应该搞清楚这两者之间的联系。
Import 与 include
在深入描述 import 语句之前,让我们先来比较一下 import 和 include 之间的区别。import 语句引入其他的命名空间(namespace),但 include 语句却是将其他的声明引入到当前命名空间中。
XSD 导入
让我们来查看基本 XSD 导入,如清单 1
中用红色突出显示的部分所示。这部分语句做的全部事情就是将命名空间从一个模式导入到另一个模式。定义了 urn:listing2
命名空间的模式导入 urn:listing3 模式
。仅此而已,没有任何文件被导入。这两个模式都在清单 1 中的同一个文件内。
清单 1. 使用两个命名空间的地址簿 WSDL
<?xml version="1.0" ?>
<wsdl:definitions targetNamespace="urn:listing2"
xmlns:tns="urn:listing2"
xmlns:listing3="urn:listing3"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:schema targetNamespace="urn:listing3"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="Phone">
<xsd:sequence>
<xsd:element name="areaCode" type="xsd:int"/>
<xsd:element name="exchange" type="xsd:int"/>
<xsd:element name="number" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
<xsd:schema targetNamespace="urn:listing2"
xmlns:listing3="urn:listing3"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="urn:listing3"/>
<xsd:complexType name="Address">
<xsd:sequence>
<xsd:element name="streetNum" type="xsd:int"/>
<xsd:element name="streetName" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="phone" type="listing3:Phone"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="GetAddressRequest">
<wsdl:part name="name" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="GetAddressResponse">
<wsdl:part name="address" type="tns:Address"/>
</wsdl:message>
<wsdl:message name="GetPhoneRequest">
<wsdl:part name="name" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="GetPhoneResponse">
<wsdl:part name="phone" type="listing3:Phone"/>
</wsdl:message>
<wsdl:portType name="AddressBook">
<wsdl:operation name="getAddress">
<wsdl:input message="tns:GetAddressRequest"/>
<wsdl:output message="tns:GetAddressResponse"/>
</wsdl:operation>
<wsdl:operation name="getPhone">
<wsdl:input message="tns:GetPhoneRequest"/>
<wsdl:output message="tns:GetPhoneResponse"/>
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
从清单 1 的范例中显而易见导入的主要目的是为了导入命名空间。XSD 导入的一个更常见的用途是导入另一个文件中的命名空间。您可以聚集文件中的命名空间,但是请不要忘记那是您导入的命名空间
,而不是文件
(不要将 import 语句和 include 语句混淆)。
当您从一个文件导入命名空间时,将看见 XSD 导入语句中的 schemaLocation
属性,但这是一个可选属性。如您在清单 1 中所见, schemaLocation
不是必需的,因为 import 语句的命名空间如 import 语句本身一样,位于同一个位置(在同一个文件中)。实际上,即使您提供了文件位置(如清单 2
所示),XML 解析器也能够忽略该位置(如果 XML 解析器想这样做的话)。 schemaLocation
属性只不过是一个提示(hint)。如果解析器已经知道命名空间中的模式类型,或者有其他寻找这些模式类型的方法,它就不需要定位到你所提供的位置。它的
这个特性也从另一方面提示您 XSD import 语句的主要目的是导入命名空间,而不是告诉您在命名空间的何处可以找到这些声明。当然,大多数时候
XML 解析器并不了解您将要导入的命名空间,所以有必要指定 schemaLocation
属性,并且很容易忘记该属性其实仅仅是一个提示。
现在,查看清单 1
中
用蓝色突出显示的 import 语句。由于使用了 XSD 命名空间,因此应该实际导入该命名空间。但是这是一个十分常见的命名空间。事实上每个
XML 解析器都知道它。大多数解析器允许为其包含 import 语句。其实很多工具甚至允许您忽略红色部分的 import 语句 --
导入的存在于相同文件中的名字空间。但是导入所有要使用的命名空间是一个好习惯,您应该养成这样的习惯。因为您不知道什么时候或是某个使用您的
WSDL 文件的人可能将使用更严格的工具。
必须确保您在 import 语句中使用的命名空间与您所导入模式的 targetNamespace
相同。在清单 1
的范例中,显然您必须这样做。但是如果您将 urn:listing3
模式移动到一个名为 listing3.xml
的文件中,并导入该文件(如清单 2
所
示),那么这两者的相同可能就不那么明显了。实际上,这可能看起来好像您能够通过使用 import 语句中(而不是 targetNamespace
中)的不同命名空间属性在文件中修改模式的命名空间。这是一个错误。您不能修改命名空间。Import 语句的命名空间属性必须
与该模式的 targetNamespace 一致。
清单2
和3
源于清单 1
。清单 2 是清单 1 将 Phone 模式移到清单 3 中的文件之后的结果。清单 2 中的 import 语句现在包含了 schemaLocation
属性(用蓝色突出显示)。这是从文件导入模式的推荐方法。
清单 2. 导入 Phone 模式 XSD 文件的地址簿 WSDL
<?xml version="1.0" ?>
<wsdl:definitions targetNamespace="urn:listing2"
xmlns:tns="urn:listing2"
xmlns:listing3="urn:listing3"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<wsdl:types>
<xsd:schema targetNamespace="urn:listing2"
xmlns:listing3="urn:listing3"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="urn:listing3" schemaLocation="listing3.xsd"
/>
<xsd:complexType name="Address">
<xsd:sequence>
<xsd:element name="streetNum" type="xsd:int"/>
<xsd:element name="streetName" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="phone" type="listing3:Phone"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="GetAddressRequest">
<wsdl:part name="name" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="GetAddressResponse">
<wsdl:part name="address" type="tns:Address"/>
</wsdl:message>
<wsdl:message name="GetPhoneRequest">
<wsdl:part name="name" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="GetPhoneResponse">
<wsdl:part name="phone" type="listing3:Phone"/>
</wsdl:message>
<wsdl:portType name="AddressBook">
<wsdl:operation name="getAddress">
<wsdl:input message="tns:GetAddressRequest"/>
<wsdl:output message="tns:GetAddressResponse"/>
</wsdl:operation>
<wsdl:operation name="getPhone">
<wsdl:input message="tns:GetPhoneRequest"/>
<wsdl:output message="tns:GetPhoneResponse"/>
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
清单 3. Phone 模式的 XSD 文件
<?xml version="1.0" ?>
<xsd:schema targetNamespace="urn:listing3"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="Phone">
<xsd:sequence>
<xsd:element name="areaCode" type="xsd:int"/>
<xsd:element name="exchange" type="xsd:int"/>
<xsd:element name="number" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
WSDL 导入
查看清单4
和5
。
它们基本上与清单 2 和 3 相同。清单 4 导入清单 5,这与清单 2 导入清单 3 类似。但是这一次使用 WSDL 导入而不是 XSD
导入。清单 2 与清单 4 之间的差别在清单 4 中用蓝色突出显示。同样,清单 3 与清单 5 之间的差别在清单 5 中用蓝色突出显示。
清单 4. 导入 Phone 模式 WSDL 文件的地址簿 WSDL
<?xml version="1.0" ?>
<wsdl:definitions targetNamespace="urn:listing4"
xmlns:tns="urn:listing4"
xmlns:listing5="urn:listing5"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<wsdl:import namespace="urn:listing5" location="listing5.wsdl"/>
<wsdl:types>
<xsd:schema targetNamespace="urn:listing4"
xmlns:listing5="urn:listing5"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>
<xsd:complexType name="Address">
<xsd:sequence>
<xsd:element name="streetNum" type="xsd:int"/>
<xsd:element name="streetName" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="phone" type="listing5:Phone"
/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="GetAddressRequest">
<wsdl:part name="name" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="GetAddressResponse">
<wsdl:part name="address" type="tns:Address"/>
</wsdl:message>
<wsdl:message name="GetPhoneRequest">
<wsdl:part name="name" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="GetPhoneResponse">
<wsdl:part name="phone" type="listing5:Phone"/>
</wsdl:message>
<wsdl:portType name="AddressBook">
<wsdl:operation name="getAddress">
<wsdl:input message="tns:GetAddressRequest"/>
<wsdl:output message="tns:GetAddressResponse"/>
</wsdl:operation>
<wsdl:operation name="getPhone">
<wsdl:input message="tns:GetPhoneRequest"/>
<wsdl:output message="tns:GetPhoneResponse"/>
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
清单 5. Phone 模式的 WSDL 文件
<?xml version="1.0" ?>
<wsdl:definitions targetNamespace="urn:listing5"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:schema targetNamespace="urn:listing5"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>
<xsd:complexType name="Phone">
<xsd:sequence>
<xsd:element name="areaCode" type="xsd:int"/>
<xsd:element name="exchange" type="xsd:int"/>
<xsd:element name="number" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
</wsdl:definitions>
这样做很好吗?如果您在 listing4.wsdl 上运行 WSDL-to-Java 工具,将会发生错误。在清单 4 中,突出显示了两个对 Phone
类型的引用,一个是绿色的,另一个是红色的。绿色的引用在 WSDL 消息语句中。该语句能够查找到 Phone
,因为它是一个 WSDL 语句,并且 WSDL 文件是通过 WSDL import 语句导入 Phone
的。红色的引用在模式中。该引用不能查找到 Phone
,因为它不是通过 XSD import 语句来导入的。您不能在模式之外执行对其他模式的查找。而是必须
从模式内导入其他模式。
如果 Address
类型没有 phone 元素并且因此没有引用 urn:listing5
命名空间,那么清单 4 和 5 将是合法的。然而,对于用 WSDL 导入方法来导入模式信息而言,这不是一个好方法。清单 2 和 3 比清单 4 和 5 更佳。使用 XSD 导入 来导入模式,使用 WSDL 导入来导入 WSDL。
作为 WSDL 导入范例,您会注意到清单 4 中既没有绑定语句,也没有服务语句。估计可能一些其他包含绑定和服务的文件将通过 WSDL import 语句来导入 listing4.wsdl。
关于 WSDL 导入的最后两个注释。与 XSD 导入类似,WSDL 导入的 namespace
属性必须
和所导入 WSDL 的 targetNamespace 相同。WSDL 导入的 location
属性与 XSD 导入的 schemaLocation
属性相似,只不过是一个提示。然而,与 XSD 导入的 schemaLocation
属性不同的是,WSDL 导入的 location
属性是必须给出的。(这在 WSDL 1.1 规范中没有明确提出,但在 WS-I Web 站点的基本概要(Basic Profile)中阐明了这一点。(请参阅参考资料
。) )
结束语
简单的说,本技巧要说明的是:
- 使用 XSD 导入来导入模式,使用 WSDL 导入来导入 WSDL,这是一个很好的惯例。
- 导入所有要使用的命名空间,这是一个好习惯。
- 导入命名空间的属性值必须与导入的 targetNamespace 值一致。
- Import 语句的主要目的是导入命名空间。
schemaLocation
和 location
属性尽管有时是必需的,但其实只不过是一个提示。
分享到:
相关推荐
以前没学过webservice,项目经理突然要求用webservice处理项目,作为新手,在网上查阅了N多资源及教程后自己总结出来了靠谱的使用流程,包括相关包导入tomcat、myeclipse插件导入及wsdl文件导入生成Java类等
1. **导入WSDL文件**:假设我们有一个核心服务定义在`core_service.wsdl`中,而在`extensions.wsdl`中定义了对核心服务的扩展。在`extensions.wsdl`中,我们可以这样使用`import`: ```xml <wsdl:import namespace...
WSDL(Web Services Description Language)是用于定义Web服务接口的一种XML格式,它详细描述了服务的位置、使用的消息协议以及如何调用这些服务。当我们只有WSDL离线文件时,仍可以调用Web Service接口,下面将详细...
标题“onvif_wsdl”涉及的是ONVIF(Open Network Video Interface Forum)协议与WSDL(Web Services Description Language)的结合。ONVIF是一种开放标准,旨在规范网络视频安防设备之间的通信,确保不同厂商的产品...
2. **SoapUI**:强大的Web服务测试工具,支持WSDL导入和导出。 3. **Visual Studio**:Microsoft的开发环境,内建了WSDL支持。 **七、学习资源** 1. **官方文档**:W3C发布的WSDL规范(https://www.w3.org/TR/wsdl...
1. **WSDL导入**:用户可以输入WSDL URL或上传WSDL文件,工具会自动解析并显示可用的服务操作。 2. **SOAP调用**:允许用户选择一个操作,填写参数,并发送SOAP请求。工具会展示响应结果,帮助开发者验证服务是否按...
1. 改进了WSDL导入功能,支持更复杂的WSDL结构。 2. 提供了更丰富的断言类型,帮助用户全面验证服务响应。 3. 强大的脚本支持,允许自定义测试逻辑,进行更复杂的测试场景模拟。 4. 提供了详细的报告功能,方便分析...
步骤一:导入WSDL 1. 打开Postman,点击顶部菜单的"文件",选择"导入"。 2. 在弹出的窗口中,点击"上传文件",选择包含WSDL的XML文件。 3. Postman会解析WSDL并创建一个集合,其中包含了服务提供的所有操作。 步骤...
- **定义**:包括命名空间和导入其他WSDL文件的信息。 - **消息**:定义了可以被交换的数据抽象。 - **端口类型**:定义了操作及其消息的抽象集合。 - **绑定**:将端口类型的抽象定义绑定到具体的传输协议和消息...
它支持自动完成,WSDL导入以及对WSDL文档的实时更新,帮助开发者快速理解和测试接口。 2. **RESTful API测试**:除了SOAP,SOAPUI还支持RESTful服务的测试。你可以创建REST请求,包括GET、POST、PUT、DELETE等HTTP...
1. **导入依赖**:在项目中引入WSDL4J的库,通常是通过Maven或Gradle的依赖管理来完成。 2. **加载WSDL**:使用`WSDLReader`类读取WSDL文件,例如`WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();`...
Eclipse中用wsdl生成java客户端 Eclipse是一款功能强大、功能丰富的集成开发环境(IDE),广泛应用于Java开发领域。随着WebService技术的普及,Eclipse也提供了相应的支持,允许开发者通过wsdl文件生成Java客户端...
Delphi 中 String 与 WideString 的区别 Delphi 中的字符串类型主要有三种:ShortString、AnsiString 和 WideString。其中,AnsiString 是 Delphi 中最常用的字符串类型,它具有动态分配字符串空间和自动回收的功能...
另外,还可以使用IDE如Visual Studio的“添加服务引用”功能,它会自动处理WSDL导入和代理类生成。 总结,调用Java或.NET编写的WebService主要依赖于WSDL定义的服务接口。通过生成并使用客户端代理类,可以轻松地...
3. **WSDL导入**:能够从WSDL文件中自动获取接口定义,自动生成请求模板,简化测试工作。 4. **断言和验证**:对返回的响应数据进行断言,确保响应数据与预期相符,例如检查响应状态码、返回值、错误信息等。 5. *...
9. **IDE集成**:现代的Java集成开发环境(IDE),如Eclipse和IntelliJ IDEA,都内置了对WSDL的支持,可以直接导入WSDL文件生成服务客户端或服务实现。 10. **测试WSDL服务**:使用WSDL测试客户端(如 soapUI)可以...
- 使用WSDL导入器导入Web服务的定义。 - 引用导入的单元(如`Service1`)并在THTTPRIO的`URL`属性中设置Web服务的地址。 - 在按钮的点击事件中,调用Web服务的方法,如示例中的`HelloWorld`方法。 6. **解决测试...
- 使用Delphi 7的WSDL导入功能导入WSDL文件。 - 保存生成的单元文件(如`unitService1`)。 ##### 3. 引用Service1单元文件 - 在主单元文件(如`unit1`)中引用之前导入的Service1单元文件。 ##### 4. 设置HTTPRIO...
【Delphi调用...总之,Delphi调用WebService涉及到Wsdl导入、控件配置、参数传递、IIS配置以及错误排查等多个环节,理解并掌握这些知识点对于开发人员来说至关重要,能够帮助他们高效地实现跨平台的数据交互。
2. **WSDL导入:** 对于SOAP Web服务,WSDL文件是关键,因为它定义了服务的接口和消息格式。在新项目中,你可以通过以下步骤导入WSDL: - 新建一个类或在现有类中引入Web服务。 - 使用Eclipse或MyEclipse的New -> ...