`
j2ee_zhongqi
  • 浏览: 202628 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

REST 基础(二):Web 服务编程,REST 与 SOAP

阅读更多
应用场景介绍(在线用户管理)

本文将借助于一个应用场景,通过基于 REST 和 SOAP Web 服务的不同实现,来对两者进行对比。该应用场景的业务逻辑会尽量保持简单且易于理解,以有助于把我们的重心放在 REST 和 SOAP Web 服务技术特质对比上。

需求描述
这是一个在线的用户管理模块,负责用户信息的创建,修改,删除,查询。用户的信息主要包括:

用户名(唯一标志在系统中的用户)
头衔
公司
EMAIL
描述
需求用例图如下:


如图 1 所示,客户端 1(Client1)与客户端 2(Client2)对于信息的存取具有不同的权限,客户端 1 可以执行所有的操作,而客户端 2 只被允许执行用户查询(Query User)与用户列表查询(Query User List)。关于这一点,我们在对 REST Web 服务与 SOAP Web 服务安全控制对比时会具体谈到。下面我们将分别向您介绍如何使用 REST 和 SOAP 架构实现 Web 服务。

使用 REST 实现 Web 服务

本部分将基于 Restlet 框架来实现该应用。Restlet 为那些要采用 REST 结构体系来构建应用程序的 Java 开发者提供了一个具体的解决方案。关于更多的 Restlet 相关内容,本文不做深入讨论,请见参考资源列表。

设计
我们将采用遵循 REST 设计原则的 ROA(Resource-Oriented Architecture,面向资源的体系架构)进行设计。ROA 是什么?简单点说,ROA 是一种把实际问题转换成 REST 式 Web 服务的方法,它使得 URI、HTTP 和 XML 具有跟其他 Web 应用一样的工作方式。

在使用 ROA 进行设计时,我们需要把真实的应用需求转化成 ROA 中的资源,基本上遵循以下的步骤:

分析应用需求中的数据集。
映射数据集到 ROA 中的资源。
对于每一资源,命名它的 URI。
为每一资源设计其 Representations。
用 hypermedia links 表述资源间的联系。
接下来我们按照以上的步骤来设计本文的应用案例。

在线用户管理所涉及的数据集就是用户信息,如果映射到 ROA 资源,主要包括两类资源:用户及用户列表。用户资源的 URI 用 http://localhost:8182/v1/users/{username} 表示,用户列表资源的 URI 用 http://localhost:8182/v1/users 表示。它们的 Representation 如下,它们都采用了如清单 1 和清单 2 所示的 XML 表述方式。
清单 1. 用户列表资源 Representation
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
	<user>
			<name>tester</name>
			<link>http://localhost:8182/v1/users/tester</link>
	</user>
	<user>
			<name>tester1</name>
			<link>http://localhost:8182/v1/users/tester1</link>
	</user>
</users>


清单 2. 用户资源 Representation
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<user>
	<name>tester</name>
	<title>software engineer</title>
	<company>IBM</company>
	<email>tester@cn.ibm.com</email>
	<description>testing!</description>
</user>


客户端通过 User List Resource 提供的 LINK 信息 ( 如 : <link>http://localhost:8182/v1/users/tester</link> ) 获得具体的某个 USER Resource

Restful Web 服务架构

首先给出 Web 服务使用 REST 风格实现的整体架构图,如下图所示:


图 2. REST 实现架构


接下来,我们将基于该架构,使用 Restlet 给出应用的 RESTful Web 服务实现。

下面的章节中,我们将给出 REST Web 服务实现的核心代码片段。关于完整的代码清单,读者可以通过资源列表下载。

客户端实现
清单 3 给出的是客户端的核心实现部分,其主要由四部分组成:使用 HTTP PUT 增加、修改用户资源,使用 HTTP GET 得到某一具体用户资源,使用 HTTP DELETE 删除用户资源,使用 HTTP GET 得到用户列表资源。而这四部分也正对应了图 2 关于架构描述的四对 HTTP 消息来回。关于 UserRestHelper 类的完整实现,请读者参见本文所附的代码示例


清单 3. 客户端实现
public class UserRestHelper {
//The root URI of our ROA implementation.
public static final tring APPLICATION_URI = "http://localhost:8182/v1";

//Get the URI of user resource by user name. 
private static String getUserUri(String name) {
	return APPLICATION_URI + "/users/" + name;
}

//Get the URI of user list resource.
private static String getUsersUri() {
	return APPLICATION_URI + "/users";
}
//Delete user resource from server by user name.
//使用 HTTP DELETE 方法经由 URI 删除用户资源
public static void deleteFromServer(String name) {
	Response response = new Client(Protocol.HTTP).delete(getUserUri(name));
	…… 
}
//Put user resource to server.
//使用 HTTP PUT 方法经由 URI 增加或者修改用户资源
public static void putToServer(User user) {
	//Fill FORM using user data.
	Form form = new Form();
 	form.add("user[title]", user.getTitle());
 	form.add("user[company]", user.getCompany());
 	form.add("user[email]", user.getEmail());
 	form.add("user[description]", user.getDescription());
	Response putResponse = new Client(Protocol.HTTP).put(
	getUserUri(user.getName()), form.getWebRepresentation());
 	……
}
//Output user resource to console.
public static void printUser(String name) {
	printUserByURI(getUserUri(name));
}

//Output user list resource to console.
//使用 HTTP GET 方法经由 URI 显示用户列表资源
public static void printUserList() {
	Response getResponse = new Client(Protocol.HTTP).get(getUsersUri());
	if (getResponse.getStatus().isSuccess()) { 
			DomRepresentation result = getResponse.getEntityAsDom();
 //The following code line will explore this XML document and output
 //each user resource to console.
			……
	} else { 
	 	System.out.println("Unexpected status:"+ getResponse.getStatus()); 
	}
}

//Output user resource to console.
//使用 HTTP GET 方法经由 URI 显示用户资源
private static void printUserByURI(String uri) { 
	Response getResponse = new Client(Protocol.HTTP).get(uri);
	if (getResponse.getStatus().isSuccess()) { 
 		DomRepresentation result = getResponse.getEntityAsDom();
 		//The following code line will explore this XML document and output
 //current user resource to console.
 ……
 	} else { 
 		System.out.println("unexpected status:"+ getResponse.getStatus()); 
 	}
}
} 




服务器端实现
清单 4 给出的是服务器端对于用户资源类(UserResourc)的实现,其核心的功能是响应有关用户资源的 HTTP GET/PUT/DELETE 请求,而这些请求响应逻辑正对应了 UserRestHelper 类中关于用户资源类的 HTTP 请求。


清单 4. 服务器端实现
public class UserResource extends Resource {
private User _user;
private String _userName;
public UserResource(Context context, Request request, Response response) {
//Constructor is here.
……
}
//响应 HTTP DELETE 请求逻辑
public void delete() {
	// Remove the user from container.
	getContainer().remove(_userName);
 	getResponse().setStatus(Status.SUCCESS_OK);
}

//This method will be called by handleGet.
public Representation getRepresentation(Variant variant) {
 Representation result = null;
 if (variant.getMediaType().equals(MediaType.TEXT_XML)) {	
 	Document doc = createDocument(this._user);
 	result = new DomRepresentation(MediaType.TEXT_XML, doc);
 }
 return result;
}
//响应 HTTP PUT 请求逻辑。
public void put(Representation entity) {
 if (getUser() == null) {
 //The user doesn't exist, create it
 setUser(new User());
 getUser().setName(this._userName);
 getResponse().setStatus(Status.SUCCESS_CREATED);
 } else {
 	getResponse().setStatus(Status.SUCCESS_NO_CONTENT);
 }
 //Parse the entity as a Web form.
 Form form = new Form(entity);
 getUser().setTitle(form.getFirstValue("user[title]"));
 getUser().setCompany(form.getFirstValue("user[company]"));
 getUser().setEmail(form.getFirstValue("user[email]"));
 getUser().setDescription(form.getFirstValue("user[description]")); 
 //Put the user to the container.
	getApplication().getContainer().put(_userName, getUser()); 
}
//响应 HTTP GET 请求逻辑。
public void handleGet() {
	super.handleGet();
	if(this._user != null ) {
	    getResponse().setEntity(getRepresentation(
	               new Variant(MediaType.TEXT_XML)));
	    getResponse().setStatus(Status.SUCCESS_OK);	
	} else {
		getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);		
	}
}
//build XML document for user resource.
private Document createDocument(User user) {
 //The following code line will create XML document according to user info. 
	……
}
//The remaining methods here
……
}


UserResource 类是对用户资源类的抽象,包括了对该资源的创建修改(put 方法),读取(handleGet 方法 )和删除(delete 方法),被创建出来的 UserResource 类实例被 Restlet 框架所托管,所有操纵资源的方法会在相应的 HTTP 请求到达后被自动回调。

另外,在服务端,还需要实现代表用户列表资源的资源类 UserListResource,它的实现与 UserResource 类似,响应 HTTP GET 请求,读取当前系统内的所有用户信息,形成如清单 1 所示的用户列表资源 Representation,然后返回该结果给客户端。具体的实现请读者参见本文所附的代码示例。


使用 SOAP 实现 Web 服务


本文对于 SOAP 实现,就不再像 REST 那样,具体到代码级别的实现。本节将主要通过 URI,HTTP 和 XML 来宏观上表述 SOAP Web 服务实现的技术本质,为下一节 REST Web 服务与 SOAP Web 服务的对比做铺垫。
SOAP Web 服务架构
同样,首先给出 SOAP 实现的整体架构图,如下图所示:

图 3. SOAP 实现架构


可以看到,与 REST 架构相比,SOAP 架构图明显不同的是:所有的 SOAP 消息发送都使用 HTTP POST 方法,并且所有 SOAP 消息的 URI 都是一样的,这是基于 SOAP 的 Web 服务的基本实践特征。

获得用户信息列表
基于 SOAP 的客户端创建如清单 5 所示的 SOAP XML 文档,它通过类 RPC 方式来获得用户列表信息。


清单 5. getUserList SOAP 消息

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<p:getUserList xmlns:p="http://www.exmaple.com"/>
	</soap:Body>
</soap:Envelope>


客户端将使用 HTTP 的 POST 方法,将上述的 SOAP 消息发送至 http://localhost:8182/v1/soap/servlet/messagerouter URI,SOAP SERVER 收到该 HTTP POST 请求,通过解码 SOAP 消息确定需要调用 getUserList 方法完成该 WEB 服务调用,返回如下的响应:


清单 6. getUserListResponse 消息
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
			<p:get
				UserListResponse xmlns:p="http://www.exmaple.com">
				<Users>
				<username>tester<username>
				<username>tester1<username>
				......
				</Users>
				<p: getUserListResponse >
	</soap:Body>
</soap:Envelope>


获得某一具体用户信息

清单 7. getUserByName SOAP 消息
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
	 <p:getUserByName xmlns:p="http://www.exmaple.com">
				<username>tester</username>
				</p:getUserByName >
	</soap:Body>
</soap:Envelope>


同样地,客户端将使用 HTTP 的 POST 方法,将上述的 SOAP 消息发送至 http://localhost:8182/v1/soap/servlet/messagerouter URI,SOAP SERVER 处理后返回的 Response 如下
清单 8. getUserByNameResponse SOAP 消息

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
	<p:getUserByNameResponse xmlns:p="http://www.exmaple.com">
			<name>tester</name>
			<title>software engineer</title>
			<company>IBM</company>
			<email>tester@cn.ibm.com</email>
			<description>testing!</description>
	</p:getUserByNameResponse>
</soap:Body>
</soap:Envelope>


实际上,创建新的用户,过程也比较类似,在这里,就不一一列出,因为这两个例子对于本文在选定的点上对比 REST 与 SOAP 已经足够了。

REST 与 SOAP 比较:略

实例参加下面附件code_rest.zip
from:http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/
  • 大小: 17.1 KB
  • 大小: 32.1 KB
  • 大小: 37.4 KB
分享到:
评论

相关推荐

    《PHP Web Services (English)》是一本关于使用 PHP 构建 Web 服务的书籍 在这本书中,你可以学习

    PHP 简介: 介绍 PHP 编程语言的基础知识和语法,以及如何在 PHP 中编写 Web 服务。 RESTful API 设计: 深入探讨如何设计和实现符合 REST 架构风格的 API,包括资源、URI 设计、HTTP 方法等。 SOAP 服务: 讨论...

    JAVA.WEB服务.构建与运行

    3.4 web服务与二进制数据传输 109 3.5 下一章 119 第4章 rest风格的web服务 121 4.1 什么是rest 121 4.2 从@webservice到@webserviceprovider 125 4.3 restful版本的teams服务 126 4.4 provider和dispatch 148 4.5 ...

    Java Web服务构建与运行(高清中文版).part1.rar

    Java Web服务:构建与运行 作 者: (美)卡林 著,任增刚 译...3.4 Web服务与二进制数据传输 3.5 下一章 第4章 REST风格的Web服务 第5章 Web服务安全 第6章 Java应用服务器中的JAX-WS 第7章 除了争论,还有什么 索引

    Java Web服务构建与运行(高清中文版).part2.rar

    Java Web服务:构建与运行 作 者: (美)卡林 著,任增刚 译...3.4 Web服务与二进制数据传输 3.5 下一章 第4章 REST风格的Web服务 第5章 Web服务安全 第6章 Java应用服务器中的JAX-WS 第7章 除了争论,还有什么 索引

    go web编程

    7.3 基于REST的Web服务简介 166 7.3.1 将动作转换为资源 168 7.3.2 将动作转换为资源的属性 169 7.4 通过Go分析和创建XML 169 7.4.1 分析XML 169 7.4.2 创建XML 177 7.5 通过Go分析和创建...

    Java Web服务构建与运行(高清中文版).part3.rar

    Java Web服务:构建与运行 作 者: (美)卡林 著,任增刚 译...3.4 Web服务与二进制数据传输 3.5 下一章 第4章 REST风格的Web服务 第5章 Web服务安全 第6章 Java应用服务器中的JAX-WS 第7章 除了争论,还有什么 索引

    Java Web服务构建与运行(高清中文版).part5.rar

    Java Web服务:构建与运行 作 者: (美)卡林 著,任增刚 译...3.4 Web服务与二进制数据传输 3.5 下一章 第4章 REST风格的Web服务 第5章 Web服务安全 第6章 Java应用服务器中的JAX-WS 第7章 除了争论,还有什么 索引

    Java Web服务构建与运行(高清中文版).part4.rar

    Java Web服务:构建与运行 作 者: (美)卡林 著,任增刚 译...3.4 Web服务与二进制数据传输 3.5 下一章 第4章 REST风格的Web服务 第5章 Web服务安全 第6章 Java应用服务器中的JAX-WS 第7章 除了争论,还有什么 索引

    webservice-clients:一组Web服务客户端,用于通过REST和SOAP API使用EBI的工具

    注意:现在已弃用了多种编程语言中的许多“较旧” REST和SOAP客户端,但那些可能感兴趣的人使用。 除了Perl,Python和Java外,还可以使用各种不同的REST / SOAP库在C#,Visual Basic .NET,Ruby和PHP中使用客户端...

    IOS网络编程与云端应用最佳实践 + 随书代码.zip

    云服务篇包括了第4章~第5章,介绍了客户端服务器结构网络通信两种具体实现方式:REST Web Service和SOAP Web Service,以及 iClo ud编程。社交篇包括了第6章~第7章,介绍了Twitter、Facebook、新浪微博社交网络...

    《iOS网络编程与云端应用最佳实践》源码

    云服务篇包括了第4章~第5章,介绍了客户端服务器结构网络通信两种具体实现方式:REST WebService和SOAP Web Service,以及iCloud编程。社交篇包括了第6章~第7章,介绍了Twitter、Facebook、新浪微博社交网络客户端...

    [WCFREST]WebHTTP编程模型——WebHttpBinding

    绑定是一组相关绑定元素的有序组合,绑定的特性与能力决定于它包含的绑定元素,在这里我们通过  不论是我们采用SOAP还是REST架构风格,运行时框架体系依然不曾改变,终结点也仍旧是通信的核心。在WebHTTP编程模型中...

    Python编程入门经典

    20.10.6 基于SOAP Web服务的 wiki搜索和替换 447 20.11 为Web服务API创建 文档 449 20.11.1 人类可读的API 文档 449 20.11.2 XML-RPC自省API 450 20.11.3 WSDL 451 20.12 选择Web服务标准 455 20.13 Web服务礼仪 456...

    PHP经典实例(第二版)中文PDF下载

    PHP经典实例(第二版)能够为您节省宝贵的Web开发时间。有了这些针对真实问题的解决方案放在手边,大多数编程难题都会迎刃而解。 本书将PHP的特性与经典实例丛书的独特形式组合到一起,足以帮您...使用SOAP和REST架构

    ASP.NET Web API 2框架揭秘

    随着互联网的普及,互联网应用(尤其移动互联网应用)已经成为主流,“SOAP之重”已经越来越令我们无法承受,于是采用REST架构风格并直接采用Web进行通信的轻量级Web Service走进了我们的视野并登堂入室。为了与传统...

    PHP和MySQL Web开发第4版pdf以及源码

    16.5.4 Web应用的商业主机服务 16.6 数据库服务器的安全性 16.6.1 用户和权限系统 16.6.2发送数据至服务器 16.6.3 连接服务器 16.6.4 运行服务器 16.7 保护网络 16.7.1 安装防火墙 16.7.2使用隔离区域(DMZ) 16.7.3...

    PHP和MySQL WEB开发(第4版)

    16.5.4 Web应用的商业主机服务 16.6 数据库服务器的安全性 16.6.1 用户和权限系统 16.6.2发送数据至服务器 16.6.3 连接服务器 16.6.4 运行服务器 16.7 保护网络 16.7.1 安装防火墙 16.7.2使用隔离区域(DMZ) 16.7.3...

    bioservices:从Python访问生物Web服务

    Bioservices是一个Python软件包,可提供对许多Bioinformatices Web服务(例如UniProt)的访问,并提供了一个框架来轻松实现Web服务包装器(基于WSDL / SOAP或REST协议)。 BioServices的主要目标是使用Python作为...

Global site tag (gtag.js) - Google Analytics