wsdl解析
首先介绍两个知识点:
a、xmlns使用方法
xmlns的使用格式是xmlns:namespace-prefix="namespace"
xmlns可以使用在任何元素上,表明该元素及其子元素,可以通过相应的前缀名引用定义在名字空间内的元素,可以引入多个名字空间。
比如:
<wsdl:definitions
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
</wsdl:definitions>
上述代表的含义是在definitions元素下,可以通过xsd前缀名和wsdl前缀分别引用名字空间"http://www.w3.org/2001/XMLSchema"和"http://schemas.xmlsoap.org/wsdl/"中定义的元素。
b、targetNamespace
由于在XML中并不一定都只是引用一个名字空间中的元素,有时也可能是要向一个名字空间中加入新的元素,那么应该如何向一个名字空间中加入元素呢?这时就要使用到targetNamespace。
targetNamespace也可以用在任何元素上,它代表在这个元素及其子元素下定义的任何元素、数据类型等都会被定义在指定的名字空间上。例如:
<wsdl:definitions
targetNamespace="http://com.lxzh.cxfDemo/HelloService"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:message name="xx">.....</wsdl:message>
</wsdl:definitions>
就是将该wsdl中的元素和数据类型都定义在命名空间"http://com.lxzh.cxfDemo/HelloService"下。
一般来说,定义 xmlns:xsd="http://www.w3.org/2001/XMLSchema"的都是一个xsd文件,这个xsd命名空间就是标准的XMLSchema.xsd文件。
当你引用到定义的类型时,在eclipse中的wsdl文件中就会有 xmlns:xsd1="http://www.lxzh.org/request",它指的是你自己定义的request.xsd文件。引用的类型就是属于这个request.xsd文件,在wsdl以后中使用的话就会使用xsd1......。这样的格式。
下面来说在eclipse下建立wsdl的内容。
在eclipse中建立一个wsdl文件时,首先点击“design”选项卡下的空白处,会看到definition,这里面的信息都会在definitons的根目录中出现。
点击上图中的“request”,properties视图中会显示这是一个service,name属性是"request"。
点击“requestSOAP”,下面会显示这是一个port,name属性是requestSOAP,Binding属性是requestSOAP,address属性是“http://www.lxzhrequestsoap.org/”,protocol(协议类型)是“SOAP”.需要注意的是上面的Binding属性,它是指的中间那个小方框。
点击“小方框”,下面出现的是binding。有三个属性,name,porttype,和protocol,点击“generate binding content”属性,可以对上面的三个属性进行修改。
点击"lxzhrequest1",会显示这是一个porttype,name属性是lxzhrequest1.
点击"requestLxzh",会显示这是一个operation,name是requestLxzh.
点击“input”,会显示这是一个input,Message属性是requestLxzhRequest。message属性是自动生成的。
点击“output”,会显示这是一个output,Message属性是requestLxzhResponse
点击“parameters”,会显示这是一个part,name属性是parameters,type属性是requestSimplelxzh,都是所显示的名称。
如果说xml是数据库中的数据,那么xsd就是数据库的定义。
WSDL文件是一个XML 文档,用于说明一组SOAP消息以及如何交换这些消息。
1.Types:独立与机器和语言的类型定义。
下面是关于types中的xml:schema的一些解释。我感觉types中定义的元素可有可无,官方上说的是Types中的元素要被message所使用,但我看来,当我把参数更改之后,types中的东西并没有改变。Types下面会有两个element,一个是以operation命名,一个是以operation+response来命名。两个element都包括复杂类型。一个是in,一个是out。绿底的字还没有整理,临时粘贴到这里的。在xsd:schema中的targetnamespace是说明下面定义的类型只有在这个命名空间中是有效的。
基本的XML Schema的使用就是这样,下面我们要介绍XML Schema的另外一个核心的部分也是Schema最关键的一个部分,就是关于Schema的名字空间(namespace)的问题。在上面关于XML Schema的介绍中,为了把读者集中到对XML Schema的语法理解上,特意省略了关于名字空间(namespace)的介绍。
首先我们还是从简单的例子着手,见下面的一段代码:
<xsd:schema targetNamespace= http://www.SampleStore.com/Account
xmlns:xsd= http://www.w3.org/2000/08/xmlSchema
xmlns:ACC= http://www.SampleStore.com/Account >
<xsd:element name= 订单号码 type= xsd:positiveInteger />
<xsd:element name= 商品编号 type= ACC:商品编号类型 />
<xsd:simpleType name= 商品编号类型 base= xsd:string >
<xsd:pattern value= [A-Z]{1}d{6} />
<!-上面的一行代码表示商品编码的第一个字符应该为字母,后面跟六个阿拉伯数字 -->
</xsd:simpleType>
现在大家需要把注意力集中到开头几行的代码上来,如下:
<xsd:schema targetNamespace= http://www.SampleStore.com/Account
xmlns:xsd= http://www.w3.org/2000/08/xmlSchema
xmlns:ACC= http://www.SampleStore.com/Account >
实际上,一个给定的XML Schema定义了一系列的元素名称,类型名称,属性名称和属性组名称。比如上面的代码中的订单号码、商品编号、商品编号类型等。而这些名称都有它一定的作用范围,类似于C++中的局部变量的概念。而它们的作用范围是什么呢?就是在他们的目标名字空间(target namespace)中是有效的,在上面的代码中,我们可以看到它的目标名字空间为http://www.SampleStore.com/Account。
需要注意的是,目标名字空间的命名必须遵守URL的语义。同时需要注意的是,该目标名字空间并不是指一个具体的文件,仅仅是给它一个名字而已。实际上,在Schema中的定义和声明也可以引用其他的名字空间,我们可以把这种名字空间取名为源名字空间(source namespaces)。每一个Schema必须有一个目标名字空间,但是可以有多个源名字空间。
实际上,在一个给定的Schema中,每一个名称都是属于一个特定的名字空间的。名字空间的名称可能会很长(比如http://www.SampleStore.com/Account),但是它们可以用在XML Schema中的语义xmlns来进行简化。在上面的例子中,我们用xsd(取名为xsd是任意的,比如你可以取名为kkk,tt,ppp,gh都可以)来表示名字空间 http://www.w3.org/2000/08/xmlSchema ,用ACC来表示名字空间http://www.SampleStore.com/Account。同时我们把http://www.w3.org/2000/08/xmlSchema这个名字空间称为标准名字空间(standard namespace),因为它是定义Schema语法的标准地
2.message
<message>元素包含了Messages栏。如果我们把操作看作函数,<message>元素定义了那个函数的参数。其实这一点在上面的例子中就可以看到,当点击“input”时,它有两个属性,一个是name,一个是message。message的值是****request;当点击“output”时,它的message属性是*****response。所以来说,message是用来定义参数的,有多少个参数,就有多少个message,比如说你定义了两个porttype,每个porttype中都有一个input,一个output。那么可以预见的是,如果你不进行更改,则是下面的形式,NewOperationRequest1,NewOperationRequest2,NewOperationResponse1,NewOperationResponse2。比如,NewOperationRequest1中有两个part,也就是代表在这个请求中有两个参数。也就是在part中可以使用上面定义的Types,但是我没有看到,都还是用命名空间中的类型来直接定义的。
一个是<message>元素中的每个<part>子元素都和某个参数相符。输入参数在<message>元素中定义,与输出参数相隔离--输出参数有自己的<message>元素。兼作输入、输出的参数在输入输出的<message>元素中有它们相应的<part>元素。输出<message>元素以"Response"结尾,就像以前所用的"fooResponse"。每个<part>元素都有名字和类型属性,就像函数的参数有参数名和参数类型。
用于交换文档时,WSDL允许使用<message>元素来描述交换的文档。
<part>元素的类型可以是XSD基类型,也可以是SOAP定义类型(soapenc)、WSDL定义类型(wsdl)或是Types栏定义的类型。
3.portType
可以将portType看成是一个服务,而wsdl就是一个服务的集合。wsdl中没有单独定义operation元素,operation直接包含在portType中了。一个portType中可以包括多个operation。一个operation又可以包括多个message,一个message又可以包括多个part。可以将portType看作一个类。而operation就是其中的函数。message是参数组,part是其中具体的参数。
name指定的定义为服务端口的名称。然后可以定义在该端口上执行的操作wsdl:operation,该wsdl:operation包括输入和输出两项操作。
4.binding
就是上面的那个小方框。指定端口定义消息格式和协议细节。
这部分将服务访问点的抽象定义与SOAP HTTP绑定,描述如何通过SOAP/HTTP来访问按照前面描述的访问入口点类型部署的访问入口。其中规定了在具体SOAP调用时,应当使用的 soapAction是"soapAction="http://www.aagtest.org/aae/NewOperation1",而请求/响应消息的编码风格都应当采用SOAP 规范默认定义的编码风格" http://schemas.xmlsoap.org/soap/encoding/"。这里需要注意的是soapAction中的命名空间http://www.aagtest.org/aae/是在点击空白是的那个命名空间。也就是definition中的targetnamespace。
5.service
指明了服务的名称及其端口和地址等信息,
<wsdl:service name="aaservice">
<wsdl:port binding="tns:aaeSOAP" name="aaeSOAP">
<soap:address location="http://www.example.org/"/>
</wsdl:port>
</wsdl:service>
名为aaservice的Web服务中,提供了一个服务访问入口,访问地址是"http://www.example.org/",使用的消息模式是由前面的binding所定义的。
在上面五个元素中,types,message,porttype是抽象类型,而binding是将它们和具体的实现联系在一起,service是将binding和用户访问的接口联系在一起,可以使用http协议来进行访问。
以我在eclipse下面所做的实验,一个service只能和一个binding在一起,一个binding只能连接一个porttype,但是一个porttype下面可以有多个operation。