由SOAP说开去 - - 谈谈WebServices、RMI、RPC、SOA、REST、XML、
发布时间:2020-12-16 22:12:57 所属栏目:安全 来源:网络整理
导读:标签: 引子: 关于SOAP其实我一直模模糊糊不太理解,这种模模糊糊的感觉表述起来是这样: 在使用web服务时(功能接口),本来我就可以通过安卓中固有的http类(使用http协议),来发送http请求,并且解析返回的数据(一般是xml或者json),得到我要的结果
标签:
引子:
关于SOAP其实我一直模模糊糊不太理解,这种模模糊糊的感觉表述起来是这样:
于是我详细查阅了网上的资料,结合自己的理解,归纳整理如下,引用部分过于零散,就未标示,还请谅解
?
要好好谈SOAP,就必须从其源头开始,它的源头就是WebServices(Web服务)
1.Web服务
最早的软件都是本地软件,只运行在本地电脑上,直到网络技术诞生它也只是利用网络传送资料,这之后网络技术独自发展网页WEB自己发展了好多年,直到大家发现网络技术不只是用来看看网页,还可以把网络技术更深地应用进本地软件中,深入地跟本地软件的功能结合,拓展本地软件的功能,Web服务的概念就是在这种环境下兴起的。
Web服务 简单地说,,就是服务器如何向客户端提供服务,现有的实现方式可以分为三类:
1.1.其他相关概念
RMI
2.SOA
SOA 是前几年炒的很火的一个词,不亚于当前的 Cloud Computing,如果说 RPC 是基于方法调用(method),那么 SOA 则是基于 消息,基于方法调用通常会与特定的程序语言 耦合起来,而后者则与具体的实现语言无关,所以在一定程度上得到大公司的支持
3.RPC
3.1总览:
3.2.实现方式:
3.3.其他相关概念
yar
yar是PRC的一个框架,类似webservice的,可以远程调用方法,返回的数据不单单是字符串,可以是数组等类型。
比方说,当你的项目非常庞大的时候,有些公用的模块就需要对外提供接口。
1、可以用curl方式调用,接口返回xml格式、或者json格式的字符串,调用方自己去解析。
2、可以用使用yar写的方法,直接返回结果,就跟调用代码本身的方法一样,可以返回字符串、数组等格式。
Web服务描述语言-WSDL
WSDL(Web Services Description Language)是描述web服务的,是描述怎样访问web服务的。WSDL是用来描述SOAP的,换句话说,WSDL 文件告诉你调用 SOAP 所需要知道的一切。WSDL也是一段xml。现在各个语言对wsdl的支持都很成熟,可以根据同一份wsdl文件生成自己语言的客户端。
为了创建一个用于描述Web服务的XML格式化文件,Web服务描述语言(WSDL)标准提供了足够多的细节,以便能够构建出客户端代码,从而访问服务或者服务器端代码以提供服务。一个服务的WSDL文件将会为你提供以下几个方面的内容:
2001 年3月,W3C推出了WSDL 1.1版本用于讨论,这并不是最终确定的规范。W3C Web服务描述工作组目前正在开发该规范的2.0版本,基本上已经到了尾声。虽然,WSDL通常是用于特定的SOAP服务,但是,从理论说,它是完全可以 用于特定的REST风格的GET或者POST操作的。
能够根据服务的WSDL描述来自动创建客户端和服务器端代码,支持这一功能的开发环境目前使用得很广泛,以便能够适用于Web服务器和Web服务客户端的 不同程序设计语言。如果你使用Google搜索“SOAP IDE”的话,大概会出现上百万条相关信息。也有这样的工具,根据Java或C#对象来生成相应的WSDL和代码。自动生成代码也许能够使你的开发效率更 高,但是离优化却是越来越远。
SOAP数据包结构解析
SOAP的消息被称为一个SOAP Envelope,包括SOAP Header和SOAP Body。其中,SOAP Header可以方便的插入各种其它消息来扩充Web Service的功能,比如Security(采用证书访问Web Service),SOAP Body则是具体的消息正文,也就是Marshall后的信息。
SOAP调用的时候,也就是向一个URL(比如 http://api.google.com/search/beta2 )发送HTTP Post报文(根据SOAP规范,HTTP Get报文也可被支持),调用方法的名字在HTTP Request Header SOAP-Action中给出,接下来就是SOAP Envelope了。服务端接到请求,执行计算,将返回结果Marshall成XML,用HTTP返回给客户端。
4.REST
4.1.概念:
4.1.推导REST
先从理论层次上我们看一下REST是怎么推导来的(参考论文第五章)
? ? ? ? ?Web架构背后的设计基本原理,能够被描述为由一组应用于架构中元素之上的约束组成的架构风格。当将每个约束添加到进化中的风格时,会产生一些影响。通过检查这些影响,我们就能够识别出Web的约束所导致的属性。然后就能够应用额外的约束来形成一种新的架构风格,这种风格能够更好地反映出现代Web架构所期待的属性。通过简述REST作为架构风格的推导过程,后面各节将会详细描述组成REST风格的各种特定约束
? ? ?0. ? 从“空”风格开始。从架构的观点来看,空风格描述了一个组件之间没有明显边界的系统,这就是我们描述REST的起点。
4.2.REST风格/约束:
Fielding 在他的论文中提出了一个RESTful应用应该具备的几点约束。
Fielding 认为,只有具备了上面的约束的应用才能算是REST应用,其实现在许多所谓的REST应用或服务,其实并不能算是真正的REST应用,目前很多所谓的REST应用,其实只是RPC而已。出现这样的情况很正常,因为RPC更符合一般程序员的思维。
之后这几个约束被表述为:
看了这几个特征后,你想起了什么? 你可能会破口而出:HTTP
HTTP是WWW的最核心的协议,它将简单的分布于世界各个角落的资源都统一起来,统一的地址,简单的方法,和一定数量的表达方式.(你可能对这三点描述很模糊,请go ahead).
REST 的三个要素就是是 唯一的资源标识,简单的方法 (此处的方法是个抽象的概念),一定的表达方式.
REST 是以 资源 为中心,名词即资源的地址,动词即施加于名词上的一些有限操作,表达是对各种资源形态的抽象.
以HTTP为例,名词即为URI(统一资源标识),动词包括POST,GET,DELETE等(还有其它不常用的2个,所以 整个动词集合是有限的),资源的形态(如text,html,image,pdf等)
根据以上的描述,我们其实发现HTTP是一种典型的REST风格,这也难怪,在1994年提出REST风格时,REST被称作“HTTP对象模型”,但是那个名称常常引起误解,使人们误以为它是一个HTTP服务器的实现模型。这个名称“表述性状态转移”是有意唤起人们对于一个良好设计的Web应用如何运转的印象。反过来看HTTP就是REST的具体实现。在一个REST风格中,我们能够感受到的就是统一接口的数据,这些数据包括所以,当我们开发一个web服务时,比如一个网站,由于使用了HTTP(HTTPS)协议,其实就是一种REST风格,但是在这个REST风格中我们着重处理的是两点
? ? ? ?1:URI,即所谓的资源,网站的uri设计
? ? ? ?2:统一接口,即所谓的PUT,DELETE方法
虽然我们的网站是REST的风格的,但是由于统一接口设计的不好,导致我们网站在访问请求时,效率低下,以及可扩展性差。在深入浅出REST中,作者总结了五条关键原
? ? ? ? 1:为所有“事物”定义ID
? ? ? ? 2:将所有事物链接在一起
? ? ? ? 3:使用标准方法
? ? ? ? 4:资源多重表述
? ? ? ? 5:无状态通信
其中前四条就是对统一接口中的数据元素,第一二条讲的就是uri,第三四条讲的是控制数据。第五条无状态通信,这个需要特别说明下,无状态通信是指服务器和客户端通信是无状态的,假如我们的系统中使用Session保存客户端状态,这种情况就是非无状态通信,是一种unREST的方式。但是应用本身是有状态的,比如用户登录前后,就是应用状态的变化。
4.3.REST与WEB
Fielding指出,使用且符合代表性状态传输(REST)设计约束的 Web 上部署的组件,可以充分利用 Web 的有用特性,万维网(World Wide Web)才能够达到最佳的工作效果。可以这样理解REST——当一个浏览器得到并且显示构成HTML页面的各个元素时,它正在获取资源的当前状态的表现形式。在Fielding的博士论文中,他列举了REST风格的设计约束,并且解释了为什么这些约束能够充分利用Web 的有用特性,使其达到最佳状态,以及这些约束的关键所在。同时,在论文中,他也包含了一些关于REST和某些目前的Web风格之间 “不符合”的讨论,以及这些Web风格是如何导致设计无法利用Web特性的。
Fielding认为,对于使用HTTP承载应用程序协议穿越防火墙,XML-RPC 和SOAP所采用的方式是“从根本上被误导的概念。”它们所采用的方式违背了设立防火墙的概念,结果是,防火墙厂商为了保护系统需要侦察出所承载的协议。由于大多数SOAP应用程序使用HTTP都是为了穿越防火墙,因此,你可以发现REST与SOAP之间的冲突是从哪里开始的。Fielding认为,如果你打算使用HTTP的话,就应该与充分利用HTTP本身的含义。
REST风格强调,通过有限的操作或者是“动词”以及一个组件之间的标准接口,也就是HTTP协议提供的借口,来提升客户与服务之间的交互。通过为每一个资源分配其自己的URL,来实现灵活性,REST可以调用包含上百个URI的资源类型的客户,其中的关键是REST能够给你无限多的“名词”。REST使用HTTP的动词——简单的良定义操作集:POST,DELETE进行请求和响应,从而避免了歧义。举个例子,GET只能够简单地返回资源的表现形式,而不能够创建任何其他的内容。
在Web发展的初期,由于人们都在试验通过收集各种不同来源的元素,从而把Web应用程序融合在一起,有大量这种Web服务的不成熟探索的例子——从HTTP页面中解析信息,用于页面创建者没有计划到的用途。这种“屏幕抓取”的Web类比表明,REST风格的方法是先于那些更加复杂的Web服务而出现的。
4.4.规划REST服务
在InfoQ上有一篇很好的文章来介绍如何规划REST服务《如何获取(GET)一杯咖啡——星巴克REST案例分析》,估计大家看完这篇文章,应该对如何规划REST服务会有更深的认识。
当我们要规划REST服务的时候,其中最关键的概念是“资源”。
资源是什么呢?广义上讲,任何事物只要有用,它就是资源。狭义的讲(在Web环境中),它是一个可以存放、连接在计算机上,可以通过比特流进行操控的实体。一个实体若要成为资源,它必须有一个URI。在这里URI包含了两重含义:1)它是该资源的名称 2)它是该资源的地址。
在规划URI的时候,有几点希望大家能够注意一下:
当我们定义好资源之后,接下来要做的事情就是定义操作资源的方法以及资源的表述格式了。
使用HTTP提供的基本方法来对资源进行操作,一般的操作定义如下:POST(创建资源)、GET(获取资源)、PUT(修改资源)、DELETE(删除)。它们正好对应了CRUD。
对资源的表述,一般的选择会是XML,但是我更加推荐使用JSON来表述资源。在网络中的传输量小,而且也便于JavaScript解析,同时使用其他语言解析也是非常方便的事情。不过,最关键的还是占用更少的资源,让同样的资源能够服务于更多的人。
4.5.一个简单的REST举例
假设我们希望一个Web服务暴露一部分目录,从这个目录中,用户将能够得到一些描述、图片、安装指令等等。为了得到数字“n1996-01”的描述,用户需要格式化一个GET请求,类似于下面的这个URL: http://company.com/catalog/description/n1996-01
在处理这个请求时,“/catalog”将映射到一个服务中,之后,通过该服务对“description/n1996-01”进行解释,从而 定位资源。在创建响应时,服务需要使用内容类型(Content-Type)的头文件来指定返回格式。在这种情况下,假定返回格式是HTML或者XML, 客户端能够使用它来控制页面的布局。如果要得到图片,那么这个请求将对“/catalog/picture/n1996-01”进行寻址,返回的响应将是 图片内容类型(Content-Type)。
4.6.REST的应用场景:
其实,我们经常容易犯的一个错误是:当我们了解了一个新的技术,就会用这个技术来解决所有的问题。有一句谚语是这么来说的:“在锤子的眼里,所有的东西都是钉子”,其实REST也只是我们工具箱里面的其中的一个工具而已,希望不要把它当做我们唯一的工具。下面,我们就来聊聊适合使用REST的应用场景和不适合使用REST的应用场景。
在我看来,REST最适合的应用场景是需要对外暴露服务的情况。此时,我们可以充分利用REST的自描述、无状态、唯一标识等特性来提供清晰、友好的API;此外,目前Jesery、RESTEasy等JAX-RS框架也提供了OAuth的支持,基本上能够保证服务安全。
最不适合的应用场景是对性能要求高的系统内部的服务调用,在这种情况下使用REST的话,那么REST所有的特性都会变成拖累。这个时候,还是需要选择更底层的通信协议和方式会更好一些,比如ICE。这样的错误,我曾经犯过,后来通过很长时间的努力才慢慢的将这个错误改过来。
4.7.RPC与REST的比较
如何选择?
根据笔者自己的经验和心得,建议 能够使用REST就尽量使用REST,主要基于下面几个考虑:
当然上述的几点也并非 RPC 都不满足,不过相对而言,REST 更加清晰和简洁,再辅以 JSON 相应的服务会在性能和稳定性(简单通常意味着robust)方面有很大的提高.
总体上,因为REST模式的Web服务与复杂的SOAP和XML-RPC对比来讲明显的更加简洁,越来越多的web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务进行图书查找;雅虎提供的Web服务也是REST风格的。REST对于资源型服务接口来说很合适,同时特别适合对于效率要求很高,但是对于安全要求不高的场景。而SOAP的成熟性可以给需要提供给多开发语言的,对于安全性要求较高的接口设计带来便利。所以我觉得纯粹说什么设计模式将会占据主导地位没有什么意义,关键还是看应用场景,正是那句老话:适合的才是最好的
同时很重要一点就是不要扭曲了REST现在很多网站都跟风去开发REST风格的接口,其实都是在学其形,不知其心,最后弄得不伦不类,性能上不去,安全又保证不了,徒有一个看似象摸象样的皮囊。
4.8.soap与REST比较:
造成SOAP和REST放在一起讨论是因为,网络上很多工程师把REST风格和REST的实现混淆了。REST的概念比较宽泛,本身如果符合1)Client–server,2)Stateless,3)Cacheable,4)Layered system,和5)Uniform interface这几个主要的限制,就是RESTful的设计。同时呢,由于HTTP是一个很容易满足stateless,cacheable,uniform interface的protocol,所以实际上REST被默认就是用HTTP来实现,很多人耳熟能详HTTP的verb如何对应到resource的CRUD,仿佛也成了REST风格本身的死规定。我认为其实不然,以HTTP中的PUT为例,如果用PUT来实现resource的update,那么就必须要保证idempotent,每次传给server的信息,必须是resource的全部信息,不能作partial update。不难发现,用PUT来实现update,其实是在REST的constraint上又加上了HTTP的一些限制。如果我们放弃PUT的constraint,采用POST来实现update,则partial update是可以的。紧接着就由一个问题,既然PUT被POST替代,那么我们是否可以用POST来代替GET和DELETE呢?笔者认为应该没问题,一个很现实的例子,如果browser不支持DELETE,用POST来work around是很常见的。
okay,再来看看SOAP,很多在HTTP上实现的SOAP协议就是用POST来实现的 (wikipedia里SOAP的一个sample http://en.wikipedia.org/wiki/SOAP#Example_message)
因此,当我们使用HTTP POST来实现REST,再加上XML的数据传输格式,其实我们就是在SOAP上面实现了RESTFul的"风格"(尽管还网上没人提到RESTful SOAP,但我觉得这在理论上是没问题的)。
与RESTful SOAP相对的一个例子,很多基于Rails的website(并非说Rails不好,Rails大行其道使得REST风行,故举例)URL风格是/callSomeMethodWithArgumentA,/callSomeMethodWithArgumentB,非常长,不uniform,不满足REST的限制,这些route都是不RESTFul的,我们可以称之为non-RESTful HTTP
长话短说,本人认为SOAP协议和REST架构风格是兼容的。虽然,约定俗成,REST的具体实现一般采用HTTP,且充分利用HTTP verb的不同特性,从而形成了一些约定俗称的范式,但这种实现本身不是REST"风格"的核心。
目前,大部分Web开发者似乎都了解REST——一种采用标准URI进行调用的方案。REST很容易理解,而且只要是支持HTTP/HTTPS的客户端/服务器就支持它。你可以用HTTP GET方法来执行命令。所以,开发者们感受到的REST的优势是:开发简单、只需依托现有Web基础设施、以及学习成本低。
然而,SOAP作为一种古老的Web服务技术,短期内还不会退出历史舞台。而且,随着SOAP 1.2的出现,SOAP印象中的一些缺点已得到改进,采纳率和易用程度也都得到提高。另需注意的是,从W3C SOAP 1.2版开始,SOAP这一缩写不再代表Simple Object Access Protocol(简单对象访问协议),而是仅仅作为协议名称而已。
相对REST而言,SOAP 1.2多出一些开销,不过这些开销也带来了一些好处。首先,SOAP在三个方面离不开XML(Extensible Markup Language,可扩展标记语言):SOAP信封(envelope)是基于XML的,它定义了消息里有什么以及如何处理它;一套用于数据类型的编码规则;过程调用和响应的规划。SOAP信封由传输协议(HTTP/HTTPS)发出,RPC(Remote Procedure Call,远程过程调用)得到执行,然后一个XML文档随SOAP信封返回。
需要注意的是,基于“通用”传输协议是SOAP的一个优点。REST目前基于HTTP/HTTPS;而SOAP可支持任何传输协议,从HTTP/HTTPS到SMTP(Simple Mail Transfer Protocol,简单邮件传送协议),甚至JMS(Java Messaging Service,Java消息传递服务)。不过,由于XML较为冗长且解析费时,因此采用XML也成为一个弊端。
不过,对Web开发者来说的好消息是,目前上述两种方案都是行之有效的方案。REST和SOAP都能解决许多Web方面的问题与挑战,而且在许多情况下,它们各自都能满足开发者的要求,也就是说可互换使用。
但很多人不知道,这两种技术可以混合搭配使用。REST很好理解,且极易上手;不过由于它缺乏标准,因此只被看作是一种架构方法。与之相比,SOAP是一个工业标准,它具备良好定义的协议,以及一套良好确立的规则,在大型和小型系统中均有采用。
因此,REST的适用场合包括:
有限的带宽和资源 别忘了返回的结构可以采用(由开发者定义的)任何格式。另外,由于REST采用标准的GET、PUT、POST和DELETE动词,因此可被任何浏览器所支持。除此以外,REST还可以使用为目前大多数浏览器支持的XMLHttpRequest对象,这为AJAX增色不少。
完全无状态的操作 对于那些需多步执行的操作,REST并非最佳选择,采用SOAP更合适。但是,如果你需要无状态的CRUD(Create/Read/Update/Delete,创建/读取/更新/删除)操作,那么应采用REST。
缓存考虑 若要利用无状态操作的特性,使得信息可被缓存,那么REST是很好的选择。
以上已经覆盖很多方案了,那么,为什么还要考虑SOAP呢?正如前述,SOAP比较成熟而且是经过良好定义的,具有完整的规范。而REST只不过是一种方法,对开发未作任何规约;因此,假如你遇到以下场合,那么SOAP是最佳选择:
异步处理与调用 如果你的应用需要确保可靠性与安全性,那么请采用SOAP。SOAP 1.2为确保这种操作补充定义了WSRM(WS-Reliable Messaging)等标准。
形式化契约 若提供者/消费者双方必须就交换格式取得一致,那么采用SOAP更合适。SOAP 1.2为这种交互提供了严格的规范。
有状态的操作 如果应用需要上下文信息与对话状态管理,那么应采用SOAP。SOAP 1.2为此补充定义了WS-Security、WS-Transactions和WS-Coordination等标准。相比之下,REST方法要求开发者自己来实现这些框架性工作。
正如你所看到的,REST和SOAP各自有其用武之地。它们在安全性和传输层等方面有着自己的潜在问题,不过它们都能完成任务,而且在许多情况下,它们都丰富了Web的技术手段。因此,就这一论题,其实最好的原则就是灵活性原则;因为至少在现今的Web开发中,无论面对何种问题,Web开发者们总有办法运用好这两种技术中的一种。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |