Web Service笔记(三):wsdl 与 soap协议详解

注:1、结合Web
Service笔记(二):利用CXF开发Web Service

一、WSDL语言:(web service definition language - web service定义语言)

(一)简介:

1、wsdl 是全完基于xml 的,特别是xml schema。详见: XML学习笔记(三):XML规范:Schema详解

2、wsdl 文档描述了 ws 主要的3个方面:

1)WHATA:该 ws 包含”什么“操作,即有几个方法。

2)HOW:该 ws 的操作应该”怎样“调用?

3)WHERE:该 ws 的服务地址。

3、详细的 wsdl 文件如下,给予Web
Service笔记(二):利用CXF开发Web Service
 的服务和客户端。

1)实现类的 wsdl 地址为:http://localhost:8080/helloWorld?wsdl 。内容如下:

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://impl.ws.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://ws.com/" name="HelloSAM" targetNamespace="http://impl.ws.com/">
<wsdl:import location="http://localhost:8080/helloWorld?wsdl=HelloWorld.wsdl" namespace="http://ws.com/"></wsdl:import>
<wsdl:binding name="HelloSAMSoapBinding" type="ns1:HelloWorld">
<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>
</wsdl:operation>
<wsdl:operation name="getCatsByUser">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getCatsByUser">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getCatsByUserResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloSAM">
<wsdl:port binding="tns:HelloSAMSoapBinding" name="HelloWorldImplPort">
<soap:address location="http://localhost:8080/helloWorld"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

2)接口的 wsdl 地址为:http://localhost:8080/helloWorld?wsdl=HelloWorld.wsdl 。内容如下:

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://ws.com/" name="HelloWorld" targetNamespace="http://ws.com/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.com/" elementFormDefault="unqualified" targetNamespace="http://ws.com/" version="1.0">
<xs:element name="getCatsByUser" type="tns:getCatsByUser"/>
<xs:element name="getCatsByUserResponse" type="tns:getCatsByUserResponse"/>
<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:complexType name="getCatsByUser">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="tns:user"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="user">
<xs:sequence>
<xs:element minOccurs="0" name="address" type="xs:string"/>
<xs:element minOccurs="0" name="id" type="xs:int"/>
<xs:element minOccurs="0" name="name" type="xs:string"/>
<xs:element minOccurs="0" name="pass" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getCatsByUserResponse">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="tns:cat"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="cat">
<xs:sequence>
<xs:element minOccurs="0" name="color" type="xs:string"/>
<xs:element minOccurs="0" name="id" type="xs:int"/>
<xs:element minOccurs="0" name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="getCatsByUserResponse">
<wsdl:part element="ns1:getCatsByUserResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="sayHiResponse">
<wsdl:part element="ns1:sayHiResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="getCatsByUser">
<wsdl:part element="ns1:getCatsByUser" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="sayHi">
<wsdl:part element="ns1:sayHi" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="HelloWorld">
<wsdl:operation name="sayHi">
<wsdl:input message="ns1:sayHi" name="sayHi"></wsdl:input>
<wsdl:output message="ns1:sayHiResponse" name="sayHiResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="getCatsByUser">
<wsdl:input message="ns1:getCatsByUser" name="getCatsByUser"></wsdl:input>
<wsdl:output message="ns1:getCatsByUserResponse" name="getCatsByUserResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>

(二)语法详解:

1、根元素:definitions

1)targetNamespace :相当于java的 package 。

如 服务端实现类与 wsdl 文件的 targetNamespace 为 如下,应该是一致的。

package com.ws.impl;//实现类的包
targetNamespace="http://impl.ws.com/"//wsdl的targetNamespace

2)xmlns :遵守的命名空间的schema 文件,相当于java的 import 。即本文档引进了这个schema规范,需要遵守它的语法。可以有别名,用来区分引进不同的schema规范。

xmlns:xsd="http://www.w3.org/2001/XMLSchema"//xsd为别名

3)import :导入的接口文件。通过 namespase的路径也可以看出。

<wsdl:import location="http://localhost:8080/helloWorld?wsdl=HelloWorld.wsdl" namespace="http://ws.com/"></wsdl:import>

2、WS接口的wsdl语法。wsdl 显示的服务端内容都在此。

1)types元素 :该元素内容是标准的xml Schema文档 。

