服务端REST与SOAP的探讨

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!

声明:

闲来逛论坛看到一篇不错的文章,阅读后受益匪浅。

本文从一个简单的应用场景出发,使用REST和SOAP两种不同的架构风格实现,通过对REST与SOAP Web服务具体对比,旨在帮助读者更深刻理解REST架构风格。

REST简介

在开始我们的正式讨论之前,让我们简单看一下REST的定义。

REST(Representational State Transfer)是Roy Fielding提出的一个描述互联系统架构风格的名词。为什么称为REST?Web本质上由各种各样的资源组成,资源由URI唯一标识。浏览器(或者任何其它类似于浏览器的应用程序)将展示出该资源的一种表现方式,或者一种表现状态。如果用户在该页面中定向到指向其它资源的链接,则将访问该资源,并表现出它的状态。这意味着客户端应用程序随着每个资源表现状态的不同而发生状态转移,也即所谓REST。关于REST本身,本文就不再这里过多地讨论,读者可以参考developerWorks上其它介绍REST的文章。本文的重点在于通过REST与SOAP Web服务的对比,帮助读者更深刻理解REST架构风格的特点,优势。

应用场景介绍(在线用户管理)

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

需求描述

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

需求用例图如下图一:

如图所示,客户端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用 :8182/v1/users/{username} 表示,用户列表资源的URI用 :8182/v1/users表示。它们的Representation如下,它们都采用了如清单1和清单2所示的XML表述方式。

清单1. 用户列表资源Representation

>>>:8182/v1/users/tester1>

清单2. 用户资源 Representation

>tester>IBM>testing!</description></user>

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

Restful Web服务架构

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

接下来,我们将基于该架构,使用Restlet给出应用的RESTful Web服务实现。下面的章节中,我们将给出REST Web服务实现的核心代码片段。关于完整的代码清单,读者可以通过资源列表下载。

客户端实现

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

{String APPLICATION_URI = “http://localhost:8182/v1”;String getUserUri(String name) {return APPLICATION_URI + “/users/” + name;}String getUsersUri() {return APPLICATION_URI + “/users”;}(String name) {Response response = new Client(Protocol.HTTP).delete(getUserUri(name));……}(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());……}(String name) {printUserByURI(getUserUri(name));}() {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());}}(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());}}}服务器端实现我没有值得分享的感伤爱情故事,

服务端REST与SOAP的探讨

相关文章:

你感兴趣的文章:

标签云: