标签:子邮件 不包含 包名 als 分享 容器 sfb 数据传输 b站
<什么是WSDL语言>
WSDL(网络服务描述语言,Web Services Description Language)是一门基于 XML 的语言,用于描述 Web Services 以及如何对它们进行访问,参阅http://www.w3school.com.cn/wsdl/index.asp。
?WSDL文档可以分为两部分,顶部分由抽象定义组成,而底部分由具体描述组成。
?抽象部分
抽象部分以独立于平台和语言的方式定义SOAP消息,它们并不包含任何随机器或语言而变的元素。这就定义了一系列服务,截然不同的应用都可以实现。
?具体部分
具体部分,如数据的序列化则归入底部分,因为它包含具体的定义。在上述的文档元 素中,<types>、<message>、<portType>属于抽象定义 层,<binding>、<service>属于具体定义层。所有的抽象可以是单独存在于别的文件中,也可以从主文档中导入。
Type :数据类型定义的包容器。对类型的描述可以用xsd来完成。
Message :定义通信中的数据。包括数据输入和输出。
Operation :对某项服务所能完成的一个动作进行的抽象定义。
Port :由一个绑定和一个网络地址所定义的一个端点。
PortType :对一个或多个端口所支持的一组操作进行描述。
Binding :为一个给定的端口类型安排协议和数据格式。
Service :由一组相互关联的端口所构成的一个聚合。
<WDSL实例>
通过http://localhost:9000/helloWorld?wsdl可以查看到XML文件,这就是WSDL(WebService Definition Language),将该wsdl文件通过浏览器“将页面另存为”保存为helloWorld.wsdl。完整的 WSDL 语法见http://www.w3school.com.cn/wsdl/wsdl_syntax.asp
<?xml version=‘1.0‘ encoding=‘UTF-8‘?>
<wsdl:definitions name="HelloWorld"
targetNamespace="http://server.cxf.webservice.web.apps.lucl.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://server.cxf.webservice.web.apps.lucl.com/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
>
<!-- 定义数据类型 -->
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://server.cxf.webservice.web.apps.lucl.com/"
elementFormDefault="unqualified"
targetNamespace="http://server.cxf.webservice.web.apps.lucl.com/"
version="1.0">
<xs:element name="sayHi" type="tns:sayHi" />
<xs:element name="sayHiResponse" type="tns:sayHiResponse" />
<xs:complexType name="sayHi">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHiResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<!-- 定义消息分组 -->
<wsdl:message name="sayHiResponse">
<wsdl:part element="tns:sayHiResponse" name="parameters" />
</wsdl:message>
<wsdl:message name="sayHi">
<wsdl:part element="tns:sayHi" name="parameters" />
</wsdl:message>
<!-- 定义port type -->
<wsdl:portType name="HelloWorldPortType">
<wsdl:operation name="sayHi">
<wsdl:input message="tns:sayHi" name="sayHi" />
<wsdl:output message="tns:sayHiResponse" name="sayHiResponse" />
<!-- 指定当 Web 服务设法响应客户机的请求时所发生的任何消息级异常 -->
<!--
<wsdl:fault name="" message=""></wsdl:fault>
-->
</wsdl:operation>
</wsdl:portType>
<!-- binding操作到特定协议,即关联portType到协议,这里为SOAP -->
<!-- W3C 推荐了三个 Web 服务的绑定:
HTTP 上的 SOAP(SOAP over HTTP)
HTTP GET/POST
SOAP/MIME
-->
<wsdl:binding name="HelloWorldSoapBinding" type="tns:HelloWorldPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="sayHi">
<soap:operation soapAction="" style="document" />
<wsdl:input name="sayHi">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="sayHiResponse">
<soap:body use="literal" />
</wsdl:output>
<!-- 应用portType处的fault -->
<!--
<wsdl:fault name="">
<soap:fault name="" use="literal"/>
</wsdl:fault>
-->
</wsdl:operation>
</wsdl:binding>
<!--
描述binding的连接信息,根据绑定所实现的 portType 来处理请求。
对于 HTTP 上的 SOAP,这就是指向那个进程的 URL。
-->
<wsdl:service name="HelloWorld">
<wsdl:port binding="tns:HelloWorldSoapBinding" name="HelloWorldPort">
<soap:address location="http://localhost:9000/helloWorld" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
<wsdl:definition>
WSDL的根元素,主要属性为name和targetNamespace两个。
name为公开的Web服务接口,默认为实现类+Service,可通过WebService的serviceNmae指定;
targetNamespace指定目标名称空间,属性值同样被后面的xmlns:tns属性作为值,默认是使用接口实现类的包名的反序(http://server.cxf.webservice.web.apps.lucl.com/)。
<wsdl:types>
xs:schema是定义xml的属性信息,如命名空空间。
通过<xs:element... 和<xs:complexType...对元素进行说明,wsdl2java会根据element生成java类,而根据complexType创建类的属性。<xs:element...>
name为定义的方法sayHi以及元素sayHiResponse,
type属性是tns:+name属性对应的方法名。
sayHi是对方法的封装,sayHiResponse是对返回值的封装。
说明:可以使用WebMethod的operationName属性来自定义名称。
<xs:complexType...>
这个元素通过name属性关联到<xs:element...,它为element元素指定封装的具体内容,
通过子元素<xs:sequence...指定(参数名和参数类型)。
@WebService(name="HelloWorldPortType")
public interface HelloWorld {
@WebMethod(operationName="cusSayHi")
@WebResult(name="sayHiToUser") String sayHi(@WebParam(name="text") String text);
}
<wsdl:message>
这个元素将输入参数(方法参数)和响应结果(方法返回值)、受检查的异常信息包装为消息。
<wsdl:portType>
指定Web服务的端口类型(Web服务会被发布为EndPoint端点服务),它的name属性默认为接口名称(可以使用@WebService 注解的name 属性指定值,默认为实现类+Port)。
子元素<wsdl:operation …指定该端点服务包含了那些操作( 方法),input/output指定操作的输入输出(通过属性message 绑定到前面声明过的消息)。
<wsdl:operation… 的子元素>
<wsdl:input message="tns:sayHi" name="sayHi" />
<wsdl:output message="tns:sayHiResponse" name="sayHiResponse" />
<wsdl:binding>
将前面的端点服务绑定到SOAP协议,其中<soap:xxx... 的style、use分别可以使用SOAPBinding注解的style、use属性指定值。<wsdl:operation...>
指定公开的操作(方法)
<wsdl:service>
name 属性指定服务名称。
与根元素name值相同,可通过WebService的serviceName属性指定,默认为实现类+Service。
子元素<wsdl:port… 的name 属性指定port 名称,可通过WebService的属性portName指定,默认为实现类+Port。
子元素<soap:address … 的location 属性指定Web 服务的地址。
<深入理解WSDL>
曾经有人说soap并不真需要什么接口描述语言。如果soap是交流纯内容的标准,那就需要一种语言来描述内容。soap消息确实带有某些 类型信息 ,因此soap允许动态的决定类型。但不知道一个函数的函数名,参数的个数和各自类型,怎么可能去调用这个函数呢?没有wsdl,可以从必备文档中确定调用语法,或者检查消息。即便何种方法,都必须有人参与,这个过程可能会出错。而使用了wsdl,就可以通过这种跨平台和跨语言的方法使web service代理的产生自动化。
每个wsdl都定义了一项服务(service),而这项服务被定义为一组“端口(port)”。你可以把wsdl中的端口想象为URL地址,而不是TCP/IP中的数据通道。一个端口定义了一个”服务”项目的提供地点。一项服务可以有多个提供地点,但只能对一组事先安排好的“信息(message)”作出响应。“信息”是对通信数据的描述,每条信息由一组数据组成,这些数据必须定义为收发双方都知道的某种“类型(type)”。如果没有遇到其他方法更能说明问题的情况,则”类型”必须用XSD来定义。端口和信息结合在一起代表了一组“操作(operation)”,并定义了这个端口的“端口类型(portType)”。把一种协议和一种数据格式关联在一起就定义了一种可重复使用的“绑定(binding)”。把一个网络地址和一个绑定关联在一起就定义出了一个端口,而一组端口将定义出一项服务。综上所述,wsdl文档使用下面这些元素来定义一项网络服务:
Type :数据类型定义的包容器。对类型的描述可以用xsd来完成。
Message :定义通信中的数据。包括数据输入和输出。
Operation :对某项服务所能完成的一个动作进行的抽象定义。
Port :由一个绑定和一个网络地址所定义的一个端点。
PortType :对一个或多个端口所支持的一组操作进行描述。
Binding :为一个给定的端口类型安排协议和数据格式。
Service :由一组相互关联的端口所构成的一个聚合。
在开始讨论这些术语之前,需要对wsdl技术标准所使用的命名空间前缀有一个了解。大家应该习惯使用这些前缀。wsdl技术标准所使用的名字空间前缀见下表。
所有xml文档需要有一个顶级文档作为树结构的 根 。而wsdl技术标准选定的就是这个。
?documentation
这个元素可以包含任意文本和元素。只要你就觉得有必要在文档里的某个位置加上一些额外的资料帮助其他人阅读和理解,就可以向这个元素注射一个注释文档进来。
?message
对服务过程中锁发送和接收的数据进行的抽象定义。它可以由多个逻辑部分组成,每个部分必须与某个类型相关联。
?portType
对给定端口上的可用操作集合进行的定义。
?operation
给操作起个名字,并列出预期的输入和输出情况。每个元素还可以包含一个对该operation可能返回的出错数据进行描述的fault子元素。
?input
对给定操作用作输入参数的元素进行描述。它还可以把input链接到一个指定的信息。
?output
对给定操作作为输出参数返回的元素进行描述。它还可以把output链接到一个指定的信息。
?fault
对可能返回的出错数据进行定义。
?binding
为给定的portType所定义的操作和信息指定协议和数据格式。
?service
用来把相关的端口组织在一起。
?port
为一个给定的绑定分配地址。它通常以URN标识符的形式出现。一个典型的wsdl文档看起来使这个样子(其中的*,?,+就是普通的通配符含义,代表该元素出现的限制):
? 不带import元素的wsdl文档
?下面先提取出http://example.com/stockquote/stockquote.xsd的内容
下面是完整的http://example.com/stockquote/stockquoteservice.wsdl的内容。
?首先是了解消息头header和ProbeMatches中的内容,非常重要,可以参考这里http://www.w3.org/Submission/ws-addressing/ 最好详细的学习一下,里面的内容非常重要。
?其次需要理解的是,其实当你看完ws-addressing后你会发现,骨架代码中的结构体和SOAP消息中的内容是一一对应的,例如:
结构体osap->header对应SOAP消息的<SOAP-ENV:Header></SOAP-ENV:Header>中的内容,包含在header里的内容当然会包含在SOAP的header内。例如:
结构体soap->header->wsa__RelatesTo对应的是<wsa:RelatesTo></wsa:RelatesTo>。
?最后需要理解的是,在代码中的"__"双下划线一般对应xml中的命名空间的":",下划线前是命名空间,后是具体内容。
?最后的最后是要详细的阅读ONVIF Core Specification
下图为响应OnvifTestTool的Probe命令的SOAP消息
结合上图再分析代码就亲切多了。在ONVIF Core Specification的7.3.2.2 Scopes 一节描述了onvif需要的Scopes,这个是需要在程序里填充,具体填充什么,文档里说的很明确:
注意点是在太多,随便漏掉一个都可能会导致搜不到设备,下图是非常重要的一个:
SOAP1.1和SOAP1.2所使用的SOAP-ENV是不同的,ONVIF使用的是SOAP1.1,如果soapcpp2产生的nsmap文件中的SOAP-ENV是SOAP1.2版本的话,那么OnvifTestTool是不会识别设备发出的SOAP消息的。
标签:子邮件 不包含 包名 als 分享 容器 sfb 数据传输 b站
原文地址:http://www.cnblogs.com/big-devil/p/7625770.html