<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.com/" elementFormDefault="unqualified" targetNamespace="http://ws.com/" version="1.0">
<xs:element name="getCatsByUser" type="tns:getCatsByUser"/>
<xs:element name="getCatsByUserResponse" type="tns:getCatsByUserResponse"/>
<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:complexType name="getCatsByUser">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="tns:user"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="user">
<xs:sequence>
<xs:element minOccurs="0" name="address" type="xs:string"/>
<xs:element minOccurs="0" name="id" type="xs:int"/>
<xs:element minOccurs="0" name="name" type="xs:string"/>
<xs:element minOccurs="0" name="pass" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getCatsByUserResponse">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="tns:cat"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="cat">
<xs:sequence>
<xs:element minOccurs="0" name="color" type="xs:string"/>
<xs:element minOccurs="0" name="id" type="xs:int"/>
<xs:element minOccurs="0" name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>

2)message元素:有2N个message元素,需要有传入传出消息。如服务端方法public String sayHi(String name){}方法:

<wsdl:message name="getCatsByUserResponse">
<wsdl:part element="ns1:getCatsByUserResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="sayHiResponse">
<wsdl:part element="ns1:sayHiResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="getCatsByUser">
<wsdl:part element="ns1:getCatsByUser" name="parameters"></wsdl:part>
</wsdl:message>
<span style="color:#ff0000;"><wsdl:message name="sayHi">
<wsdl:part element="ns1:sayHi" name="parameters"></wsdl:part>
</wsdl:message></span>

①、message 元素中有name等于 sayHi 的属性。可以理解为 一个 sayHi 的消息。

②、子元素 part中有element属性为 sayHi 。理解为 sayHi的消息需要一个 sayHi 的元素(element)。这个元素在上面的 type 中会有定义。

3)portType元素: N个operation子元素,每个operation代表一个ws操作(即方法),包含请求与回复2次。

<wsdl:portType name="HelloWorld">
<wsdl:operation name="sayHi">
<wsdl:input message="ns1:sayHi" name="sayHi"></wsdl:input>
<wsdl:output message="ns1:sayHiResponse" name="sayHiResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="getCatsByUser">
<wsdl:input message="ns1:getCatsByUser" name="getCatsByUser"></wsdl:input>
<wsdl:output message="ns1:getCatsByUserResponse" name="getCatsByUserResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>

①、服务端有两个操作的方法 sayHi() 和 getCatsByUser() ,在 portType 元素中就会有 2个 operation ,分别为 sayHi 和 getCatsByUser 。

②、每个 operation元素中有input 和 output 子元素,定义了这次操作需要的 message元素信息,在上面定义。

4)显而易见,这边有一定的依赖关系存在:一个 WS 服务端实现类,定义了多个方法(operation元素),方法的调用需要明确传入传出参数,被定义在message元素中,称为消息。每个定义的消息有依赖于element元素,定义在 types 中,是一份标准的 schema。

5)整个接口的 wsdl 由于上述依赖的关系,可以倒过来分析:如方法public List<Cat> getCatsByUser(User user) {},其实其本质规定了调用该方法传入参数的类型与规范。

①、一个接口,定义方法为 getCatsByUser。wsdl 定义为:一个 portType 为 HelloWorld 的接口,有名为 getCatsByUser 的 operation,即有这个方法可调用。这个方法需要name为 getCatsByUser  和 getCatsByUserResponse 的 message 元素(input 和 output ),代表了这个方法的传入与传出消息(即方法的参数)。

②、方法的传入传出参数。message 元素中规定这个 getCatsByUser  的传入消息实际内容在名为 getCatsByUser 的element元素中,element元素定义在types元素中。

③、element元素中规定 getCatsByUser  遵守名字为getCatsByUser  的schema语法定义,使用type关键字实现sechema语法的复用。

④、名字为 getCatsByUser  的 schema定义为:complex为复杂类型,0-1个,sequesce指要有顺序,type指向名字为 user 的schema定义。

⑤、名字为 user 的 schema定义为: 有顺利的四个元素,分别为address、id、name、pass,出现0-1次。

4、本质:一个ws,其实并不是方法的调用,而是发送soap消息(即xml文档片段)

1)客户端把调用的方法参数,转换生成xml文档片段(soap消息)——必须符合wsdl规定的格式

2)客户端通过网络,把xml文档片段传给服务器。

3)服务器接收到xml文档片段。

4)服务器解析xml文档片段,提取其中的数据。返回xml文档。

如getCatsByUser(User user) 方法,传入传出的是这样的xml片段:

<!--传入的参数-->
<getCatsByUser>
	<arg0>
		<address></address>
		<id></id>
		<name></name>
		<pass></pass>
	</arg0>
</getCatsByUser>

