话说移动4G+普遍吗

Web&Service&与&RESTful&Web&Service比较(转)
REST ful Web Service是什么?
REST是一种架构风格,其核心是面向资源,REST专门针对网络应用设计和开发方式,以降低开发的复杂性,提高系统的可伸缩性。REST提出设计概念和准则为:
1.网络上的所有事物都可以被抽象为资源(resource)
2.每一个资源都有唯一的资源标识(resource identifier),对资源的操作不会改变这些标识
3.所有的操作都是无状态的
&REST简化开发,其架构遵循CRUD原则,该原则告诉我们对于资源(包括网络资源)只需要四种行为:创建,获取,更新和删除就可以完成相关的操作和处理。您可以通过统一资源标识符(Universal
Resource Identifier,URI)来识别和定位资源,并且针对这些资源而执行的操作是通过 HTTP
规范定义的。其核心操作只有GET,PUT,POST,DELETE。
&由于REST强制所有的操作都必须是stateless的,这就没有上下文的约束,如果做分布式,集群都不需要考虑上下文和会话保持的问题。极大的提高系统的可伸缩性。
&对于SOAP Webservice和Restful
Webservice的选择问题,首先需要理解就是SOAP偏向于面向活动,有严格的规范和标准,包括安全,事务等各个方面的内容,同时SOAP强调操作方法和操作对象的分离,有WSDL文件规范和XSD文件分别对其定义。而REST强调面向资源,只要我们要操作的对象可以抽象为资源即可以使用REST架构风格。
&是否使用REST就需要考虑资源本身的抽象和识别是否困难,如果本身就是简单的类似增删改查的业务操作,那么抽象资源就比较容易,而对于复杂的业务活动抽象资源并不是一个简单的事情。比如校验用户等级,转账,事务处理等,这些往往并不容易简单的抽象为资源。
&其次如果有严格的规范和标准定义要求,而且前期规范标准需要指导多个业务系统集成和开发的时候,SOAP风格由于有清晰的规范标准定义是明显有优势的。我们可以在开始和实现之前就严格定义相关的接口方法和接口传输数据。
&简单数据操作,无事务处理,开发和调用简单这些是使用REST架构风格的优势。而对于较为复杂的面向活动的服务,如果我们还是使用REST,很多时候都是仍然是传统的面向活动的思想通过转换工具再转换得到REST服务,这种使用方式是没有意义的。
效率和易用性
SOAP协议对于消息体和消息头都有定义,同时消息头的可扩展性为各种互联网的标准提供了扩展的基础,WS-*系列就是较为成功的规范。但是也由于SOAP由于各种需求不断扩充其本身协议的内容,导致在SOAP处理方面的性能有所下降。同时在易用性方面以及学习成本上也有所增加。
REST被人们的重视,其实很大一方面也是因为其高效以及简洁易用的特性。这种高效一方面源于其面向资源接口设计以及操作抽象简化了开发者的不良设计,同时也最大限度的利用了Http最初的应用协议设计理念。同时,在我看来REST还有一个很吸引开发者的就是能够很好的融合当前Web2.0的很多前端技术来提高开发效率。例如很多大型网站开放的REST风格的API都会有多种返回形式,除了传统的xml作为数据承载,还有(JSON,RSS,ATOM)等形式,这对很多网站前端开发人员来说就能够很好的mashup各种资源信息
&技术没有好坏,只有是不是合适,一种好的技术和思想被误用了,那么就会得到反效果。REST和SOAP各自都有自己的优点,同时如果在一些场景下如果去改造REST,其实就会走向SOAP(例如安全)。
&REST对于资源型服务接口来说很合适,同时特别适合对于效率要求很高,但是对于安全要求不高的场景。而SOAP的成熟性可以给需要提供给多开发语言的,对于安全性要求较高的接口设计带来便利。所以我觉得纯粹说什么设计模式将会占据主导地位没有什么意义,关键还是看应用场景。
&同时很重要一点就是不要扭曲了REST现在很多网站都跟风去开发REST风格的接口,其实都是在学其形,不知其心,最后弄得不伦不类,性能上不去,安全又保证不了。
&SOAP虽然发展到现在已经脱离了初衷,但是对于异构环境服务发布和调用,以及厂商的支持都已经达到了较为成熟的情况。不同平台,开发语言之间通过SOAP来交互的web
service都能够较好的互通。
&由于没有类似于SOAP的权威性协议作为规范,REST实现的各种协议仅仅只能算是私有协议,当然需要遵循REST的思想,但是这样细节方面有太多没有约束的地方。REST日后的发展所走向规范也会直接影响到这部分的设计是否能够有很好的生命力。
简单对象访问协议(Simple Object Access
Protocol,SOAP)是一种基于&XML&的协议,可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME),基于“通用”传输协议是&SOAP的一个优点。它还支持从消息系统到远程过程调用(Remote
Procedure Call,RPC)等大量的应用程序。SOAP提供了一系列的标准,如WSRM(WS-Reliable
Messaging)形式化契约确保可靠性与安全性,确保异步处理与调用;WS-Security、WS-Transactions和WS-Coordination等标准提供了上下文信息与对话状态管理。
相对而言,SOAP协议属于复杂的、重量级的协议,当前随着Web2.0的兴起,表述性状态转移(Representational
State Transfer,REST)逐步成为一个流行的架构风格。REST是一种轻量级的Web
Service架构风格,其实现和操作比SOAP和XML-RPC更为简洁,可以完全通过HTTP协议实现,还可以利用缓存Cache来提高响应速度,性能、效率和易用性上都优于SOAP协议。REST架构对资源的操作包括获取、创建、修改和删除资源的操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法,这种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。REST架构尤其适用于完全无状态的CRUD(Create、Read、Update、Delete,创建、读取、更新、删除)操作。
基于REST的软件体系结构风格(Software Architecture
Style)称之为面向资源体系架构(Resource-oriented
Architecture,ROA)。按照REST原则设计的软件、体系结构,通常被称为“REST式的”(RESTful),在本文中以下称之为RESTful
Web服务,以便于和基于SOAP的Web服务区别。&
服务器端采用J2EE,客户端采用JSP、Flex、JavaFX、AIR等可以直接调用Servlet,其他的实现技术基本上不能直接调用,但是无论是那种客户端,对于基于SOAP的Web服务或者基于RESTful
Web服务务都是支持的,如AJAX的&XMLHttpRequest、Flex的HTTPService等。如下图所示:
客户端和服务器端的通讯方式&&&
HTTP 的 GET、HEAD 请求本质上应该是安全的调用,即:GET、HEAD
调用不会有任何的副作用,不会造成服务器端状态的改变。对于服务器来说,客户端对某一 URI 做 n 次的 GET、HAED
调用,其状态与没有做调用是一样的,不会发生任何的改变。
HTTP 的 PUT、DELTE 调用,具有幂指相等特性 , 即:客户端对某一 URI 做 n 次的 PUT、DELTE
调用,其效果与做一次的调用是一样的。HTTP 的 GET、HEAD 方法也具有幂指相等特性。
HTTP 这些标准方法在原则上保证你的分布式系统具有这些特性,以帮助构建更加健壮的分布式系统。
为了说明问题,基于上面的在线用户管理系统,我们给定以下场景:
参考一开始我们给出的用例图,对于客户端 Client2,我们只希望它能以只读的方式访问 User 和 User List 资源,而
Client1 具有访问所有资源的所有权限。
如何做这样的安全控制?
通行的做法是:所有从客户端 Client2 发出的 HTTP 请求都经过代理服务器 (Proxy
Server)。代理服务器制定安全策略:所有经过该代理的访问 User 和 User List 资源的请求只具有读取权限,即:允许
GET/HEAD 操作,而像具有写权限的 PUT/DELTE 是不被允许的。
如果对于 REST,我们看看这样的安全策略是如何部署的。如下图所示:
图 4. REST 与代理服务器 (Proxy
Servers)&&
一般代理服务器的实现根据 (URI, HTTP Method) 两元组来决定 HTTP 请求的安全合法性。
当发现类似于(http://localhost:8182/v1/users/{username},DELETE)这样的请求时,予以拒绝。
对于 SOAP,如果我们想借助于既有的代理服务器进行安全控制,会比较尴尬,如下图:
图 5. SOAP 与代理服务器 (Proxy
Servers)&&
所有的 SOAP 消息经过代理服务器,只能看到(
http://localhost:8182/v1/soap/servlet/messagerouter
, HTTP POST)这样的信息,如果代理服务器想知道当前的 HTTP 请求具体做的是什么,必须对 SOAP
的消息体解码,这样的话,意味着要求第三方的代理服务器需要理解当前的 SOAP 消息语义,而这种 SOAP
应用与代理服务器之间的紧耦合关系是不合理的。
众所周知,对于基于网络的分布式应用,网络传输是一个影响应用性能的重要因素。如何使用缓存来节省网络传输带来的开销,这是每一个构建分布式网络应用的开发人员必须考虑的问题。
HTTP 协议带条件的 HTTP GET 请求 (Conditional GET)
被设计用来节省客户端与服务器之间网络传输带来的开销,这也给客户端实现 Cache 机制 ( 包括在客户端与服务器之间的任何代理 )
提供了可能。HTTP 协议通过 HTTP HEADER 域:If-Modified-Since/Last-
Modified,If-None-Match/ETag 实现带条件的 GET 请求。
REST 的应用可以充分地挖掘 HTTP 协议对缓存支持的能力。当客户端第一次发送 HTTP GET
请求给服务器获得内容后,该内容可能被缓存服务器 (Cache Server)
缓存。当下一次客户端请求同样的资源时,缓存可以直接给出响应,而不需要请求远程的服务器获得。而这一切对客户端来说都是透明的。
图 6. REST 与缓存服务器 (Cache
而对于 SOAP,情况又是怎样的呢?
使用 HTTP 协议的 SOAP,由于其设计原则上并不像 REST 那样强调与 Web 的工作方式相一致,所以,基于 SOAP
应用很难充分发挥 HTTP 本身的缓存能力,图
7. SOAP 与缓存服务器 (Cache Server)
两个因素决定了基于 SOAP 应用的缓存机制要远比 REST 复杂:
其一、所有经过缓存服务器的 SOAP 消息总是 HTTP POST,缓存服务器如果不解码 SOAP 消息体,没法知道该 HTTP
请求是否是想从服务器获得数据。
其二、SOAP 消息所使用的 URI 总是指向 SOAP
的服务器,如本文例子中的&
http://localhost:8182/v1/soap/servlet/messagerouter
,这并没有表达真实的资源 URI,其结果是缓存服务器根本不知道那个资源正在被请求,更不用谈进行缓存处理。
关于连接性
在一个纯的 SOAP 应用中,URI 本质上除了用来指示 SOAP 服务器外,本身没有任何意义。与 REST 的不同的是,无法通过
URI 驱动 SOAP 方法调用。例如在我们的例子中,当我们通过
getUserList SOAP 消息获得所有的用户列表后,仍然无法通过既有的信息得到某个具体的用户信息。唯一的方法只有通过 WSDL
的指示,通过调用 getUserByName 获得,getUserList 与 getUserByName 是彼此孤立的。
而对于 REST,情况是完全不同的:通过&
http://localhost:8182/v1/users
URI 获得用户列表,然后再通过用户列表中所提供的 LINK 属性,例如&
http://localhost:8182/v1/users/tester
获得 tester 用户的用户信息。这样的工作方式,非常类似于你在浏览器的某个页面上点击某个 hyperlink,
浏览器帮你自动定向到你想访问的页面,并不依赖任何第三方的信息
REST 构建的系统其系统的扩展能力要强于 SOAP,这可以体现在它的统一接口抽象、代理服务器支持、缓存服务器支持等诸多方面,
而SOAP的成熟性可以给需要提供给多开发语言的,多传输方式的,对于安全性要求较高的接口设计带来便利
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。使用Java创建RESTful Web Service_小牛学堂
使用Java创建RESTful Web Service
使用Java创建RESTful Web Service
REST是REpresentational State Transfer的缩写(一般中文翻译为表述性状态转移)。2000年Roy Fielding博士在他的博士论文《体系结构与基于网络的软件架构设计》中提出了REST。
REST是一种体系结构。而HTTP是一种包含了REST架构属性的协议。
REST基础概念
在REST中所有东西都被看作资源。每一个资源都有一个URI和它对应。
在REST中使用统一接口处理资源。与数据库CRUD操作(Create、Read、Update 和 Delete)一样,可以用POST、GET、PUT和DELETE处理REST资源。
每个REST请求都是孤立的,请求中包含了所需的全部信息。REST服务端不存储状态。
REST支持不同的通信数据格式,比如XML、JSON。
RESTful Web Services
RESTful Web Services因其简单性被广泛使用,它比SOAP要更简单。本文将重点介绍如何使用Jersey框架创建RESTful Web Services。Jersey框架实现了JAX-RS接口。本文示例代码使用Eclipse和Java SE 6编写。
创建RESTful Web Service服务端
在Eclipse中创建一个“dynamic web project”(动态web工程) ,项目名设为 “RESTfulWS”。
从下载Jersey。示例代码使用的是Jersey 1.17.1。首先解压Jersey到“jersey-archive-1.17.1”文件夹。接着将里面lib文件夹下的jar文件拷贝到工程目录的WEB-INF -& lib。然后将它们添加到build path。
asm-3.1.jar
jersey-client-1.17.1.jar
jersey-core-1.17.1.jar
jersey-server-1.17.1.jar
jersey-servlet-1.17.1.jar
jsr311-api-1.1.1.jar
在工程Java Resources -& src中创建“com.eviac.blog.restws”包,并在其中创建“UserInfo”类。最后把web.xml拷贝到WEB-INF目录下。
UserInfo.java
package com.eviac.blog.
import javax.ws.rs.GET;
import javax.ws.rs.P
import javax.ws.rs.PathP
import javax.ws.rs.P
import javax.ws.rs.core.MediaT
* @author pavithra
// 这里@Path定义了类的层次路径。
// 指定了资源类提供服务的URI路径。
@Path(&UserInfoService&)
public class UserInfo {
// @GET表示方法会处理HTTP GET请求
// 这里@Path定义了类的层次路径。指定了资源类提供服务的URI路径。
@Path(&/name/{i}&)
// @Produces定义了资源类方法会生成的媒体类型。
@Produces(MediaType.TEXT_XML)
// @PathParam向@Path定义的表达式注入URI参数值。
public String userName(@PathParam(&i&) String i) {
String name =
return &&User&& + &&Name&& + name + &&/Name&& + &&/User&&;
@Path(&/age/{j}&)
@Produces(MediaType.TEXT_XML)
public String userAge(@PathParam(&j&) int j) {
return &&User&& + &&Age&& + age + &&/Age&& + &&/User&&;
&?xml version=&1.0& encoding=&UTF-8&?&
&web-app xmlns:xsi=&http://www.w3.org/2001/XMLSchema-instance& xmlns=&/xml/ns/javaee& xmlns:web=&/xml/ns/javaee/web-app_2_5.xsd& xsi:schemaLocation=&/xml/ns/javaee &a href=&/xml/ns/javaee/web-app_2_5.xsd&&/xml/ns/javaee/web-app_2_5.xsd&&/a& id=&WebApp_ID& version=&2.5&&
&display-name&RESTfulWS&/display-name&
&servlet-name&Jersey REST Service&/servlet-name&
&servlet-class&com.sun.jersey.spi.container.servlet.ServletContainer&/servlet-class&
&init-param&
&param-name&com.sun.jersey.config.property.packages&/param-name&
&param-value&com.eviac.blog.restws&/param-value&
&/init-param&
&load-on-startup&1&/load-on-startup&
&/servlet&
&servlet-mapping&
&servlet-name&Jersey REST Service&/servlet-name&
&url-pattern&/rest/*&/url-pattern&
&/servlet-mapping&
&/web-app&
将此URL拷贝到浏览器地址栏中运行:
http://localhost:8080/RESTfulWS/rest/UserInfoService/name/Pavithra
输出结果如下:
创建客户端
创建一个“com.eviac.blog.restclient”包,然后新建“UserInfoClient”类。
UserInfoClient.java
package com.eviac.blog.
import javax.ws.rs.core.MediaT
import com.sun.jersey.api.client.C
import com.sun.jersey.api.client.ClientR
import com.sun.jersey.api.client.WebR
import com.sun.jersey.api.client.config.ClientC
import com.sun.jersey.api.client.config.DefaultClientC
* @author pavithra
public class UserInfoClient {
public static final String BASE_URI = &http://localhost:8080/RESTfulWS&;
public static final String PATH_NAME = &/UserInfoService/name/&;
public static final String PATH_AGE = &/UserInfoService/age/&;
public static void main(String[] args) {
String name = &Pavithra&;
int age = 25;
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource resource = client.resource(BASE_URI);
WebResource nameResource = resource.path(&rest&).path(PATH_NAME + name);
System.out.println(&Client Response \n&
+ getClientResponse(nameResource));
System.out.println(&Response \n& + getResponse(nameResource) + &\n\n&);
WebResource ageResource = resource.path(&rest&).path(PATH_AGE + age);
System.out.println(&Client Response \n&
+ getClientResponse(ageResource));
System.out.println(&Response \n& + getResponse(ageResource));
* 返回客户端请求。
* GET http://localhost:8080/RESTfulWS/rest/UserInfoService/name/Pavithra
* 返回请求结果状态“200 OK”。
* @param service
private static String getClientResponse(WebResource resource) {
return resource.accept(MediaType.TEXT_XML).get(ClientResponse.class)
.toString();
* 返回请求结果XML
* 例如:&User&&Name&Pavithra&/Name&&/User&
* @param service
private static String getResponse(WebResource resource) {
return resource.accept(MediaType.TEXT_XML).get(String.class);
运行客户端程序后,可以看到以下输出:
Client Response
GET http://localhost:8080/RESTfulWS/rest/UserInfoService/name/Pavithra returned a response status of 200 OK
&User&&Name&Pavithra&/Name&&/User&
Client Response
GET http://localhost:8080/RESTfulWS/rest/UserInfoService/age/25 returned a response status of 200 OK
&User&&Age&25&/Age&&/User&
试试吧 :)
原文链接:
- 译文链接: [ 转载请保留原文出处、译者和译文链接。]
关于作者:
(新浪微博:)
小牛学堂是森纵教育(股票代码:837906)推出的专注于为广大大学生和职场人士提供大数据技术的重度学习服务,与全国多家大数据交易所签订战略培训合作协议,并共同参与制订大数据行业人才培养标准,小牛学堂已然成为蓬勃发展的大数据行业发展的人才港湾。
免费咨询热线:400
课程咨询群:
对公支付宝账号:森纵艾德(北京)教育科技股份有限公司
对公支付宝账号:森纵艾德(北京)教育科技股份有限公司
课程内容版权均归小牛学堂所有 校区地址:北京市海淀区小牛学堂教学基地
V1.1 京ICP备号—3号

我要回帖

 

随机推荐