<!--返回的参数-->
<getCatsByUserResponse>
	<return>
		<color></color>
		<id></id>
		<name></name>
	</return>
	<return>
		<color></color>
		<id></id>
		<name></name>
	</return>
</getCatsByUserResponse>

3、WS实现类:

1)、binding:指定ws的函数风格,并详细的定义了接口中的操作即 operation 。函数风格,现在一般为 document 文档风格。

<wsdl:binding name="HelloSAMSoapBinding" type="ns1:HelloWorld">
<soap:binding <span style="color:#ff0000;">style="document" </span>transport="http://schemas.xmlsoap.org/soap/http"/>
<<span style="color:#ff0000;">wsdl:operation </span>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>
</wsdl:operation>
<wsdl:operation name="getCatsByUser">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getCatsByUser">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getCatsByUserResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>

2)、service:name-定义了ws的名称,即代码中使用 serviceName 指定的名称,port【address】-定义ws绑定的地址。

<wsdl:service name="HelloSAM">
<wsdl:port binding="tns:HelloSAMSoapBinding" name="HelloWorldImplPort">
<soap:address location="http://localhost:8080/helloWorld"/>
</wsdl:port>
</wsdl:service>

二、SOAP语言(简单访问对象协议)

(一)通过使用CXF的日志拦截器,我们可以在控制台输出拦截器的soap消息。服务端拦截如下:

1、sayHi()操作的soap消息:

传入:

Headers:
		{Accept=[text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2],
		connection=[keep-alive],
		Content-Length=[186],
		content-type=[text/xml; charset=UTF-8],
		Host=[localhost:8080],
		SOAPAction=[""],
		User-Agent=[Java/1.6.0_10-rc2]}

Payload:
		<?xml version="1.0" ?>
		<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
			<S:Body>
				<ns2:sayHi xmlns:ns2="http://ws.com/">
					<arg0>SAM-SHO</arg0>
				</ns2:sayHi>
			</S:Body>
		</S:Envelope>

传出:
	Headers: {}
	Payload:
		<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
			<soap:Body>
				<ns2:sayHiResponse xmlns:ns2="http://ws.com/">
					<return>SAM-SHO,您好!您现在访问的是简单的WS服务端,时间为:14-11-20 下午1:28</return>
				</ns2:sayHiResponse>
			</soap:Body>
		</soap:Envelope>

2、getCatsByUser()操作的soap消息:与上面wsdl分析的消息应该是一致的。

传入:

<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
	<S:Body>
		<ns2:getCatsByUser xmlns:ns2="http://ws.com/">
			<arg0>
				<address>soochow</address>
				<id>1</id>
				<name>Sam-Sho</name>
				<pass>1234</pass>
			</arg0>
		</ns2:getCatsByUser>
	</S:Body>
</S:Envelope>

传出:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns2:getCatsByUserResponse xmlns:ns2="http://ws.com/">
			<return>
				<color>黄色</color>
				<id>1</id>
				<name>加菲猫</name>
			</return>
			<return>
				<color>蓝色</color>
				<id>2</id>
				<name>蓝胖子</name>
			</return>
			<return>
				<color>粉色</color>
				<id>3</id>
				<name>hello kitty</name>
			</return>
			<return>
				<color>黑白色</color>
				<id>4</id>
				<name>熊猫</name>
			</return>
		</ns2:getCatsByUserResponse>
	</soap:Body>
</soap:Envelope>

(二)soap语法

	<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
			<soap:Header>
				<!--可能会有Header元素-->
			</soap:Header>
			<soap:Body>
				<ns2:sayHiResponse xmlns:ns2="http://ws.com/">
					<return>SAM-SHO,您好!您现在访问的是简单的WS服务端,时间为:14-11-20 下午1:28</return>
				</ns2:sayHiResponse>
			</soap:Body>
		</soap:Envelope>

1、根元素:Envelope。

2、Header元素::不是强制出现,由程序员控制,主要用于携带一些额外的信息,比如用户名、密码

3、Body:

1)调用正确,body元素内容应该遵守WSDL要求的格式。

	<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
		<soap:Body>
			<ns2:sayHiResponse xmlns:ns2="http://ws.com/">
				<return>SAM,您好现在的时间是:Thu Jan 09 10:19:57 CST 2014</return>
			</ns2:sayHiResponse>
		</soap:Body>
	</soap:Envelope>

2)调用错误,body元素内容显示Faulty元素。

<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>
No binding operation info while invoking unknown method with params unknown.
</faultstring>
</soap:Fault>
</soap:Body>

4、return:返回信息。

三、UDDI(可以省略)

时间: 2024-11-06 21:20:31

Web Service笔记(三):wsdl 与 soap协议详解的相关文章

转-Web Service中三种发送接受协议SOA、http get、http post

原文链接:web服务中三种发送接受协议SOAP/HTTP GET/HTTP POST 一.web服务中三种发送接受协议SOAP/HTTP GET/HTTP POST 在web服务中,有三种可供选择的发送和接受信息的协议:SOAP,HTTP GET,HTTP POST,但是SOAP支持的数据类型更为广泛 SOAP=RPC+HTTP+XML SOAP简单的理解,就是这样的一个开放协议SOAP=RPC+HTTP+XML:采用HTTP作为底层通讯协议:RPC作为一致性的调用途径,XML作为数据传送的格式

Web Service 笔记-fkjava

========================第一讲======================= WebService概述 ===================================================== Web Service 不是框架,更甚至不是一种技术,而是一种跨平台,跨语言的规范. Web Service实际用途: 1.同一公司的新,旧系统的整合. 2.不同公司的业务整合. 3.内容聚合. CXF Axis(Apache) --> Axis2(Apache)

构建安全的Xml Web Service系列之初探使用Soap头

原文:构建安全的Xml Web Service系列之初探使用Soap头 Xml Web Service 从诞生那天就说自己都么都么好,还津津乐道的说internet也会因此而进入一个新纪元,可5年多来,Xml Web Service并没有像当初宣扬的那样火起来,尽管在一些领域之内,也有人牛刀小试,但从整体而言,Service还并没有得到广泛的应用,原因有很多,有一些来源于目前各大厂商都坚持自己的service标准,不能形成统一,也有对现有的稳定系统不愿进行更改的原因,但还包括web servic

Web Service笔记(五):CXF开发RESTful风格的Web Service

前言: 1.Web Service笔记(五):利用CXF结合Spring开发web service 2.XML学习笔记(三):Jaxb负责xml与javaBean映射 3.jax-rs详解 4.可以使用浏览器的工具调试:如 Firefox 的RESTClient 和chrome的REST Console. 一.配置Spring的配置文件 1.需要引入新的 jar 包. 2.配置 applicationContext-server.xml 文件.使用 jaxrs:server ,记得引入jaxrs

Http 协议详解笔记

HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出.HTTP协议的主要特点可概括如下:1.支持客户/服务器模式.2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径.请求方法常用的有GET.HEAD.POST.每

HTTP协议 (三) HTTP协议详解

HTTP协议详解 当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等. 无论Web技术在未来如何发展,理解Web程序之间通信的基本协议相当重要, 因为它让我们理解了Web应用程序的内部工作. 本文将对HTTP协议进行详细的实例讲解,内容较多,希望大家耐心看.也希望对大家的开发工作或者测试工作有所帮助.使用Fiddler工具非常方便地捕获HTTP Request和HTTP Response,  关于Fiddler工具的用法,请看我另一篇博客[Fid

IP协议详解

IP协议详解 前言 本屌今天可算是累坏了,一大早起来本来寻思赶快centOS虚拟机玩玩吧,那天刚装了系统,本来的虚拟机没了,今天想着先把centOS装上,结果给个系统不停的给我扯淡啊,显示虚拟机上不去网,好不容易上去网了,ping不通主机,主机ping不通虚拟机,各种办法都试了,最后我吧VMware8那块网卡禁用了,卧槽!!啥都好了,本屌一直鼓捣到晚上八点,从早晨10点多.服了我自己了. 引入 在前面的学习中,我们简单地IP接力和IP地址后,咱们今天具体的说说IP协议的具体细节和设计哲学. IP

http协议详解和httpd基本介绍

httpd是Apache超文本传输协议(HTTP)服务器的主程序.被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程的池. 要了解httpd就需要先了解下各种协议. http:Hyper Text Transfer Protocol,超文本传输协议 html:Hyper Text Mark Language,超文本标记语言 CGI:Common Gateway Interface,通用网关接口,http和程序解释器的链接协议 http协议版本: http 0.9: 仅用于传输ht

IP协议详解(转)

本文转载自博文协议森林05 我尽力 (IP协议详解).这篇博文写的很有趣味,特转载! IPv4与IPv6头部的对比 我们已经在IP接力中介绍过,一个IP包分为头部(header)和数据(payload/data)两部分.头部是为了实现IP通信必须的附加信息,数据是IP通信所要传送的信息. 黄色区域 (同名区域) 我们看到,三个黄色区域跨越了IPv4和IPv6.Version(4位)用来表明IP协议版本,是IPv4还是IPv6(IPv4, Version=0100; IPv6, Version=0